【问题标题】:Assigning and updating value for dynamically created input tags - jquery -Materialize autocomplete为动态创建的输入标签分配和更新值 - jquery -Materialize autocomplete
【发布时间】:2020-03-11 07:22:12
【问题描述】:

我正在尝试构建一个发票页面,其中用户搜索产品和详细信息是自动填写的,

我正在从数据库中获取值以填充 Materialize 下拉列表和 onAutocomplete 以触发下一个事件

如果用户输入产品代码,则该值将通过 ajax 请求传递并分配给相应的值。

对于单行,代码运行完美, 问题是当我添加新行并更新对任何字段的更改时。

我面临的问题: 无论单击什么,所有行中的值都会更新。

我不确定如何将响应绑定到特定字段。

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>

脚本

$(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

截图:

【问题讨论】:

  • 提示:将此添加到 codepen 或 Code Snippet 以获得答案。
  • 您没有选择正确行的输入,而是选择了 qtypricegst 类的所有输入。在 Autocomplete 上保存发生自动完成的行(例如 let $row = $(this).parent("tr") )并在您的 succes 函数中仅将值应用于 $rows 输入字段($row.find('.qty').val(response.quantity)
  • @AlexandrBiship 谢谢 - 添加小提琴 - jsfiddle.net/qcryzsn4/4
  • @Lapskaus 我添加了小提琴。如果您能更新我的更改并使其正常工作,我将不胜感激

标签: javascript jquery html ajax materialize


【解决方案1】:

$(".product_name") 返回页面中所有具有该类的元素。您将需要一个父元素来定位所需的确切元素。因此,例如,您可以获取 idclass(以存在且唯一的为准)并将其附加到查询的开头。

更新:创建自定义$this 并指向当前$('input.autocomplete'),如图所示:

$("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

这是working fiddle

【讨论】:

  • 这很可能有效!但是选择行和相应的子输入是一种奇怪的方式。在变量名中使用 $ - 前缀表明您在此处保存了一个 DOM 元素,但您将其转换为 id- 字符串,这违反了命名约定并且有点多余。更好的方法是保存var $row = $(this).parent('tr); 并在选择中直接使用$row.find('.qty').val(response.quantity);
  • 哈哈是的,我绊倒了。没错,$ 前缀在这里实际上是多余的,因为变量包含一个字符串。 $row.find('.qty').val(response.quantity); 非常适合完成工作,但是我的目标是对发布的初始代码进行最小的更改。无论如何,感谢您指出这一点。干杯:)
  • @tipos 感谢您的代码,但是当我使用 console.log($row) 时,我得到了#undefined
  • @Lapskaus var $row = $(this).parent('tr); console.log($row.find('.qty'.val()); 给我带来语法错误,无法识别的表达式:[object Object].qty
  • $row.find('.qty'.val()); 你放错了右括号。应该是$row.find('.qty').val();
猜你喜欢
  • 2014-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-30
  • 2013-02-07
  • 1970-01-01
  • 2012-05-21
相关资源
最近更新 更多