首页 > 解决方案 > 如何在不生成新行的情况下使用 ajax 成功的 json 访问现有 tr 并填充其 td

问题描述

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

我将可重复区域定义为:

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

可编辑区域是我们可以通过将它们绑定到相应的文本框/选择等来填充数据的区域。

现在我想做的是:

  1. 从名为“产品”的可编辑的下拉列表中选择一个值。
  2. 当一个选项被选中时,一个 AJAX 被调用。这个 AJAX 又返回一些数据。
  3. 我能够获取数据、控制台记录或将其显示在 div 或表格中。

但我真正想做的是:

  1. 由于可重复区域以表格的形式显示,所以存在。我希望能够只获取现有数据中显示的 AJAX JSON 数据。
  2. 如果您看到上面的可编辑项,则存在一个表格,其中每个可编辑项的选择/文本框在 中,有:

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

产品 高速网络 数量 价格 数量 删除
<div>
    <p class="addRow" id="addRow_f_item_detail"><a>Add a Row</a></p>
</div>

使用可重复区域时,我也可以直接添加新行。如果观察到 id 并且名称的值为零 [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 代码,我可以使用它添加一个新的,但它在一个 New 中,而我希望将其附加到包含现有可重复区域的相同区域。阿贾克斯代码:

$(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。任何帮助将非常感激。

提前致谢。问候!@Swati:这个小提琴中的完整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()它会中断。并且总数不计算。你有什么建议?我们如何使用索引值或其他东西。另外,如果您还可以建议我如何以总计(GST 总金额 + 总金额)显示 GST 总金额和总金额,我会非常感激,我会非常感激。

我一点也不擅长 javascript 或 jQuery。

标签: javascriptphpjqueryajaxcouch-cms

解决方案


每当您的选择框发生更改时,您都可以简单地从该选择框中获取closesttr 然后.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

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

更新 的 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
}

推荐阅读