manish thakur
manish thakur

Reputation: 820

Dynamically created HTML table row is not working fine

I have a Select drop-down field So on change of which I am creating a HTML table row which is fully dynamic

What I am doing is

Issue is - when I want to change supplier and and now I have selected supplier 2 and deleted the previous row which is of Supplier 1, and when I type in autocomplete field and on focus out it says value is not defined - I don't know what I am doing wrong

To check the error

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();

  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

    });




  }
  rowappend($('tbody', '#tableInvoice'))

  function getValues(row) {

    const search = ($('[name=itemNametd]', row).val()).toString()
    console.log("search  : " + search)
    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);
    }

  }

  $(document).on('focusout', (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) {
    const row = event.target.parentElement.parentElement

    var keycode = event.keyCode || event.which;
    if (keycode == '13') {
      if (!$(event.target).val()) {
        e.preventDefault();
        return;
      }

      if (event.target.matches('[name=discPercentagetd]')) {

        if ($(row).parent().find('tr').length - $(row).index() === 1) {
          rowappend(event.target.parentElement.parentElement.parentElement)
        }
      }

    }


  });


}
<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">Item Code</th>
          <th id="unitQtyth" class="commanth">Unit Qty</th>
          <th id="purRateth" class="commanth">Pur.Rate</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" style="display: none;">
      <tfoot>


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

Edit/Update

I ahve edited my snippet when I press enter and if it is Disc% input field then I am creating new row, so when I change the dropdown i.e supplier name it is taking previous one data

Suppose I select supplier 1 So I am entering(Typing in input fields) and tabledata is in working , but when I select supplier 2 and enter data first row gets the tableData1 but when I enter and create row the nex row shows supplier 1 data

Upvotes: 0

Views: 201

Answers (2)

gaetanoM
gaetanoM

Reputation: 42044

Your issue is in this line:

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

The data variable continues to have the first value. I would suggest to simplify the code. But if there is no chance you may simply save the data value as a data attribute to the autocomplete widget and get its value when needed.

Take a look to .data() or dataset for details.

You can save the data value when you create the autocomplete:

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

You can get the value after:

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

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();

    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(function () {
            $("[name=itemNametd]", markup).last().focus()
        }, 100);

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

    rowappend($('tbody', '#tableInvoice'))

    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);
        }
    }

    $(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();
        }
    });

}
<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">Item Code</th>
                <th id="unitQtyth" class="commanth">Unit Qty</th>
                <th id="purRateth" class="commanth">Pur.Rate</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" style="display: none;">
            <tfoot>
            </tfoot>
        </table>
    </div>
    <button type="button" class="commonButton" id="clear">
        <i class="fa fa-eraser"></i> Clear
    </button>
</div>

Upvotes: 1

Adil Liaqat
Adil Liaqat

Reputation: 229

Issue is here $(document).on('focusout', (e) => { you are registering a focusout event on document. Instead use $('#itemNametd').on('focusout', (e) => {

Upvotes: 0

Related Questions