1

I have Html code with dynamic forms. In that forms i need to perform arithmetic operation. In first row its working fine from next row which mean the dynamic one its not working for me.

$(document).ready(function(e) {
  var html = '<div id ="container">                <input type="text" name="tax_val[]" id="P_tax_val" size="10" placeholder="Val" />                     <select name="tax_per[]" id="P_tax_per" >            <option value="2">2</option>                 <option value="8">8</option>                 <option value="12">12</option>             </select>                          <input type="text" name="cgst_val[]" id="P_cgst_val" size="3" placeholder="cs" />                           <input type="text" name="sgst_val[]" id="P_sgst_val" size="3" placeholder="gs" />               <input type="text" name="total[]" id="P_total"size="5" placeholder="total"/>                      <a href="#" id="remove">X</a></div>'

  //Add More values

  $("#add").click(function(e) {
    $("#container").append(html);
  });
  //Remove rows
  $("#container").on('click', '#remove', function(e) {
    $(this).parent('div').remove();
  });
  //calculate CGST and SGST values
  $("#P_tax_per").click(function(e) {
    num1 = $("#P_tax_val").val();
    num2 = $("#P_tax_per").val();
    num3 = (num1 * num2) / 100;
    $("#P_cgst_val").val(num3);
    $("#P_sgst_val").val(num3);
    num4 = parseInt(num1) + parseInt(num3) + parseInt(num3);
    $("#P_total").val(num4);
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<form action="ActionServlet" method="post">
  <p class="noscroll">
    <a href="#" id="add">ADD</a>
    <input type="submit" name="SUBMIT" />
  </p>
  <div id="container">
    <input type="text" name="tax_val[]" id="P_tax_val" size="10" placeholder="Val" value="" />
    <select name="tax_per[]" id="P_tax_per" value="">
      <option value="2">2</option>
      <option value="8">8</option>
      <option value="12">12</option>
    </select>
    <input type="text" name="cgst_val[]" id="P_cgst_val" size="3" placeholder="cs" value="" />
    <input type="text" name="sgst_val[]" id="P_sgst_val" size="3" placeholder="gs" value="" />
    <input type="text" name="total[]" id="P_total" size="5" placeholder="total" value="" />
  </div>
  </div>
</form>
</html>
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
V. Monisha
  • 89
  • 6
  • If i change the Id with class it will reflect all element with same values. – V. Monisha Jun 04 '19 at 09:59
  • If you don't amend the classes only the first row of inputs will ever work. You need to use DOM traversal with the classes to find related content. I've added an answer below to give you a complete example. – Rory McCrossan Jun 04 '19 at 10:05

2 Answers2

0

There's several issues here. Firstly you're duplicating the same id attributes when you clone the content which is invalid, and will mean the events are only bound to the first instances of those elements. You need to use classes instead.

You should avoid having large chunks of HTML in your JS logic. In this case you can simply clone() the group of inputs when adding a new group, re-setting the values back to defaults before adding them in to the DOM.

To perform the calculation on the dynamically appended elements you will need to use a delegated event handler.

When performing the calculation you need to retrieve the inputs within the current group by using DOM traversal. In this case closest() will work once you surround each group of inputs in its own div. Next you should use the change event with select elements, not click, for accessibility reasons. You should perform the calculation on the input event of the text box as well as when the select is changed.

Finally, your calculation logic is incorrect as num3 is a floating point value, yet you parse it to an integer which will remove the precision and affect the outcome. You need to remove parseInt() from that value.

With all that said, try this:

$(document).ready(function() {
  $("#add").click(function() {
    var $clone = $('#container .group:first').clone();
    $clone.find('input').val('');
    $clone.find('select').val('2');
    $clone.append('<a href="#" class="remove">X</a>');
    $clone.appendTo('#container');
  });

  $("#container").on('click', '.remove', function() {
    $(this).parent('.group').remove();
  });

  $('#container').on('input, change', ".P_tax_per, .P_tax_val", function() {
    var $group = $(this).closest('.group');
    var num1 = parseInt($group.find(".P_tax_val").val(), 10) || 0;
    var num2 = parseInt($group.find(".P_tax_per").val(), 10) || 0;
    var num3 = (num1 * num2) / 100;
    var num4 = num1 + num3 * 2;
    
    $group.find(".P_cgst_val").val(num3);
    $group.find(".P_sgst_val").val(num3);
    $group.find(".P_total").val(num4);
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<form action="ActionServlet" method="post">
  <p class="noscroll">
    <a href="#" id="add">ADD</a>
    <input type="submit" name="SUBMIT" />
  </p>
  <div id="container">
    <div class="group">
      <input type="text" name="tax_val[]" class="P_tax_val" size="10" placeholder="Val" value="" />
      <select name="tax_per[]" class="P_tax_per" value="">
        <option value="2">2</option>
        <option value="8">8</option>
        <option value="12">12</option>
      </select>
      <input type="text" name="cgst_val[]" class="P_cgst_val" size="3" placeholder="cs" value="" />
      <input type="text" name="sgst_val[]" class="P_sgst_val" size="3" placeholder="gs" value="" />
      <input type="text" name="total[]" class="P_total" size="5" placeholder="total" value="" />
    </div>
  </div>
</form>
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
0

You have used id which is unique. use like my snippet. I used class and used closest to find the elements.

Try like this,

$(document).ready(function(e) {
  var html = '<div class ="container">                <input type="text" name="tax_val[]" class="P_tax_val" size="10" placeholder="Val" />                     <select name="tax_per[]" class="P_tax_per" >            <option value="2">2</option>                 <option value="8">8</option>                 <option value="12">12</option>             </select>                          <input type="text" name="cgst_val[]" class="P_cgst_val" size="3" placeholder="cs" />                           <input type="text" name="sgst_val[]" class="P_sgst_val" size="3" placeholder="gs" />               <input type="text" name="total[]" class="P_total"size="5" placeholder="total"/>                      <a href="#" id="remove">X</a></div>'

  //Add More values

  $("#add").click(function(e) {
    $("#fullContainer").append(html);
  });
  //Remove rows
  $("#fullContainer").on('click', '#remove', function(e) {
    $(this).parent('div').remove();
  });
  //calculate CGST and SGST values
  $("#fullContainer").on("click", "select.P_tax_per", function(){
    num1 = $(this).closest(".container").find(".P_tax_val").val();
    num2 = $(this).closest(".container").find(".P_tax_per").val();
    num3 = (num1 * num2) / 100;
    var num3 = (num1 * num2) / 100;
    var num4 = parseFloat(num1) + parseFloat(num3 * 2);
    $(this).closest(".container").find(".P_cgst_val").val(num3);
    $(this).closest(".container").find(".P_sgst_val").val(num3);
    $(this).closest(".container").find(".P_total").val(num4);
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
  <form action="ActionServlet" method="post">
    <p class="noscroll">
      <a href="#" id="add">ADD</a>
      <input type="submit" name="SUBMIT" />
    </p>
    <div id="fullContainer">
      <div class="container">
        <input type="text" name="tax_val[]" class="P_tax_val" size="10" placeholder="Val" value="" />
        <select name="tax_per[]" class="P_tax_per" value="">
          <option value="2">2</option>
          <option value="8">8</option>
          <option value="12">12</option>
        </select>
        <input type="text" name="cgst_val[]" class="P_cgst_val" size="3" placeholder="cs" value="" />
        <input type="text" name="sgst_val[]" class="P_sgst_val" size="3" placeholder="gs" value="" />
        <input type="text" name="total[]" class="P_total" size="5" placeholder="total" value="" />
      </div>
    </div>
  </form>
</html>
Syed mohamed aladeen
  • 6,507
  • 4
  • 32
  • 59