Search code examples
javascriptjqueryhtmlbarcodebarcode-scanner

Dynamically add row with jQuery


I have an application that integrated with barcode scanner, like this:

enter image description here

I have made a row dynamically with this snippet of code:

<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>

<div class="container" align="top" style="margin-top: 0px;">
    <h1 align="center">
        Barcode: <br><input type="text" id="myHeader" value="5555">
    </h1>
    <table id="myTable" class=" table order-list">
      <thead>
        <tr>
          <td>Barcode</td>
          <td>Item</td>
        </tr>
      </thead>
      <tbody>
      </tbody>
      <tfoot>
        <tr>
          <td colspan="7" style="text-align: left;">
            <div align="right">
              <p style="color: black;margin-right: 90px;">9.999.999</p>
            </div>
            <input type="button" class="btn btn-lg btn-block " id="addrow" value="Add Row" style="border-color: black;" />
          </td>
        </tr>
        <tr>
        </tr>
      </tfoot>
    </table>
</div>

and here is the code that I wrapped with script tag:

<script >
    $(document).ready(function() {
        var counter = 0;

        $("#addrow").on("click", function() {
            var newRow = $("<tr>");
            var cols = "";

            cols += '<td><input type="text" disabled value="123123123" class="form-control" name="name' + counter + '"/></td>';
            cols += '<td><input type="text" disabled value="Sekop" class="form-control" name="mail' + counter + '"/></td>';

            cols += '<td><input type="button" class="ibtnDel btn btn-md btn-danger "  value="Delete"></td>';
            newRow.append(cols);
            $("table.order-list").append(newRow);
            counter++;
        });

        $("table.order-list").on("click", ".ibtnDel", function(event) {
            $(this).closest("tr").remove();
            counter -= 1
        });
    });

function calculateRow(row) {
    var price = +row.find('input[name^="price"]').val();
}

function calculateGrandTotal() {
    var grandTotal = 0;
    $("table.order-list").find('input[name^="price"]').each(function() {
        grandTotal += +$(this).val();
    });
    $("#grandtotal").text(grandTotal.toFixed(2));
} </script>

But the code above just add the row only when I clicked the Add Row button.

What I want for now is, when I scan a barcode with a barcode scanner, the row automatically added follow the scanned barcode result. In this case it will be: "When the value on barcode on the header changed ( <h1 align="center">Barcode: 123123123</h1> , the result is same when I clicked the Add Row button.

So, please refer any approach, tutorial or example code how to do that, it would be very appreciated :)

For additional information: The purpose of this app is for cashier app on a store, like when the cashier scan a product, the result automatically appear on the app. And I developing it using Python Flask.


Solution

  • You have to listen to the changes made in the element. You can try with MutationObserver

    $(document).ready(function() {
      var counter = 0;
    
      $("#addrow").on("click", function() {
        var newRow = $("<tr>");
        var cols = "";
    
        cols += '<td><input type="text" disabled value="123123123" class="form-control" name="name' + counter + '"/></td>';
        cols += '<td><input type="text" disabled value="Sekop" class="form-control" name="mail' + counter + '"/></td>';
    
        cols += '<td><input type="button" class="ibtnDel btn btn-md btn-danger "  value="Delete"></td>';
        newRow.append(cols);
        $("table.order-list").append(newRow);
        counter++;
      });
    
      $("table.order-list").on("click", ".ibtnDel", function(event) {
        $(this).closest("tr").remove();
        counter -= 1
      });
    });
    
    function calculateRow(row) {
      var price = +row.find('input[name^="price"]').val();
    }
    
    function calculateGrandTotal() {
      var grandTotal = 0;
      $("table.order-list").find('input[name^="price"]').each(function() {
          grandTotal += +$(this).val();
      });
      $("#grandtotal").text(grandTotal.toFixed(2));
    }
    
    // Listen to the changes in the header element and add row
    var target = document.querySelector('#myHeader');
    
    setTimeout(function() {
      target.textContent = "New Barcode: XXXXXXXXX"; // change text after 2 seconds
    }, 2000)
    
    var observer = new MutationObserver(function(mutations) {
      mutations.forEach(function(mutation) {
        $("#addrow").trigger("click"); // trigger the click event to add row if the header text is changed
      });
    });
    
    var config = {
      attributes: true,
      childList: true,
      characterData: true
    };
    
    observer.observe(target, config);
    
    // otherwise
    observer.disconnect();
    observer.observe(target, config);
    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
    <script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
    
    <div class="container" align="top" style="margin-top: 0px;">
        <h1 align="center" id="myHeader">Barcode: 123123123</h1>
        <table id="myTable" class=" table order-list">
          <thead>
            <tr>
              <td>Barcode</td>
              <td>Item</td>
            </tr>
          </thead>
          <tbody>
          </tbody>
          <tfoot>
            <tr>
              <td colspan="7" style="text-align: left;">
                <div align="right">
                  <p style="color: black;margin-right: 90px;">9.999.999</p>
                </div>
                <input type="button" class="btn btn-lg btn-block " id="addrow" value="Add Row" style="border-color: black;" />
              </td>
            </tr>
            <tr>
            </tr>
          </tfoot>
        </table>
    </div>

    Update: The updated question indicates that you can trigger the click event on blur event of the barcode input element:

    $(document).ready(function() {
      var counter = 0;
    
      $("#addrow").on("click", function() {
        var newRow = $("<tr>");
        var cols = "";
        var barcode = $("#myHeader").val().trim();// take the current barcode value
        cols += '<td><input type="text" disabled value= '+ barcode +'  class="form-control" name="name' + counter + '"/></td>';
        cols += '<td><input type="text" disabled value="Sekop" class="form-control" name="mail' + counter + '"/></td>';
    
        cols += '<td><input type="button" class="ibtnDel btn btn-md btn-danger "  value="Delete"></td>';
        newRow.append(cols);
        $("table.order-list").append(newRow);
        counter++;
      });
    
      $("table.order-list").on("click", ".ibtnDel", function(event) {
        $(this).closest("tr").remove();
        counter -= 1
      });
    });
    
    function calculateRow(row) {
      var price = +row.find('input[name^="price"]').val();
    }
    
    function calculateGrandTotal() {
      var grandTotal = 0;
      $("table.order-list").find('input[name^="price"]').each(function() {
          grandTotal += +$(this).val();
      });
      $("#grandtotal").text(grandTotal.toFixed(2));
    }
    
    // Add new row by triggering the click event on focus out
    var target = document.querySelector('#myHeader');
    target.addEventListener('blur', function(){
      $("#addrow").trigger("click");
    });
    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
    <script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
    
    <div class="container" align="top" style="margin-top: 0px;">
        Barcode: <br><input type="text" id="myHeader" value="5555">
        <table id="myTable" class=" table order-list">
          <thead>
            <tr>
              <td>Barcode</td>
              <td>Item</td>
            </tr>
          </thead>
          <tbody>
          </tbody>
          <tfoot>
            <tr>
              <td colspan="7" style="text-align: left;">
                <div align="right">
                  <p style="color: black;margin-right: 90px;">9.999.999</p>
                </div>
                <input type="button" class="btn btn-lg btn-block " id="addrow" value="Add Row" style="border-color: black;" />
              </td>
            </tr>
            <tr>
            </tr>
          </tfoot>
        </table>
    </div>