I am using CouchCMS. In CouchCMS there is a concept of repeatable regions. This in fact generates tables and displays the repeatable contents in it.
I have the repeatable region defined as:
<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>
Where the editables are the regions where we can fill in the data by bounding them to the respective textboxes/ selects, etc.
Now What I am trying to do is:
- Select a value from the dropdown of the editable named "product".
- When an option is selected, an AJAX is called. This AJAX in turn returns some data.
- I am able to get the data, console log it or display it in a div or a table.
But what I really want to do is:
- Since the repeatable region is shown is the form of a table, the exists. I want to be able to just get the AJAX JSON data displayed in the of the existing data.
- If you see the editables above, a table exists with each editables' select/textbox in the , there are:
- product (select, for product name)
- product_hsn (textbox, with to be created and be filled by AJAX JSON)
- product_qty (textbox, with to be created but needs to be blank)
- product_price (textbox, with to be created and be filled by AJAX JSON)
- product_tax (textbox, with to be created and be filled by AJAX JSON)
- product_line_total_amount (textbox, with to be created but needs to be blank)
Now the repeatable region creates a structure as follows ( for the above defined repeatable region):
Product | HSN | Quantity | Price | Tax | Amount | Delete |
---|
<div>
<p class="addRow" id="addRow_f_item_detail"><a>Add a Row</a></p>
</div>
I can add new rows also right out of the box when using repeatable regions. If one observes ids and the names have a zero [0] this keeps on incrementing as one would add the new rows. The script helping in this above code generation is:
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 -";
Just in case if required this is my AJAX code, using which I am able to add a new but it is in a New while I want the to be appended to the same that contains the existing repeatable regions. AJAX CODE:
$(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);
})
});
And my AJAX file has the code:
<?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(); ?>
What I am looking for: Add the AJAX success JSON values to the respective textboxes in the existing , and rather than adding a new or or . I am unable to set the correct jQuery. Any help would be really appreciated.
Thanks in advance. Regards! @Swati: Full HTML in this fiddle (with some changes in the AJAX part, which partially works and outputs what I want to achieve. The value is put into the textbox but for each new row the same textbox value is updated from the first row, if i could update the textbox values row wise it would be great)
EDIT #1 I have used your code (@Swati) as follows and yes it works fine (to an extent).
<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>
It is solving the issue of going back and editing the product and hence updating the line item value as you had suggested.
But if you see the function line_total() it breaks. And the total are not calculated. What do you suggest? How can we use the indexs value or something else. Also, I would be greatful if you could also suggest me how can we display the GST Amount total and Amount Total at the end with a Grand Total (GST Amount Total + Amount Total), I would be really greatful.
I am not good with javascript or jQuery at all.