Assigning and updating value for dynamically created input tags - jquery -Materialize autocomplete

mightyteja :

I am trying to build an invoice page where user search for product and details are auto-filled,

I am getting the values from the database to populate the Materialize dropdown and onAutocomplete to trigger the next events

If the user enters the Product code the value is being passed through ajax request and assigned to the corresponding values.

For single row, the code works perfect, The issue is when I add a new row and update the changes to any of the fields.

The issue I am facing: Values in all the rows are updated regardless of what's being clicked.

I am not sure how to bind response to the particular fields.

HTML

<table class="table table-bordered table-hover tab_logic" id="tab_logic">
                    <thead class=" purple accent-3 white-text text-darken-2">
                        <tr>
                            <th class="text-center"> Product Code </th>
                            <th class="text-center"> Product Name </th>
                            <th class="text-center"> Qty </th>
                            <th class="text-center"> Price </th>
                            <th class="text-center"> GST </th>
                            <th class="text-center"> Total </th>
                        </tr>
                    </thead>

                    <tbody>
                        <input type="hidden" name="service_invoice_id" value="{{$orderid}}">
                        <tr id='addr0' class="addr0">
                            <td>
                                <div class="row">
                                    <div class="input-field col s12">
                                        <input type="text" id="product_code" name='product_code[]'
                                            value="{{old('product_code')}}" class="autocomplete product_code"
                                            placeholder="Product Code">
                                    </div>
                                </div>
                            </td>
                            <td>
                                <div class="row">
                                    <div class="input-field col s12">
                                        <input type="text" name='product_name[]' class="product_name"
                                            placeholder="Product Name" required>
                                    </div>
                                </div>
                            </td>
                            <td>
                                <div class="row">
                                    <div class="input-field col s12">
                                        <input type="number" id="qty" name='product_qty[]' placeholder='Enter Qty'
                                            class="form-control qty" step="0" min="0" required />
                                    </div>
                                </div>

                            </td>
                            <td>
                                <div class="row">
                                    <div class="input-field col s12">
                                        <input type="number" id="price" name='price[]' placeholder='Enter Unit Price'
                                            class="form-control price" step="0.00" min="0" required />
                                    </div>
                                </div>
                            </td>

                            <td>
                                <div class="row">
                                    <div class="input-field col s12">
                                        <input type="number" name='gst[]' placeholder='GST %' class="form-control gst"
                                            step="0.00" min="0" />
                                    </div>
                                </div>
                            </td>
                            <td>
                                <div class="row">
                                    <div class="input-field col s12">
                                        <input type="number" name='total[]' placeholder='0.00'
                                            class="form-control total" readonly />
                                    </div>
                                </div>

                            </td>
                        </tr>
                        <tr id='addr1' class="addr1"></tr>
                    </tbody>
                </table>

Script

$(document).ready(function(e) {
    var name = {};
    var products = {!! $products->toJson() !!};
    //    var products_string = JSON.stringify(products);
    for (var i = 0; i < products.length; i++) {
        name[[products[i].product_code]] = null;
    }
    // console.log(name);

    $("input.autocomplete").autocomplete({
        data: name,
        onAutocomplete: function(data) {
            var values = data.split(",");
            var product_code = values[0];
            console.log(product_code);

            $.ajax({
                type: "GET",
                url: "{{ route('product-fetch')}}",
                data: { product_code: product_code },
                success: function(response) {
                    console.log(response);
                    $("product_name").val(response.name);
                    $("input.qty").val(response.quantity);
                    $("input.price").val(response.price);
                    $("input.gst").val(response.tax);
                }
            }); //End of ajax
        } //End of OnAutocomplete
    }); //End of autocomplete
});

//This function created so that new rows could grab the autocomplete functionality.

function productFetch(e) {
    var name = {};
    var products = {!! $products->toJson() !!};
    //    var products_string = JSON.stringify(products);
    for (var i = 0; i < products.length; i++) {
        name[[products[i].product_code]] = null;
    }
    // console.log(name);

    $("input.autocomplete").autocomplete({
        data: name,
        onAutocomplete: function(data) {
            var values = data.split(",");
            var product_code = values[0];
            console.log(product_code);

            $.ajax({
                type: "GET",
                url: "{{ route('product-fetch')}}",
                data: { product_code: product_code },
                success: function(response) {
                    console.log(response);
                    $(".product_name").val(response.name);
                    $(".qty").val(response.quantity);
                    $(".price").val(response.price);
                    $(".gst").val(response.tax);
                }
            }); //End of ajax
        } //End of OnAutocomplete
    }); //End of autocomplete
}

//     $(document.body).ready(function() {
//     //Invoke the Autosearch
//     // productFetch();
//     //initiate select form
//     $(".gst_type").formSelect();
// });

$(function() {
    var i = 1;
    $("#add_row").on("click", function(e) {
        e.preventDefault();
        b = i - 1;
        $("#addr" + i).html($("#addr" + b).html());
        //! will remove the selected element based on the class before being appended .
        $(".select-dropdown").remove();
        $(".tab_logic").append('<tr id="addr' + (i + 1) + '"></tr>');
        i++;
        //runs the method which will fetch the autocomplete
        productFetch();
        //initiate select form
        $(".gst_type").formSelect();
    });

    $("#delete_row").click(function() {
        if (i > 1) {
            $("#addr" + (i - 1)).html("");
            i--;
        }
    });

    $("#tab_logic tbody").on("keyup change", function() {
        calc();
    });
    $("#gst").on("keyup change", function() {
        calc_total();
    });
});

//Logic for the calculation
function calc() {
    $("#tab_logic tbody tr").each(function(i, element) {
        var html = $(this).html();
        if (html != "") {
            var qty = $(this)
                .find(".qty")
                .val();
            var price = $(this)
                .find(".price")
                .val();
            var gst = $(this)
                .find(".gst")
                .val();
            var gst_total = (qty * price * gst) / 100;
            $(this)
                .find(".total")
                .val(qty * price + gst_total);
            calc_total();
        }
    });
}

//Calculates the total
function calc_total() {
    total = 0;
    $(".total").each(function() {
        total += parseInt($(this).val());
    });
    $("#sub_total").val(total.toFixed(2));
    tax_sum = (total / 100) * $("#gst").val();
    $("#tax_amount").val(tax_sum.toFixed(2));
    $("#total_amount").val((tax_sum + total).toFixed(2));
}

JSFiddle

Screenshot: enter image description here

tipos :

$(".product_name") returns all the elements with this class in the page. You will need a parent element to target exact element that is required. So, you can for example get the id or class (whichever is present and unique) and append it to the beginning of the query.

UPDATE: Create custom $this and point to current $('input.autocomplete') as shown:

$("input.autocomplete").autocomplete({
  data: name,

  onAutocomplete: function (data) { // replace with arrow function here 
    var values = data.split(",");
    var product_code = values[0];
    console.log(product_code);

    // create a custom $this to point to the current $("input.autocomplete")
    var $this = $(this)[0].$el;

    // Get the id of the table row
    var row_id = "#" + $this.parents('tr').attr('id') + ' '; // output: '#addr0 ' for the first row

    // Or get the tr element
    var $row = $this.parents('tr');

    console.log(row_id);
    console.log($row);

    $.ajax({
      type: "GET",
      url: "{{ route('product-fetch')}}",
      data: { product_code: product_code },
      success: function (response) {
        console.log(response);

        // Append the parent id to the beginning of your query
        $(row_id + ".product_name").val(response.name);
        $(row_id + ".qty").val(response.quantity);
        $(row_id + ".price").val(response.price);
        $(row_id + ".gst").val(response.tax);

        // or if you prefer this approach
        // $row.find(".product_name").val(response.name);
        // $row.find(".qty").val(response.quantity);
        // $row.find(".price").val(response.price);
        // $row.find(".gst").val(response.tax);

      }

    }); //End of ajax

  } //End of OnAutocomplete

}); //End of autocomplete

Here is a working fiddle

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=346666&siteId=1