javascript Dynamic HTML table row causing issues

问题: I have a select option on select of which I am creating an HTML table, As I am calling data from back-end on the basis of selected option so created table rows are dynamic...

问题:

I have a select option on select of which I am creating an HTML table, As I am calling data from back-end on the basis of selected option so created table rows are dynamic

what I am doing is

  • On change of select option, I am creating HTML table row, the rows are dynamic and are consist of input fields, ItemName is an auto complete so when I am selecting any item name and focusing out I am getting some corresponding value of that item and populating them in other Input fields
  • After selecting ItemName I am shifting my focus on pur. rate then UnitQty after and then Disc% in between these there are some calculations going on and lastly when I press enter on Disc% I am creating new row and everything is same for new row the working process is same

What is my issue

  • As doing above process suppose for drop-down selected option Supplier 1 I was doing all that, but then I realize I have to do it for another supplier, i.e. here it is Supplier 2, So on selection of Supplier 2 I am deleting tbody and tfoot and creating fresh one

  • So after drop-down change new row is created and it should work the same as above, but what's happening is for 1st row it is taking right data, but when on Disc% I press enter to create new row it creates a new row, but ItemName is taking other supplier data like for supplier 2 it is taking supplier 1 data in second row

Please check my snippet I have put alert and comment for better understanding of the issue

```
var CostPrice = "";
var totalAmount = "";
var unitQuantity = 0;
var unitQuantityOnDisc = 0;
var purchaseRateOnDisc = 0;
var purchaseRate = 0;
var totalAmount = "";
var discPercentage = "";
var discAmount = "";
var totalAmountOnDisc = "";
var subTotalOnDisc = 0;
var gstPercentage = "";
var gstAmount = "";
var totalAmountOnGst = "";
var total = 0;
var supplierCode = "";
var totalDiscountAmt = 0;
var totalGstAmt = 0;
var totalUnitQty = 0;
var subtotal = 0;
var totalAfterGrnDisc = 0;
var totalRoundOff = 0;
var totalAfterfreightAmt = 0;
var totalAftercommissionAmt = 0;
var mrpOnDisc = 0;
var tableData = {
  "ALMOND CHBAR~2402": {
    "itemName": "ALMOND CHBAR",
    "itemCode": "2402",
    "costPrice": 20.0,
    "gstPercentage": 14.5,
    "mrp": 30.0
  },
  "A BR SB EX~333": {
    "itemName": "A BR SB EX",
    "itemCode": "333",
    "costPrice": 1.0,
    "gstPercentage": 0.0,
    "mrp": 1.0
  }
}

var tableData1 = {
  "White rice~1001": {
    "itemName": "White rice",
    "itemCode": "1001",
    "costPrice": 50.0,
    "gstPercentage": 5,
    "mrp": 65.0
  },
  "Brown rice~333": {
    "itemName": "Brown rice",
    "itemCode": "1002",
    "costPrice": 90,
    "gstPercentage": 5.0,
    "mrp": 110
  }
}


$("#supplierInput").on("change", function(e) {
  $("tbody").empty();
  $("tfoot").empty();

  if (this.value == 'Supplier 1') {
    populateData(tableData)


  } else {
    populateData(tableData1)



  }

});

function populateData(data) {
  var autoCompleteData = Object.keys(data);

  function rowappend(tbody) {
    const markup =
      `<tr>
						  <td>
						    <input type="text" class="form-control commanChange" id="itemNametd" name="itemNametd">
						  </td>
						  <td><input type="text" name="itemCodetd" id="itemCodetd" class="form-control commantd" readonly="readonly"></td>
						  <td><input type="text" name="mrptd" id="mrptd" class="form-control commantd" readonly="readonly"></td>
						  <td><input type="text" name="purRatetd" id="purRatetd" class="form-control commantd"></td>
						  <td>
						    <input type="tel" id="unitQtytd"class="form-control commanChange" name="unitQtytd">
						  </td>
			               			 
						  <td>
						    <input type="tel" id="discPercentagetd"class="form-control commanChange" name="discPercentagetd" >
						  </td>
						  <td><input type="text" name="discAmttd" id="discAmttd" class="form-control commantd" readonly="readonly"></td> 
						  <td><input type="text" name="gstPercentagetd" id="gstPercentagetd" class="form-control commantd" readonly="readonly"></td>
						  <td><input type="text" name="gstAmttd" id="gstAmttd" class="form-control commantd" readonly="readonly"></td>
						  <td><input type="text" name="totalAmttd" id="totalAmttd" class="form-control commantd" readonly="readonly"></td>
						  <td style="background-color: white;border: 1px white"><i class="fas fa-times fa-2x remove-btn"></i></td>
						  
						</tr>`

    $(tbody).append(markup);
    setTimeout(() => $("[name=itemNametd]", tbody).last().focus(), 100);

    $("[name=itemNametd]", tbody).last().autocomplete({
      source: autoCompleteData
    }).data('tableData', data); // <----   added...
  }

  function rowappendTfoot(tfoot) {

    const tfootmarkup =
      `<tr>
		<td id="itemNametf" class="commantf" align="center">Total ->
		</td>
		<td id="itemCodetf" class="commantf"></td>
		<td id="mrptf" class="commantd"></td>
		<td id="purRatetf" class="commantf"></td>
		<td id="unitQtytf" class="commantf"></td>
		<td id="discPercentagetf" class="commantf"></td>
		<td id="discAmttf" class="commantf"></td>
		<td id="gstPercentagetf" class="commantf"></td>
		<td id="gstAmttf" class="commantf"></td>
		<td id="totalAmttf" class="commantf"></td>
		<td id="crossBtntf" class="commantf"></td>
	</tr>`

    $(tfoot).append(tfootmarkup);

  }


  rowappend($('tbody', '#tableInvoice'))
  rowappendTfoot($('tfoot', '#tfootTable'))


  function getValues(row) {
    const search = ($('[name=itemNametd]', row).val()).toString()
    console.log("search  : " + search);
    var data = $('[name=itemNametd]', row).data('tableData'); // <--- added
    const value = data[search]; // this one is causing issue
    CostPrice = value.costPrice;

    if (value) {
      $(row).find("[name=itemCodetd]").val(value.itemCode);
      $(row).find("[name=mrptd]").val(value.mrp);
      $(row).find("[name=purRatetd]").val(CostPrice);

      $(row).find("[name=gstPercentagetd]").val(value.gstPercentage);
    }
  }

  function calc(row) {
    unitQuantity = $(row).find("[name=unitQtytd]").val() || '0';
    purchaseRate = $(row).find("[name=purRatetd]").val() || '0';
    var mrp = $(row).find("[name=mrptd]").text() || '0';
    totalAmount = (parseFloat(unitQuantity) * parseFloat(purchaseRate));

    $(row).find("[name=totalAmttd]").val((totalAmount));

  }

  function calcDiscount(row) {
    unitQuantityOnDisc = $(row).find("[name=unitQtytd]").val() || '0';
    purchaseRateOnDisc = $(row).find("[name=purRatetd]").val() || '0';
    mrpOnDisc = $(row).find("[name=mrptd]").val() || '0';
    subTotalOnDisc = (parseFloat(unitQuantityOnDisc) * parseFloat(purchaseRateOnDisc));
    discPercentage = $(row).find("[name=discPercentagetd]").val() || '0';
    gstPercentage = $(row).find("[name=gstPercentagetd]").val() || '0';

    discAmount = (parseFloat(discPercentage) / 100) * parseFloat(totalAmount);
    totalAmountOnDisc = (parseFloat(totalAmount) - parseFloat(discAmount))
    gstAmount = (parseFloat(gstPercentage) / 100) * parseFloat(totalAmountOnDisc);
    totalAmountOnGst = (parseFloat(totalAmountOnDisc) + parseFloat(gstAmount))
    total += parseFloat(totalAmountOnGst);
    totalDiscountAmt += parseFloat(discAmount);
    totalGstAmt += parseFloat(gstAmount);
    totalUnitQty += parseFloat(unitQuantity);
    subtotal += parseFloat(subTotalOnDisc);
    totalRoundOff = total - Math.round(total);


    $(row).find("[name=discAmttd]").val((discAmount));
    $(row).find("[name=gstAmttd]").val((gstAmount));
    $(row).find("[name=totalAmttd]").val((totalAmountOnGst));

    $("#unitQtytf").text((totalUnitQty));
    $("#discAmttf").text((totalDiscountAmt));
    $("#gstAmttf").text((totalGstAmt));
    $("#netAmtInput").val((total));
    $("#totalAmttf").text((total));
    $("#subTotalInput").val((subtotal));
    $("#itemAmtDiscinput").val((totalDiscountAmt));
    $("#taxAmtInput").val((totalGstAmt));
    //	  $("#roundOffAmtInput").val(format(totalRoundOff));


  }

  $(document).on('focusout', function(e) {
    const row = e.target.parentElement.parentElement
    if (e.target.matches("[name=itemNametd]")) {
      getValues(e.target.parentElement.parentElement)
      $("[name=purRatetd]").focus();
    }
  });


  $(document).keypress(function(event) { // here I am trying to create new row when enter is clicked
    const row = event.target.parentElement.parentElement
    if (event.target.matches('[name=discPercentagetd]')) {
      var keycode = event.keyCode || event.which;
      if (keycode == '13') {
        alert("presed")
        calcDiscount(event.target.parentElement.parentElement)
        if ($(row).parent().find('tr').length - $(row).index() === 1) {
          rowappend(event.target.parentElement.parentElement.parentElement)

          total = 0;
          totalDiscountAmt = 0;
          totalGstAmt = 0;
          totalUnitQty = 0;
          subtotal = 0;

          $("#tableInvoice tbody tr").each(function() {
            calc(this)
            calcDiscount(this)
          })
        }
      }
    }





  });
  document.addEventListener("keydown", function(e) {

    const row = e.target.parentElement.parentElement
    if (event.target.matches('[name=discPercentagetd]') || e.target.matches('[name=unitQtytd]')) {

      var keycode = e.keyCode || event.e;
      if (keycode == '9') {


        if (!$(event.target).val()) {
          e.preventDefault();
          return;
        }


        total = 0;
        totalDiscountAmt = 0;
        totalGstAmt = 0;
        totalUnitQty = 0;
        subtotal = 0;

        $("#tableInvoice tbody tr").each(function() {
          calc(this)
          calcDiscount(this)
        })


      }

    }


  });
  $("#clear").click(function(e) {


    $("tbody").empty();
    $("tfoot").empty();
    $('#supplierInput option').prop('selected', function() {
      return this.defaultSelected;
    });
  });


}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="container commonDivInvoice">
  <div class="form-row">

    <div class="form-group col-xs-6 col-sm-6 col-md-6 col-lg-2">
      <label for="supplierInput">Supplier</label>
      <select name="supplierInput" id="supplierInput" class="form-control">
        <option disabled="disabled" selected="true">select supplier
        </option>
        <option>Supplier 1</option>
        <option>Supplier 2</option>

      </select>
    </div>





  </div>
  <div class="row tableInvoice" id="commonDvScroll">
    <table class="table table-bordered" id="tableInvoice">
      <thead>
        <tr>
          <th id="itemNameth" class="commanth">Item Name</th>
          <th id="itemCodeth" class="commanth">Code</th>
          <th id="mrpth" class="commanth">Mrp</th>
          <th id="purRateth" class="commanth">Pur.Rate</th>
          <th id="unitQtyth" class="commanth">Unit Qty</th>
          <th id="discPercentageth" class="commanth">Disc%</th>
          <th id="discAmtth" class="commanth">Disc Amt</th>
          <th id="gstPercentageth" class="commanth">Gst%</th>
          <th id="gstAmtth" class="commanth">Gst Amt</th>
          <th id="totalAmtth" class="commanth">Total Amount</th>

        </tr>
      </thead>
      <tbody>

      </tbody>

    </table>

  </div>
  <div class="row">
    <table class="table table-bordered" id="tfootTable">
      <tfoot>


      </tfoot>
    </table>
  </div>
  <button type="button" class="commonButton" id="clear">
			<i class="fa fa-eraser"></i> Clear
		</button>
</div>

Here is My dynamic Code for the people who are misinterpreting it

To populate supplier Select option

$.ajax({
        'url': 'SupplierName', 
        'method' : "GET",
        'dataType' : "json",
        'contentType': "application/json; charset=utf-8",
        'success': function(SupplierNamedata){
            let dropdown = $('#supplierInput');
            dropdown.empty();
            dropdown.append('<option selected="true" disabled>Select Supplier</option>');
            dropdown.prop('selectedIndex', 0);
          $.each(SupplierNamedata, function (key, entry) {
            dropdown.append($('<option></option>').attr('value', entry.SupplierCode).text(entry.SupplierName));
        });

        },
        'error': function(err){ 

        } 
    });

So once supplier is populated I am selecting one from drop down and calling ajax like below

 $("#supplierInput").on("change", function(e) { 

                var supplierInvNo = $("#supplierInvNoInput").val();
                 $('#grnReceivingForm input[type="text"]').val('');
                 $('#grnReceivingForm input[type="tel"]').val('0.00');                              
                 $("tbody").empty();
                 $("tfoot").empty();

                supplierCode = this.value                   
                $.ajax({

                    url: "dataToPopulate",
                    method: "GET",
                    dataType: "json",
                    data: {
                        supplierCode : supplierCode  // sending supplier code
                    },
                    contentType: "application/json; charset=utf-8",
                    success: function(tabledata) { 

                            $("#tfootTable").show();
                            populateData(tabledata)
                          },
                   });

`` So by above code what I am doing dynamically is firstly populating the select option drop-down with supplier name, than on change of supplier I am calling data from backend for that supplier and that tabledata is updating each time when supplier is changed


回答1:

Update:
The problem was, you placed rowappend function inside populateData function. This was causing always the first table object to be populated every time you add a row. Please check my updated text snippet and run it. You will see it work.


Please check my updated code snippet. Here, I am trying to mimic an AJAX call response by returning back an object. Compare my code with your original code to understand the changes:

        <div class="form-group col-xs-6 col-sm-6 col-md-6 col-lg-2">
            <label for="supplierInput">Supplier</label>
            <select name="supplierInput" id="supplierInput" class="form-control">
                <option disabled="disabled" selected="true">select supplier
                </option>
                <option>Supplier 1</option>
                <option>Supplier 2</option>

            </select>
        </div>





    </div>
    <div class="row tableInvoice" id="commonDvScroll">
        <table class="table table-bordered" id="tableInvoice">
            <thead>
                <tr>
                    <th id="itemNameth" class="commanth">Item Name</th>
                    <th id="itemCodeth" class="commanth">Code</th>
                    <th id="mrpth" class="commanth">Mrp</th>
                    <th id="purRateth" class="commanth">Pur.Rate</th>
                    <th id="unitQtyth" class="commanth">Unit Qty</th>
                    <th id="discPercentageth" class="commanth">Disc%</th>
                    <th id="discAmtth" class="commanth">Disc Amt</th>
                    <th id="gstPercentageth" class="commanth">Gst%</th>
                    <th id="gstAmtth" class="commanth">Gst Amt</th>
                    <th id="totalAmtth" class="commanth">Total Amount</th>

                </tr>
            </thead>
            <tbody>

            </tbody>

        </table>

    </div>
    <div class="row">
        <table class="table table-bordered" id="tfootTable">
            <tfoot>


            </tfoot>
        </table>
    </div>
    <button type="button" class="commonButton" id="clear">
        <i class="fa fa-eraser"></i> Clear
    </button>
</div>
<script>
    var CostPrice = "";
    var totalAmount = "";
    var unitQuantity = 0;
    var unitQuantityOnDisc = 0;
    var purchaseRateOnDisc = 0;
    var purchaseRate = 0;
    var totalAmount = "";
    var discPercentage = "";
    var discAmount = "";
    var totalAmountOnDisc = "";
    var subTotalOnDisc = 0;
    var gstPercentage = "";
    var gstAmount = "";
    var totalAmountOnGst = "";
    var total = 0;
    var supplierCode = "";
    var totalDiscountAmt = 0;
    var totalGstAmt = 0;
    var totalUnitQty = 0;
    var subtotal = 0;
    var totalAfterGrnDisc = 0;
    var totalRoundOff = 0;
    var totalAfterfreightAmt = 0;
    var totalAftercommissionAmt = 0;
    var mrpOnDisc = 0;
    var tableData = {};

    // ---- This block is to mimic jQuery API call response. I am using your own data ---- //

    sellersList = [
        {
            "SupplierCode": "0001",
            "SupplierName": "Amazon"
        },
        {
            "SupplierCode": "0002",
            "SupplierName": "FlipKart"
        },
        {
            "SupplierCode": "0003",
            "SupplierName": "eBay"
        }
    ];

    listOfItemsBySellerCode = {
        "0001" : {
            "ALMOND CHBAR" : {
                "itemName": "ALMOND CHBAR",
                "itemCode": "2402",
                "costPrice": 20.0,
                "gstPercentage": 14.5,
                "mrp": 30.0
            },
            "A BR SB EX~333" : {
                "itemName": "A BR SB EX~333",
                "itemCode": "333",
                "costPrice": 1.0,
                "gstPercentage": 0.0,
                "mrp": 20.0
            }
        },
        "0002" : {
            "iPhone SE": {
                "itemName": "iPhone SE",
                "itemCode": "2001",
                "costPrice": 15700.0,
                "gstPercentage": 14.5,
                "mrp": 20000.0
            },
            "Remi Note 5": {
                "itemName": "Remi Note 5",
                "itemCode": "2095",
                "costPrice": 25000.0,
                "gstPercentage": 13.0,
                "mrp": 28745.0
            }
        },
        "0003" : {
            "Levi's Jeans": {
                "itemName": "Levi's Jeans",
                "itemCode": "1309",
                "costPrice": 3750.0,
                "gstPercentage": 14.5,
                "mrp": 4120.0
            },
            "Fastrack M135": {
                "itemName": "Fastrack M135",
                "itemCode": "3401",
                "costPrice": 6789.0,
                "gstPercentage": 9.06,
                "mrp": 7459.0
            }
        }

    }

    function ajax_response_for_sellers_list (response) {
        return function (params) {
            params.success(sellersList);
        };
    }

    function ajax_response_for_items_sold_by_seller (response) {
        return function (params) {
            params.success(listOfItemsBySellerCode[params.data.supplierCode])
        }
    }

    // ****** Custom API response block ends here ******* //


    // Populate Supplier select options

    // Here I'm telling $.ajax to return with the seller data which I already have in my variable (for now). This way I don't even need to fire the API. 
    // But you can assume your API will respond in this JSON structure
    $.ajax = ajax_response_for_sellers_list();

    $.ajax({
        'url': '/mockAPI/to/get/suppliersData',
        'method': "GET",
        'dataType': "json",
        'contentType': "application/json; charset=utf-8",
        'success': function (response) {
            console.log('Our Mock API responding with list of all sellers : ')
            console.log(response);

            let dropdown = $('#supplierInput');
            dropdown.empty();
            dropdown.append('<option selected="true" disabled>Select Supplier</option>');
            dropdown.prop('selectedIndex', 0);
            $.each(response, function (key, entry) {
                dropdown.append($('<option></option>').attr('value', entry.SupplierCode).text(entry.SupplierName));
            });

        },
        'error': function (err) {

        }
    });

    // Here I'm telling $.ajax to return all items sold by a seller (seller is identified by code)
    // You can assume your API will respond in this JSON structure
    $.ajax = ajax_response_for_items_sold_by_seller();

    $("#supplierInput").on("change", function (e) {
        var supplierInvNo = $("#supplierInvNoInput").val();
        $('#grnReceivingForm input[type="text"]').val('');
        $('#grnReceivingForm input[type="tel"]').val('0.00');
        $("tbody").empty();
        $("tfoot").empty();

        supplierCode = jQuery(this).find(":selected").val();
        $('.loader').show();
        $('.overlay').show();
        $.ajax({

            url: "/mockAPI/to/get/items/based/on/sellercode",
            method: "POST",
            dataType: "json",
            data: {
                supplierCode: supplierCode  // sending supplier code
            },
            contentType: "application/json; charset=utf-8",
            success: function (response) {

                console.log('Our Mock API responding with all items sold by the selected seller : ', supplierCode)
                console.log(response);

                $("#tfootTable").show();
                populateData(response)
            },
        });
    });

    function rowappend(tbody) {
        const markup =
            `<tr>
                <td>
                    <input type="text" class="form-control commanChange" id="itemNametd" name="itemNametd">
                </td>
                <td><input type="text" name="itemCodetd" id="itemCodetd" class="form-control commantd" readonly="readonly"></td>
                <td><input type="text" name="mrptd" id="mrptd" class="form-control commantd" readonly="readonly"></td>
                <td><input type="text" name="purRatetd" id="purRatetd" class="form-control commantd"></td>
                <td>
                    <input type="tel" id="unitQtytd"class="form-control commanChange" name="unitQtytd">
                </td>

                <td>
                    <input type="tel" id="discPercentagetd"class="form-control commanChange" name="discPercentagetd" >
                </td>
                <td><input type="text" name="discAmttd" id="discAmttd" class="form-control commantd" readonly="readonly"></td> 
                <td><input type="text" name="gstPercentagetd" id="gstPercentagetd" class="form-control commantd" readonly="readonly"></td>
                <td><input type="text" name="gstAmttd" id="gstAmttd" class="form-control commantd" readonly="readonly"></td>
                <td><input type="text" name="totalAmttd" id="totalAmttd" class="form-control commantd" readonly="readonly"></td>
                <td style="background-color: white;border: 1px white"><i class="fas fa-times fa-2x remove-btn"></i></td>

            </tr>`

        $(tbody).append(markup);
        setTimeout(() => $("[name=itemNametd]", tbody).last().focus(), 100);

        // Bind autocomplete data
        var autoCompleteData = Object.keys(tableData);
        $("[name=itemNametd]", $('tbody', '#tableInvoice')).last().autocomplete({
            source: autoCompleteData
        }).data('tableData', tableData); // <----   added...
    }

    function getValues(row) {
        const search = ($('[name=itemNametd]', row).val()).toString()
        console.log("search  : " + search);
        var data = $('[name=itemNametd]', row).data('tableData'); // <--- added
        const value = data[search]; // this one is causing issue

        // Check first if the user is selecting an `existing` data object
        if (value) {
            CostPrice = value.costPrice;

            if (value) {
                $(row).find("[name=itemCodetd]").val(value.itemCode);
                $(row).find("[name=mrptd]").val(value.mrp);
                $(row).find("[name=purRatetd]").val(CostPrice);

                $(row).find("[name=gstPercentagetd]").val(value.gstPercentage);
            }
        }
    }

    function calc(row) {
        unitQuantity = $(row).find("[name=unitQtytd]").val() || '0';
        purchaseRate = $(row).find("[name=purRatetd]").val() || '0';
        var mrp = $(row).find("[name=mrptd]").text() || '0';
        totalAmount = (parseFloat(unitQuantity) * parseFloat(purchaseRate));

        $(row).find("[name=totalAmttd]").val((totalAmount));

    }

    function calcDiscount(row) {
        unitQuantityOnDisc = $(row).find("[name=unitQtytd]").val() || '0';
        purchaseRateOnDisc = $(row).find("[name=purRatetd]").val() || '0';
        mrpOnDisc = $(row).find("[name=mrptd]").val() || '0';
        subTotalOnDisc = (parseFloat(unitQuantityOnDisc) * parseFloat(purchaseRateOnDisc));
        discPercentage = $(row).find("[name=discPercentagetd]").val() || '0';
        gstPercentage = $(row).find("[name=gstPercentagetd]").val() || '0';

        discAmount = (parseFloat(discPercentage) / 100) * parseFloat(totalAmount);
        totalAmountOnDisc = (parseFloat(totalAmount) - parseFloat(discAmount))
        gstAmount = (parseFloat(gstPercentage) / 100) * parseFloat(totalAmountOnDisc);
        totalAmountOnGst = (parseFloat(totalAmountOnDisc) + parseFloat(gstAmount))
        total += parseFloat(totalAmountOnGst);
        totalDiscountAmt += parseFloat(discAmount);
        totalGstAmt += parseFloat(gstAmount);
        totalUnitQty += parseFloat(unitQuantity);
        subtotal += parseFloat(subTotalOnDisc);
        totalRoundOff = total - Math.round(total);


        $(row).find("[name=discAmttd]").val((discAmount));
        $(row).find("[name=gstAmttd]").val((gstAmount));
        $(row).find("[name=totalAmttd]").val((totalAmountOnGst));

        $("#unitQtytf").text((totalUnitQty));
        $("#discAmttf").text((totalDiscountAmt));
        $("#gstAmttf").text((totalGstAmt));
        $("#netAmtInput").val((total));
        $("#totalAmttf").text((total));
        $("#subTotalInput").val((subtotal));
        $("#itemAmtDiscinput").val((totalDiscountAmt));
        $("#taxAmtInput").val((totalGstAmt));
        //    $("#roundOffAmtInput").val(format(totalRoundOff));


    }

    $(document).on('focusout', '[name=itemNametd]', function (e) {
        var row = jQuery(this).parent().parent();

        // Get row values
        getValues(row);

        // Focus next
        console.log('focusing next', row.find("[name=purRatetd]").length);
        row.find("[name=purRatetd]").focus();
    });


    $(document).keypress(function (event) { // here I am trying to create new row when enter is clicked
        const row = event.target.parentElement.parentElement
        if (event.target.matches('[name=discPercentagetd]')) {
            var keycode = event.keyCode || event.which;
            if (keycode == '13') {
                alert("presed")
                calcDiscount(event.target.parentElement.parentElement)
                if ($(row).parent().find('tr').length - $(row).index() === 1) {
                    rowappend(event.target.parentElement.parentElement.parentElement)

                    total = 0;
                    totalDiscountAmt = 0;
                    totalGstAmt = 0;
                    totalUnitQty = 0;
                    subtotal = 0;

                    $("#tableInvoice tbody tr").each(function () {
                        calc(this)
                        calcDiscount(this)
                    })
                }
            }
        }





    });
    document.addEventListener("keydown", function (e) {

        const row = e.target.parentElement.parentElement
        if (event.target.matches('[name=discPercentagetd]') || e.target.matches('[name=unitQtytd]')) {

            var keycode = e.keyCode || event.e;
            if (keycode == '9') {


                if (!$(event.target).val()) {
                    e.preventDefault();
                    return;
                }


                total = 0;
                totalDiscountAmt = 0;
                totalGstAmt = 0;
                totalUnitQty = 0;
                subtotal = 0;

                $("#tableInvoice tbody tr").each(function () {
                    calc(this)
                    calcDiscount(this)
                })


            }

        }


    });
    $("#clear").click(function (e) {
        $("tbody").empty();
        $("tfoot").empty();
        $('#supplierInput option').prop('selected', function () {
            return this.defaultSelected;
        });
    });

    function rowappendTfoot(tfoot) {

        const tfootmarkup =
            `<tr>
            <td id="itemNametf" class="commantf" align="center">Total ->
            </td>
            <td id="itemCodetf" class="commantf"></td>
            <td id="mrptf" class="commantd"></td>
            <td id="purRatetf" class="commantf"></td>
            <td id="unitQtytf" class="commantf"></td>
            <td id="discPercentagetf" class="commantf"></td>
            <td id="discAmttf" class="commantf"></td>
            <td id="gstPercentagetf" class="commantf"></td>
            <td id="gstAmttf" class="commantf"></td>
            <td id="totalAmttf" class="commantf"></td>
            <td id="crossBtntf" class="commantf"></td>
        </tr>`

        $(tfoot).append(tfootmarkup);

    }

    function populateData(data) {
        tableData = Object.assign({}, data);
        var autoCompleteData = Object.keys(data);
        rowappend($('tbody', '#tableInvoice'));
        rowappendTfoot($('tfoot', '#tfootTable'))
    }
</script>


回答2:

The problem was with the data object globally used in all place. which can be handle by fetching the object again based on selected dropdown in runtime.

Please check below code

    var CostPrice = "";
    var totalAmount = "";
    var unitQuantity = 0;
    var unitQuantityOnDisc = 0;
    var purchaseRateOnDisc = 0;
    var purchaseRate = 0;
    var totalAmount = "";
    var discPercentage = "";
    var discAmount = "";
    var totalAmountOnDisc = "";
    var subTotalOnDisc = 0;
    var gstPercentage = "";
    var gstAmount = "";
    var totalAmountOnGst = "";
    var total = 0;
    var supplierCode = "";
    var totalDiscountAmt = 0;
    var totalGstAmt = 0;
    var totalUnitQty = 0;
    var subtotal = 0;
    var totalAfterGrnDisc = 0;
    var totalRoundOff = 0;
    var totalAfterfreightAmt = 0;
    var totalAftercommissionAmt = 0;
    var mrpOnDisc = 0;
    var tableData = {
      "ALMOND CHBAR~2402": {
        "itemName": "ALMOND CHBAR",
        "itemCode": "2402",
        "costPrice": 20.0,
        "gstPercentage": 14.5,
        "mrp": 30.0
      },
      "A BR SB EX~333": {
        "itemName": "A BR SB EX",
        "itemCode": "333",
        "costPrice": 1.0,
        "gstPercentage": 0.0,
        "mrp": 1.0
      }
    }

    var tableData1 = {
      "White rice~1001": {
        "itemName": "White rice",
        "itemCode": "1001",
        "costPrice": 50.0,
        "gstPercentage": 5,
        "mrp": 65.0
      },
      "Brown rice~333": {
        "itemName": "Brown rice",
        "itemCode": "1002",
        "costPrice": 90,
        "gstPercentage": 5.0,
        "mrp": 110
      }
    }

    var tableDataGlob = ''; //global object
    $("#supplierInput").on("change", function (e) {
      $("tbody").empty();
      $("tfoot").empty();
      if (this.value == 'Supplier 1') {
        tableDataGlob = tableData;
        populateData(tableDataGlob)
      } else {
        tableDataGlob = tableData1;
        populateData(tableDataGlob)
      }
    });


    function populateData(data) {

      function rowappend(tbody) {
        const markup =
          `<tr>
                  <td>
                    <input type="text" class="form-control commanChange" id="itemNametd" name="itemNametd">
                  </td>
                  <td><input type="text" name="itemCodetd" id="itemCodetd" class="form-control commantd" readonly="readonly"></td>
                  <td><input type="text" name="mrptd" id="mrptd" class="form-control commantd" readonly="readonly"></td>
                  <td><input type="text" name="purRatetd" id="purRatetd" class="form-control commantd"></td>
                  <td>
                    <input type="tel" id="unitQtytd"class="form-control commanChange unitQtytd" name="unitQtytd">
                  </td>
                              
                  <td>
                    <input type="tel" id="discPercentagetd" class="form-control commanChange discPercentagetd" name="discPercentagetd" >
                  </td>
                  <td><input type="text" name="discAmttd" id="discAmttd" class="form-control commantd" readonly="readonly"></td> 
                  <td><input type="text" name="gstPercentagetd" id="gstPercentagetd" class="form-control commantd" readonly="readonly"></td>
                  <td><input type="text" name="gstAmttd" id="gstAmttd" class="form-control commantd" readonly="readonly"></td>
                  <td><input type="text" name="totalAmttd" id="totalAmttd" class="form-control commantd" readonly="readonly"></td>
                  <td style="background-color: white;border: 1px white"><i class="fas fa-times fa-2x remove-btn"></i></td>
                  
                </tr>`

        $(tbody).append(markup);
        setTimeout(() => $("[name=itemNametd]", tbody).last().focus(), 100);
        // Fetch Data on basis of dynamic Selected option 
        // Previously the code was declaring global var 2019-07-04 15:24:28
        var autoCompleteData = Object.keys(tableDataGlob);
      

        console.log(autoCompleteData);
        console.log($("[name=itemNametd]", tbody).last());
        $("[name=itemNametd]", tbody).last().autocomplete({
          source: autoCompleteData
        }).data('tableData', data); // <----   added...

      }

      function rowappendTfoot(tfoot) {

        const tfootmarkup =
          `<tr>
        <td id="itemNametf" class="commantf" align="center">Total ->
        </td>
        <td id="itemCodetf" class="commantf"></td>
        <td id="mrptf" class="commantd"></td>
        <td id="purRatetf" class="commantf"></td>
        <td id="unitQtytf" class="commantf"></td>
        <td id="discPercentagetf" class="commantf"></td>
        <td id="discAmttf" class="commantf"></td>
        <td id="gstPercentagetf" class="commantf"></td>
        <td id="gstAmttf" class="commantf"></td>
        <td id="totalAmttf" class="commantf"></td>
        <td id="crossBtntf" class="commantf"></td>
      </tr>`

        $(tfoot).append(tfootmarkup);

      }


      rowappend($('tbody', '#tableInvoice'))
      rowappendTfoot($('tfoot', '#tfootTable'))


      function getValues(row) {
        const search = ($('[name=itemNametd]', row).val()).toString()
        console.log("search  : " + search);
        
        var data = tableDataGlob;
        console.log(tableDataGlob);
    
        const value = data[search]; // this one is causing issue
        CostPrice = value.costPrice;

        if (value) {
          $(row).find("[name=itemCodetd]").val(value.itemCode);
          $(row).find("[name=mrptd]").val(value.mrp);
          $(row).find("[name=purRatetd]").val(CostPrice);

          $(row).find("[name=gstPercentagetd]").val(value.gstPercentage);
        }
      }

      function calc(row) {
        console.log(row)
        unitQuantity = $(row).find("[name=unitQtytd]").val() || '0';
        purchaseRate = $(row).find("[name=purRatetd]").val() || '0';
        var mrp = $(row).find("[name=mrptd]").text() || '0';
        totalAmount = (parseFloat(unitQuantity) * parseFloat(purchaseRate));

        $(row).find("[name=totalAmttd]").val((totalAmount));

      }

      function calcDiscount(row) {
        unitQuantityOnDisc = $(row).find("[name=unitQtytd]").val() || '0';
        purchaseRateOnDisc = $(row).find("[name=purRatetd]").val() || '0';
        mrpOnDisc = $(row).find("[name=mrptd]").val() || '0';
        subTotalOnDisc = (parseFloat(unitQuantityOnDisc) * parseFloat(purchaseRateOnDisc));
        discPercentage = $(row).find("[name=discPercentagetd]").val() || '0';
        gstPercentage = $(row).find("[name=gstPercentagetd]").val() || '0';

        discAmount = (parseFloat(discPercentage) / 100) * parseFloat(totalAmount);
        totalAmountOnDisc = (parseFloat(totalAmount) - parseFloat(discAmount))
        gstAmount = (parseFloat(gstPercentage) / 100) * parseFloat(totalAmountOnDisc);
        totalAmountOnGst = (parseFloat(totalAmountOnDisc) + parseFloat(gstAmount))
        total += parseFloat(totalAmountOnGst);
        totalDiscountAmt += parseFloat(discAmount);
        totalGstAmt += parseFloat(gstAmount);
        totalUnitQty += parseFloat(unitQuantity);
        subtotal += parseFloat(subTotalOnDisc);
        totalRoundOff = total - Math.round(total);


        $(row).find("[name=discAmttd]").val((discAmount));
        $(row).find("[name=gstAmttd]").val((gstAmount));
        $(row).find("[name=totalAmttd]").val((totalAmountOnGst));

        $("#unitQtytf").text((totalUnitQty));
        $("#discAmttf").text((totalDiscountAmt));
        $("#gstAmttf").text((totalGstAmt));
        $("#netAmtInput").val((total));
        $("#totalAmttf").text((total));
        $("#subTotalInput").val((subtotal));
        $("#itemAmtDiscinput").val((totalDiscountAmt));
        $("#taxAmtInput").val((totalGstAmt));
        //	  $("#roundOffAmtInput").val(format(totalRoundOff));


      }

      $(document).on('focusout', function (e) {
        const row = e.target.parentElement.parentElement
        if (e.target.matches("[name=itemNametd]")) {
          console.log(e.target.parentElement.parentElement);
          getValues(e.target.parentElement.parentElement)
          $("[name=purRatetd]").focus();
        }
      });

      // $('.discPercentagetd').unbind();
      
      $('body').on('keypress','.discPercentagetd',function (event) { // here I am trying to create new row when enter is clicked
        const row = event.target.parentElement.parentElement
        if (event.target.matches('[name=discPercentagetd]')) {
          var keycode = event.keyCode || event.which;
          console.log(keycode);
          if (keycode == '13') {
            alert("presed")
            calcDiscount(event.target.parentElement.parentElement)
            if ($(row).parent().find('tr').length - $(row).index() === 1) {
              rowappend(event.target.parentElement.parentElement.parentElement)

              total = 0;
              totalDiscountAmt = 0;
              totalGstAmt = 0;
              totalUnitQty = 0;
              subtotal = 0;

              $("#tableInvoice tbody tr").each(function () {
                calc(this)
                calcDiscount(this)
              })
            }
          }
        }


      });


      $('body').on('keypress','.discPercentagetd,.unitQtytd', function (e) {

        const row = e.target.parentElement.parentElement
        if (event.target.matches('[name=discPercentagetd]') || e.target.matches('[name=unitQtytd]')) {

          var keycode = e.keyCode || event.e;
          if (keycode == '9') {


            if (!$(event.target).val()) {
              e.preventDefault();
              return;
            }


            total = 0;
            totalDiscountAmt = 0;
            totalGstAmt = 0;
            totalUnitQty = 0;
            subtotal = 0;

            $("#tableInvoice tbody tr").each(function () {
              calc(this)
              calcDiscount(this)
            })


          }

        }


      });

      $("#clear").unbind();
      $("#clear").click(function (e) {


        $("tbody").empty();
        $("tfoot").empty();
        $('#supplierInput option').prop('selected', function () {
          return this.defaultSelected;
        });
      });

    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" rel="stylesheet" />
    <link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" />
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/js/bootstrap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
    <div class="container commonDivInvoice">
      <div class="form-row">

        <div class="form-group col-xs-6 col-sm-6 col-md-6 col-lg-2">
          <label for="supplierInput">Supplier</label>
          <select name="supplierInput" id="supplierInput" class="form-control">
            <option disabled="disabled" selected="true">select supplier
            </option>
            <option>Supplier 1</option>
            <option>Supplier 2</option>

          </select>
          <input type="hidden" id="selectedtable" name="" value="">
        </div>





      </div>
      <div class="row tableInvoice" id="commonDvScroll">
        <table class="table table-bordered" id="tableInvoice">
          <thead>
            <tr>
              <th id="itemNameth" class="commanth">Item Name</th>
              <th id="itemCodeth" class="commanth">Code</th>
              <th id="mrpth" class="commanth">Mrp</th>
              <th id="purRateth" class="commanth">Pur.Rate</th>
              <th id="unitQtyth" class="commanth">Unit Qty</th>
              <th id="discPercentageth" class="commanth">Disc%</th>
              <th id="discAmtth" class="commanth">Disc Amt</th>
              <th id="gstPercentageth" class="commanth">Gst%</th>
              <th id="gstAmtth" class="commanth">Gst Amt</th>
              <th id="totalAmtth" class="commanth">Total Amount</th>

            </tr>
          </thead>
          <tbody>

          </tbody>

        </table>

      </div>
      <div class="row">
        <table class="table table-bordered" id="tfootTable">
          <tfoot>


          </tfoot>
        </table>
      </div>
      <button type="button" class="commonButton" id="clear">
          <i class="fa fa-eraser"></i> Clear
        </button>
    </div>

Test here working module: https://jsfiddle.net/m4fb038x/

  • 发表于 2019-07-07 08:16
  • 阅读 ( 238 )
  • 分类:sof

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除