user3368088
user3368088

Reputation: 151

split values are not getting calculated properly

This is related to this thread. I am adding line items with auto calculations according to the selection of price, quantity, discount and tax.

Only for tax I pass values as 1_2, i.e. both id and tax rate. So for the first line item I get a proper value for tax, but from the second onwards, whatever tax I select, it takes the first item's tax value. I don't see what I am doing wrong.

Here is my HTML through which I select the values:

    <td>
        <select name="tax[]" class="form-control tax" id="tax_1" style="width:80px;">
            <option value="">Tax</option>
<?php 
    $s1 = mysqli_query($con, "select * from taxes");
    while($s2 = mysqli_fetch_array($s1)) { 
        $options .= "<option value='". $s2['tax_id']."_".$s2['rate']."'>"
                    .$s2['name'].'-'.$s2['rate'] . "</option>"; 
?>
            <option value="<?php echo $s2['tax_id']."_".$s2['rate']; ?>">
                <?php echo $s2['name'].'-'.$s2['rate']; ?></option>
<?php
    }  
?>
        </select>
    </td>                        
</tr>  

My script:

  $(".addmore").on('click', function() {
    count = $('table tr').length - 1;
    var data = "<tr><td><input type='checkbox' class='case'/></td><td><input class='form-control' type='text' id='productname_" + i + "' name='productname[]'/></td><td><input class='form-control' type='text' id='productcode_" + i + "' name='productcode[]'/></td> <td><textarea class='form-control' id='description_"+ i + "' name='description[]'></textarea></td><td><select class='form-control uom' id='uom_" + i + "' name='uom[]'><option value=''>UOM</option>" + options1 + "</select></td><td><input class='form-control price' type='text' id='price_" + i + "' name='price[]'/></td><td><select class='form-control tax' id='tax_" + i + "' name='tax[]'><option value=''>Tax</option>" + options + "</select></select></td><td><input class='form-control quantity' type='text' id='quantity_" + i + "' name='quantity[]'/></td><td><input class='form-control discount' type='text' id='discount_" + i + "' name='discount[]'/></td><td><input class='form-control amount' type='text' id='amount_" + i + "' name='amount[]'/></td><td><input class='form-control tamount' type='text' id='tamount_" + i + "' name='tamount[]'/></td></tr>";
    $('table').append(data);
    row = i;
    $('#productname_' + i).autocomplete({
      source: function(request, response) {
        $.ajax({
          url: 'ajax.php',
          dataType: "json",
          method: 'post',
          data: {
            name_startsWith: request.term,
            type: 'items_table',
            row_num: row
          },
          success: function(data) {
            response($.map(data, function(item) {
              var code = item.split("|");
              return {
                label: code[0],
                value: code[0],
                data: item    
              }
            }));
          }
        });
      },

  $('body').on('change', '.quantity,.price,.discount,.tax', function() {
    var tr = $(this).parent().parent();
    var qty = tr.find('.quantity').val();
    var price = tr.find('.price').val();
    var taxVal= $('.tax').val();
    var tax_id=taxVal.split('_')[0];
    var rate=taxVal.split('_')[1];
  // Here from 2nd line item i am getting 1st line items value for tax. 
    var dis = tr.find('.discount').val();
    var amt = (qty * price) - (qty * price * dis) / 100;
    var tax1 = (amt * (rate / 100));

    tax1 = Number((tax1).toFixed(2));
    tr.find('.tamount').val(tax1);
    ttotal();
    tr.find('.amount').val(amt);
    total();
    //tr.find('.ttotal1').val();
  });

Upvotes: 0

Views: 95

Answers (2)

Nana Partykar
Nana Partykar

Reputation: 10548

"So for the first line item I get a proper value for tax, but from the second onwards, whatever tax I select, it takes the first item's tax value."

As Far I See, You are not taking the current object values. You always referring the class name. Since, every inputs having ID ( separated by _ ). You can fetch the ID of that particular Input field and can split to get exact/current ID of it. Using this current ID, you can find other input values too.

Updated Code

$('body').on('change', '.quantity,.price,.discount,.tax', function() {

    var tr = $(this).parents('tr');
    var id_clicked =  $(this).attr('id');
    var current_id = id_clicked.split("_")[1];

    var qty = tr.find("#quantity_"+current_id).val();
    var dis = tr.find("#tax_"+current_id).val();
    var price = tr.find("#price_"+current_id).val();
    var taxVal= tr.find("#tax"+current_id).val();
    var rate = taxVal.split('_')[1];

    var amt = (qty * price) - (qty * price * dis) / 100;
    var tax1 = (amt * (rate / 100));
    tax1 = Number((tax1).toFixed(2));

    tr.find('#tamount_'+current_id).val(tax1);
    tr.find('#tamount_'+current_id).val(amt);
  });

Upvotes: 0

NoobishPro
NoobishPro

Reputation: 2549

I see. This is because you're selecting the .tax selector like so:

var taxVal= $('.tax').val();

You should use $(this) to grab it. Because the way you're doing it, it'll always grab the first one.

Please see this jsfiddle for an example

In short: $('.tax'); will select any element with the .tax class within the DOM. When you use any type of binding, this will be the element that triggered the binding (The change event)

So, by grabbing $(this), you'll be grabbing the element that has actually been changed. By grabbing $('.tax'), you'll just grab any .tax element that is in the DOM.

Hope this helps :)

Example html

<select class="tax" id="tax">
  <option value="1_2">1_2</option>
  <option value="1_3">1_3</option>
  <option value="2_2">2_2</option>
</select>

<select class="tax" id="tax">
  <option value="3_2">3_2</option>
  <option value="3_3">3_3</option>
  <option value="3_2">3_2</option>
</select>

Example jQuery

$('.tax').on('change', function() {

  var $changedInput = $(this);
  var value = $changedInput.val();
  var aValues = value.split('_');
  var tax_id = aValues[0];
  var rate = aValues[1];

  alert("tax_id: " + tax_id + " Rate:" + rate );
});

p.s. in your own code, you are already grabbing the parentrow for the other fields in order to find them, so why not do this for .tax also?

tr.find('.tax').val();

Upvotes: 1

Related Questions