如何在不生成新行的情况下使用 json 从 ajax 成功访问现有 tr 并填充其 td

How to access existing tr and fill its td using json from ajax success without generating new row

我正在使用 CouchCMS。在 CouchCMS 中有一个 repeatable 区域的概念。这实际上会生成 tables 并在其中显示 repeatable 内容。

我将 repeatable 区域定义为:

<cms:repeatable name="item_detail" label="Item Detail" order="10" >
    
    <cms:editable name="product" label="Product" type="dropdown" opt_values="Select =- | <cms:pages masterpage='product/product.php' order='asc' orderby='product_name'><cms:show product_name /><cms:if '<cms:not k_paginated_bottom />'>|</cms:if></cms:pages>" order="1" />
    <cms:editable name="product_hsn" label="HSN" type="text" order="2" />hsn,qty,price,gst,amount
    <cms:editable name="product_qty" label="Quantity" type="text" order="3" />
    <cms:editable name="product_price" label="Price" type="text" order="4" />
    <cms:editable name="product_tax" label="Tax" type="text" order="5" />
    <cms:editable name="product_line_total_amount" label="Amount" type="text" order="6" />

</cms:repeatable>  

其中 editables 是我们可以通过将它们绑定到相应的文本框/ selects 等来填充数据的区域

现在我要做的是:

  1. Select editable 下拉列表中名为“product”的值。
  2. 当一个选项被 selected 时,一个 AJAX 被调用。这AJAX又returns一些数据。
  3. 我能够获取数据、控制台记录它或在 div 或 table 中显示它。

但我真正想做的是:

  1. 由于repeatable区域显示为table的形式,所以存在。我希望能够只获取现有数据中显示的 AJAX JSON 数据。
  2. 如果你看到上面的editables,一个table存在于每个editables' select/textbox中,有:

现在repeatable区域创建如下结构(对于上面定义的repeatable区域):

Product HSN Quantity Price Tax Amount Delete
<div>
    <p class="addRow" id="addRow_f_item_detail"><a>Add a Row</a></p>
</div>

在使用 repeatable 区域时,我也可以立即添加新行。如果一个人观察到 ids 并且名称有一个零 [0] 这会随着添加新行而不断增加。 有助于生成上述代码的脚本是:

if ( !window.COUCH ) var COUCH = {};
    $(function(){
        $('table.rr > tbody').sortable({
            axis: "y",
            handle: ".dg-arrange-table-rows-drag-icon",
            helper: function (e, ui) { 
                // https://paulund.co.uk/fixed-width-sortable-tables
                ui.children().each(function() {                
                    $(this).width($(this).width());
                });
            return ui;
        },
        update: function( event, ui ){
            var row = ui.item;
            var tbody = $( row ).closest( 'tbody' );
            tbody.trigger('_reorder');
        },
        start: function( event, ui ){    
            var row = ui.item;
            row.trigger('_reorder_start');
        },
        stop: function( event, ui ){
            var row = ui.item;
            row.trigger('_reorder_stop');
        },
    });
});
COUCH.rrInit = function( field_id, default_row ){
    var $field = $('#'+field_id);
    $field.tableGear({addDefaultRow:default_row, stackLayout:1});
    $field.on('click', '.col-actions .add-row', function(){
        var $this = $(this);
        var row_id = $this.attr('data_mosaic_row');
        var add_btn = $('#addRow_'+field_id+' a');
        add_btn.trigger("click", [row_id]);
    });
}
COUCH.t_confirm_delete_row = "Delete this row?";
COUCH.t_no_data_message = "- No Data -";

以防万一,如果需要,这是我的 AJAX 代码,我可以使用它添加一个新的,但它在一个新的中,而我希望将其附加到包含现有 repea 的代码中table 个地区。 AJAX代码:

$(document).on('change','select',function() {
    var data = "";
    $.ajax({
        type:"GET",
        url : "<cms:show k_site_link />generate/quotation-ajax.php",
        data: 
            "select_id="+$(this).val(),
        async: false
    }).done(function(data) {
        console.log(data);
        var trHTML = '';
        $.each(data.product_details, function (i, item) {
            trHTML += "<tr id='f_item_detail-" + i + "'>" + '<td class="editable k_element_product_hsn"><div style="position:relative;"><input type="bound" name=" f_item_detail[0][product_hsn]" id="f_item_detail-[0]-product_hsn" class="form-control" value="' + item.product_hsn + '"/></div></td>' +
            // '<td style="position:relative;"><input type="bound" name=" f_item_detail[0][product_price]" id="f_item_detail-[0]-product_price" class="form-control" value="' + item.product_price + '"/></td>' +
            // '<td style="position:relative;"><input type="bound" name=" f_item_detail[0][product_tax]" id="f_item_detail-[0]-product_tax" class="form-control" value="' + item.product_tax + '"/></td>' +
            '</tr>';
        });
        $('#f_item_detail').append(trHTML);
    })
});

我的 AJAX 文件有代码:

<?php require_once('../couch/cms.php'); ?>
<cms:set selected_product="<cms:gpc 'select_id' method='get' />" scope="global" />
<cms:content_type 'application/json'/>
<cms:template title="Quotation AJAX" hidden='1' parent="_generate_" />
    {
        "product_details": 
        [
            <cms:pages masterpage='product/product.php' custom_field="product_name=<cms:show selected_product />" >
            {
                "product_hsn": "<cms:addslashes><cms:show product_hsn/></cms:addslashes>",
                "product_price": "<cms:addslashes><cms:show min_selling_cost/></cms:addslashes>",
                "product_tax": "<cms:addslashes><cms:show tax_on_purchase/></cms:addslashes>"   
            }<cms:if "<cms:not k_paginated_bottom/>">,</cms:if>
            </cms:pages>
        ]
    }
<?php COUCH::invoke(); ?>

我要找的是: 将 AJAX 成功 JSON 值添加到现有 中的相应文本框,而不是添加新的 or 或 。我无法设置正确的 jQuery。非常感谢任何帮助。

提前致谢。 问候! @斯瓦蒂: 在此 fiddle 中完整 HTML(在 AJAX 部分进行了一些更改,这部分工作并输出了我想要实现的目标。该值被放入文本框中,但对于每个新行相同的文本框值从第一行更新,如果我可以按行更新文本框值,那就太好了)

编辑 #1 我按如下方式使用了您的代码 (@Swati),是的,它工作正常(在一定程度上)。

<script type="text/javascript">
    $(document).ready(function(){
        $("#f_item_detail-0-product").select2();
        $('input#f_item_detail-0-product_hsn').attr('readonly', true).addClass("form-control");
        $('input#f_item_detail-0-product_qty').attr('onchange', 'line_total()');
        $('input#f_item_detail-0-product_price').attr('onchange', 'line_total()');
        $('input#f_item_detail-0-product_tax').attr('readonly', true).addClass("form-control");
        $('input#f_item_detail-0-line_tax_amount').attr('readonly', true).addClass("form-control");
        $('input#f_item_detail-0-product_line_total_amount').attr('readonly', true).addClass("form-control");
    });
    
    var counter = 0;
    $(document).ready(function() {
        $(".addRow").click(function(){
            counter++;
            $("#f_item_detail-" + counter + "-product").select2();
        });
    });

    $(document).on('change','select',function() {
        var data = "";
        var i = 0;
        var indexs = $(this).closest("tr").index();//get index no
        console.log(indexs);

        $.ajax({
            type:"GET",
            url : "<cms:show k_site_link />generate/quotation-ajax.php",
            data: 
                "select_id="+$(this).val(),
            async: false
        }).done(function(data) {
            $('#f_item_detail-' + indexs + '-product_hsn').val(data.product_details[i].product_hsn).attr('readonly', true).addClass("form-control");

            $('#f_item_detail-' + indexs + '-product_qty').attr('onchange', 'line_total()');

            $('#f_item_detail-' + indexs + '-product_price').val(data.product_details[i].product_price).attr('onchange', 'line_total()');

            $('input#f_item_detail-' + indexs + '-product_tax').val(data.product_details[i].product_tax).attr('readonly', true).addClass("form-control");

            $('#f_item_detail-' + indexs + '-line_tax_amount').attr('readonly', true).addClass("form-control");

            $('#f_item_detail-' + indexs + '-product_line_total_amount').val(data.product_details[i].product_line_total_amount).attr('readonly', true).addClass("form-control");
        });
    });
            
    function line_total(){
        var line_qty = $('input#f_item_detail-' + indexs + '-product_qty').val();
        var line_tax = $('input#f_item_detail-' + indexs + '-product_tax').val();
        var line_cost =  $('input#f_item_detail-' + indexs + '-product_price').val();
        var line_tax_amount = parseFloat(((line_cost * line_tax)/100) * line_qty).toFixed(2);
        var result = parseFloat((+line_qty * +line_cost) + +line_tax_amount).toFixed(2);
        $('#f_item_detail-' + indexs + '-line_tax_amount').val(line_tax_amount).attr('hidden',true);
        $('#f_item_detail-' + indexs + '-product_line_total_amount').val(result);
    }

</script>

它正在解决返回和编辑产品的问题,从而按照您的建议更新订单项值。

但是如果您看到 函数 line_total() 它就会中断。并且不计算总数。你有什么建议?我们如何使用 indexs 值或其他值。另外,如果您还可以建议我如何在末尾显示 GST 总金额和总金额以及总计(GST 总金额 + 总金额),我将不胜感激。

我根本不擅长 javascript 或 jQuery。

所以我一直在努力让事情走上正轨。最后,我已经能够做到: 我正在寻找解决问题的 jQuery AJAX 代码如下:

var counter = 0;
$(document).ready(function() {
    $(".addRow").click(function(){
        counter++;
    });
});
            
$(document).on('change','select',function() {
    var data = "";
    var i = 0;
    $.ajax({
        type:"GET",
        url : "<cms:show k_site_link />generate/quotation-ajax.php",
        data: 
            "select_id="+$(this).val(),
        async: false
    }).done(function(data) {
        $('#f_item_detail-'+ counter +'-product_hsn').val(data.product_details[i].product_hsn);
        $('#f_item_detail-'+ counter +'-product_qty').val(data.product_details[i].product_qty);
        $('#f_item_detail-'+ counter +'-product_price').val(data.product_details[i].product_price);
        $('#f_item_detail-'+ counter +'-product_tax').val(data.product_details[i].product_tax);
        $('#f_item_detail-'+ counter +'-product_line_total_amount').val(data.product_details[i].product_line_total_amount);
    })
});

我实际上正在使用以下方法创建一个全局计数器:

var counter = 0;
$(document).ready(function() {
    $(".addRow").click(function(){
        var globalcounter = parseFloat(counter);
        counter++;
    });
});

然后将全局计数器的值作为“计数器”传递给 ajax()。每次单击“添加行”时,传入的计数器值都会递增。这有助于我将数字赋予输入的每一行的 id:

$('#f_item_detail-'+ counter +'-product_hsn').val(data.product_details[i].product_hsn);

“data.product_details[i]”中的 i 保持为零,因为 AJAX returns 每个订单项只有一个产品的详细信息。

每当您的 select-box 发生变化时,您只需从 select-box 获取 closest tr,然后 .find() 即可找到所需的输入并在那里添加值。

演示代码 :

$(document).on('change', 'select', function() {
  var selector = $(this).closest("tr") //get closest tr
  /* $.ajax({
     type: "GET",
     url: "<cms:show k_site_link />generate/quotation-ajax.php",
     data: "select_id=" + $(this).val(),
     async: false
   }).done(function(data) {*/
  //find your input and add value there
  selector.find('.k_element_product_hsn input').val("ac"); //data.product_details[i].product_hsn
  selector.find('.k_element_product_price input').val(124); //data.product_details[i].product_price
  selector.find('.k_element_product_tax input').val(23); //data.product_details[i].product_tax
  selector.find('.k_element_product_line_total_amount input').val(4356); //data.product_details[i].product_line_total_amount
  selector.find('.k_element_product_qty input').val(2); //data.product_details[i].product_qty


  /*}
  })*/
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>

<table>
  <tbody>
    <tr id="newDataRow_f_item_detail" class="newRow even">
      <td class="dg-arrange-table-rows-drag-icon">&nbsp;</td>
      <td class="editable k_element_product">
        <div style="position:relative;">
          <select name="data[xxx][product]" idx="data-xxx-product" id="data-xxx-product">
            <option value="-">Select</option>
            <option value="3Ply Mask">3Ply Mask</option>
            <option value="Laptop i3 4th Gen">Laptop i3 4th Gen</option>
          </select>
        </div>
      </td>
      <td class="editable k_element_product_hsn">
        <div style="position:relative;"><input type="text" idx="data-xxx-product_hsn" id="data-xxx-product_hsn" name="data[xxx][product_hsn]" value="">
        </div>
      </td>
      <td class="editable k_element_product_qty">
        <div style="position:relative;"><input type="text" idx="data-xxx-product_qty" id="data-xxx-product_qty" name="data[xxx][product_qty]" value="">
        </div>
      </td>
      <td class="editable k_element_product_price">
        <div style="position:relative;"><input type="text" idx="data-xxx-product_price" id="data-xxx-product_price" name="data[xxx][product_price]" value="">
        </div>
      </td>
      <td class="editable k_element_product_tax">
        <div style="position:relative;"><input type="text" idx="data-xxx-product_tax" id="data-xxx-product_tax" name="data[xxx][product_tax]" value="">
        </div>
      </td>
      <td class="editable k_element_product_line_total_amount">
        <div style="position:relative;"><input type="text" idx="data-xxx-product_line_total_amount" id="data-xxx-product_line_total_amount" name="data[xxx][product_line_total_amount]" value="">
        </div>
      </td>
      <td class="delete"><input type="checkbox" name="delete[]" value="" id="deleteNULL_STRING" style="display: none;" /><label for="deleteNULL_STRING">    <img src="http://localhost/CTO/GXCPL-Billing/couch/addons/repeatable/tablegear/delete.gif" alt="Delete Row" /></label></td>
    </tr>
    <tr id="newDataRow_f_item_detail" class="newRow even">
      <td class="dg-arrange-table-rows-drag-icon">&nbsp;</td>
      <td class="editable k_element_product">
        <div style="position:relative;">
          <select name="data[xxx][product]" idx="data-xxx-product" id="data-xxx-product">
            <option value="-">Select</option>
            <option value="3Ply Mask">3Ply Mask</option>
            <option value="Laptop i3 4th Gen">Laptop i3 4th Gen</option>
          </select>
        </div>
      </td>
      <td class="editable k_element_product_hsn">
        <div style="position:relative;"><input type="text" idx="data-xxx-product_hsn" id="data-xxx-product_hsn" name="data[xxx][product_hsn]" value="">
        </div>
      </td>
      <td class="editable k_element_product_qty">
        <div style="position:relative;"><input type="text" idx="data-xxx-product_qty" id="data-xxx-product_qty" name="data[xxx][product_qty]" value="">
        </div>
      </td>
      <td class="editable k_element_product_price">
        <div style="position:relative;"><input type="text" idx="data-xxx-product_price" id="data-xxx-product_price" name="data[xxx][product_price]" value="">
        </div>
      </td>
      <td class="editable k_element_product_tax">
        <div style="position:relative;"><input type="text" idx="data-xxx-product_tax" id="data-xxx-product_tax" name="data[xxx][product_tax]" value="">
        </div>
      </td>
      <td class="editable k_element_product_line_total_amount">
        <div style="position:relative;"><input type="text" idx="data-xxx-product_line_total_amount" id="data-xxx-product_line_total_amount" name="data[xxx][product_line_total_amount]" value="">
        </div>
      </td>
      <td class="delete"><input type="checkbox" name="delete[]" value="" id="deleteNULL_STRING" style="display: none;" /><label for="deleteNULL_STRING">    <img src="http://localhost/CTO/GXCPL-Billing/couch/addons/repeatable/tablegear/delete.gif" alt="Delete Row" /></label></td>
    </tr>
  </tbody>
</table>

已更新 1 :

您可以获得 tr 的 index,这是变化然后使用该索引我们可以更新该输入值。

已更新 Jquery 代码:

 $(document).on('change', 'select', function() {
  var data = "";
  var i = 0;
  var indexs = $(this).closest("tr").index();//get index no
  console.log(indexs)

  $.ajax({
    type: "GET",
    url: "<cms:show k_site_link />generate/quotation-ajax.php",
    data: "select_id=" + $(this).val(),
    async: false
  }).done(function(data) {

    $('#f_item_detail-' + indexs + '-product_hsn').val(data.product_details[i].product_hsn).attr('readonly', true).addClass("form-control");

    $('#f_item_detail-' + indexs + '-product_qty').attr('onchange', 'add_number()');

    $('#f_item_detail-' + indexs + '-product_price').val(data.product_details[i].product_price).attr('onchange', 'add_number()');

    $('input#f_item_detail-' + indexs + '-product_tax').val(data.product_details[i].product_tax).attr('readonly', true).addClass("form-control");

    $('#f_item_detail-' + indexs + '-line_tax_amount').attr('readonly', true).addClass("form-control");

    $('#f_item_detail-' + indexs + '-product_line_total_amount').val(data.product_details[i].product_line_total_amount).attr('readonly', true).addClass("form-control");
  });

});

更新 2 :

您可以将 this 作为参数传递给您的 line_total() 然后使用它来获得最接近的 tr 索引,然后根据它进行计算。

已更新 Jquery 代码:

$(document).on('change', 'select', function() {
  var indexs = $(this).closest("tr").index();
  var selector = $(this); //save selector
  var i = 0;
   $.ajax({
    type: "GET",
    url: "<cms:show k_site_link />generate/quotation-ajax.php",
    data: "select_id=" + $(this).val(),
    async: false
  }).done(function(data) {
    console.log("de");
    $('#f_item_detail-' + indexs + '-product_hsn').val(data.product_details[i].product_hsn).attr('readonly', true).addClass("form-control");

    $('#f_item_detail-' + indexs + '-product_qty').attr('onchange', 'line_total(this)'); //pass this here ...

    $('#f_item_detail-' + indexs + '-product_price').val(data.product_details[i].product_price).attr('onchange', 'line_total(this)'); //pass this here

    $('input#f_item_detail-' + indexs + '-product_tax').val(data.product_details[i].product_tax).attr('readonly', true).addClass("form-control");

    $('#f_item_detail-' + indexs + '-line_tax_amount').attr('readonly', true).addClass("form-control");

    $('#f_item_detail-' + indexs + '-product_line_total_amount').val(data.product_details[i].product_line_total_amount).attr('readonly', true).addClass("form-control");
    line_total(selector); //call this
  });

});



function line_total(selector) {
  //do same here
  var indexs = $(selector).closest("tr").index()
  var line_qty = $('input#f_item_detail-' + indexs + '-product_qty').val() != "" ? $('input#f_item_detail-' + indexs + '-product_qty').val() : 1;
  var line_tax = $('input#f_item_detail-' + indexs + '-product_tax').val();
  var line_cost = $('input#f_item_detail-' + indexs + '-product_price').val();
  var line_tax_amount = parseFloat(((line_cost * line_tax) / 100) * line_qty).toFixed(2);
  var result = parseFloat((+line_qty * +line_cost) + +line_tax_amount).toFixed(2);
  $('#f_item_detail-' + indexs + '-line_tax_amount').val(line_tax_amount).attr('hidden', true);
  $('#f_item_detail-' + indexs + '-product_line_total_amount').val(result);
  grand_total(); //call this
}

function grand_total() {
  var grand = 0;
  $(".k_element_product_line_total_amount input").each(function() {
    grand += $(this).val() != "" ? parseFloat($(this).val()) : 0
  })
  $("#grand_total").text(grand + 100); //100 is gst change it...according to your need and change id where you need to display grand total
}