3

I have a javascript where upon click of a button a row with two cells is added to the table. One cell has a livesearch textfield and the another cell has a quantity textfield, whose value suppose to dynamically change and/or determined upon click on the livesearch textfiled results.

I have tried somethin but the challenge I am facing is that the value of the dynamically determined textfield of other rows keep retainin the value of the first row textfiled.

So I am seeking for assistance on how to clean-up the script so that each row will respond according to its respective values in the livesearch textfield

<div style="overflow-x:auto">
  <table id="stockTransfer" class="table">
    <thead>
      <tr>
        <th style="color:blue">Search Product's(Name/Code)</th>
        <th style="color:blue">instore Availability</th>
        <th style="color:blue">Price/Unit</th>
        <th style="color:blue">Choose Selling Unit(eg:cartons/etc)</th>
        <th style="color:blue">Quantity</th>
        <th style="color:blue">Cummulative Price</th>
        <th style="color:blue"> Delete </th>
      </tr>
    </thead>
    <tbody>
      <tr>
      </tr>
    </tbody>
  </table>
</div>

<script>
//stock transfer dynamic textboxes
$(document).ready(function() {
  $(document).on('click', '.btnaddstockTransfer', function() {
    var html = '';
    html += '<tr>';
    html += '<td><div class="search-box"><input id="stock" class="form-control is-warning stock" type="text" name="stock[]" placeholder="Search by name or code"><div class="result"></div></div></td>';
    html += '<td><input class="form-control is-warning eqty" type="text" name="stockeqty[]" readonly size="2"></td>';
    html += '</tr>';

    $('#stockTransfer').append(html);


    $(document).on('keyup input', '.search-box input[type="text"]', function() {
      /* Get input value on change */
      var inputVal = $(this).val();
      var resultDropdown = $(this).siblings(".result");
      if (inputVal.length) {
        $.get("backend-search.php", {
          term: inputVal
        }).done(function(data) {
          // Display the returned data in browser
          resultDropdown.html(data);
        });
      } else {
        resultDropdown.empty();
      }
    });

    // Set search input value on click of result item
    $(document).on("click", ".result p", function() {

      var stock = $(this).text();

      $(this).parents(".search-box").find('.stock').val(stock);
      $(this).parent(".result").empty();

      var tr = $(this).parent(".search-box").parent().parent().parent();

      $.ajax({
        method: "get",
        url: "saleqtyOnFly.php",
        data: {
          item: stock
        },
        success: function(data) {
          tr.find(".eqty").val(data);
        }
      })

    });
  });
});
13
  • 1
    Please format your code properly. It's pretty much illegible the way it is now. Commented Jul 10 at 8:25
  • Please have a look at How do I format my posts?, How to Ask, and how to make a minimal reproducible example of your issue. See also the tour, since you haven't take it yet. You can edit your post. Thanks.
    – ADyson
    Commented Jul 10 at 8:30
  • Having a $(document).ready inside another $(document).ready is completely redundant and pointless.
    – ADyson
    Commented Jul 10 at 8:33
  • another text field in another td tag...this is vague. Be specific about exactly which field you are talking about and how we should identify it, then there is no ambiguity.
    – ADyson
    Commented Jul 10 at 8:36
  • var stock = document.getElementsById('stock') will cause you a problem because it looks like you can have more than one <input id="stock" in your page. An ID must be unique. So JS will always only find and use the first item with that ID. All others are considered invalid. A few lines above that you already used $(this).parents(".search-box").find('.stock') to find a specific "stock" input by its position...so why didn't you do that again just below? It seems you didn't really think about that getElementById code carefully when you wrote it.
    – ADyson
    Commented Jul 10 at 8:38

2 Answers 2

2

The reason it's not populating your "quantity" textbox is because inside $(document).on("click", ".result p", function(), tr doesn't contain a jQuery object. That's because $(this).parent(".result").empty(); clears the "result" div, and that means $(this) no longer exists because that points to an element within the "result" div.

The simple solution is to assign tr before you clear the "result" div:

  $(this).parents(".search-box").find('.stock').val(stock);
  var tr = $(this).parent().parent().parent().parent();
  $(this).parent(".result").empty();

Here's a working demo (just using hard-coded sample data instead of the responses to your AJAX calls):

$(document).ready(function() {
  $(document).on('click', '.btnaddstockTransfer', function() {
    var html = '';
    html += '<tr>';
    html += '<td><div class="search-box"><input id="stock" class="form-control is-warning stock" type="text" name="stock[]" placeholder="Search by name or code"><div class="result"></div></div></td>';
    html += '<td><input class="form-control is-warning eqty" type="text" name="stockeqty[]" readonly size="2"></td>';
    html += '</tr>';

    $('#stockTransfer').append(html);


    $(document).on('keyup input', '.search-box input[type="text"]', function() {
      /* Get input value on change */
      var inputVal = $(this).val();
      var resultDropdown = $(this).siblings(".result");
      if (inputVal.length) {
        //just dummy data for example purposes:
          resultDropdown.html("<p>Result 1</p><p>Result 2</p>");
        /*$.get("backend-search.php", {
          term: inputVal
        }).done(function(data) {
          // Display the returned data in browser
          resultDropdown.html(data);
        });*/
      } else {
        resultDropdown.empty();
      }
    });

    // Set search input value on click of result item
    $(document).on("click", ".result p", function() {

      var stock = $(this).text();

      $(this).parents(".search-box").find('.stock').val(stock);
      var tr = $(this).parent().parent().parent().parent();
      $(this).parent(".result").empty();

      /*$.ajax({
        method: "get",
        url: "saleqtyOnFly.php",
        data: {
          item: stock
        },
        success: function(data) {
          tr.find(".eqty").val(data);
        }
      })*/
      //just dummy data for example purposes:
      tr.find(".eqty").val(123);
    });
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<button class="btnaddstockTransfer" type="button">
Add stock transfer
</button>
<div style="overflow-x:auto">
  <table id="stockTransfer" class="table">
    <thead>
      <tr>
        <th style="color:blue">Search Product's(Name/Code)</th>
        <th style="color:blue">instore Availability</th>
        <th style="color:blue">Price/Unit</th>
        <th style="color:blue">Choose Selling Unit(eg:cartons/etc)</th>
        <th style="color:blue">Quantity</th>
        <th style="color:blue">Cummulative Price</th>
        <th style="color:blue"> Delete </th>
      </tr>
    </thead>
    <tbody>
      <tr>
      </tr>
    </tbody>
  </table>
</div>

0
-1

Consider the following example.

//stock transfer dynamic textboxes
$(function() {

  function makeRow(table) {
    console.log("Add Row to " + $(table).attr("id"));
    var row = $("<tr>").appendTo($("tbody", table));
    $("thead th", table).each(function() {
      $("<td>").html("&nbsp;").appendTo(row);
    });
    $("td")
      .eq(0)
      .append($("<div>", {
        class: "search-box"
      }), $("<input>", {
        id: "stock-" + row.index(),
        class: "form-control is-warning stock",
        type: "text",
        name: "stock[]",
        placeholder: "Search by name or code"
      }), $("<div>", {
        class: "result"
      }));
    $("td")
      .eq(4)
      .append($("<input>", {
        class: "form-control is-warning eqty",
        type: "text",
        name: "stockeqty[]",
        size: "2",
        readonly: true
      }));
    return row;
  }

  $(document).on('click', '.btnaddstockTransfer', function() {
    makeRow($("#stockTransfer"));
  });
  
  $(document).on('keyup input', '.search-box input[type="text"]', function() {
    /* Get input value on change */
    var inputVal = $(this).val();
    var resultDropdown = $(this).closest("tr").find(".result");
    if (inputVal.length) {
      $.get("backend-search.php", {
        term: inputVal
      }).done(function(data) {
        // Display the returned data in browser
        resultDropdown.html(data);
      });
    } else {
      resultDropdown.empty();
    }
  });

  // Set search input value on click of result item
  $(document).on("click", ".result", function() {
    var row = $(this).closest("tr");

    $('.stock', row).val($(this).text().trim());
    $(this).html("");

    $.ajax({
      method: "get",
      url: "saleqtyOnFly.php",
      data: {
        item: stock
      },
      success: function(data) {
        $(".eqty", row).val(data);
      }
    });
  });
});
#stockTransfer thead th {
  color: blue;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<button class="btnaddstockTransfer">Add Stock Transfer</button>
<div style="overflow-x:auto">
  <table id="stockTransfer" class="table">
    <thead>
      <tr>
        <th>Search Product's(Name/Code)</th>
        <th>Instore Availability</th>
        <th>Price/Unit</th>
        <th>Choose Selling Unit(eg:cartons/etc)</th>
        <th>Quantity</th>
        <th>Cummulative Price</th>
        <th>Delete </th>
      </tr>
    </thead>
    <tbody>
    </tbody>
  </table>
</div>

The fastest way to help clean things up is to take repeatable code and move it to a function.

It can also be helpful to use .closest() to find specific parent elements.

Not the answer you're looking for? Browse other questions tagged or ask your own question.