Dongsan
Dongsan

Reputation: 85

calculating sums for dynamically added form elements

I have below form, where each .form-row is dynamically added using jQuery when user clicks on Add New button.

My html form (simplified)

<div id="total_sum">
  <!-- here will show up total amount, which is sum of unit[] * price[] - discount[] of all below form-rows -->
</div>

<div id="total_discount">
  <!-- here will show up total discount amount, which is sum of discount[] of all below form-rows -->
</div>

<div id="total_net">
  <!-- here will show up net amount, which is total_sum - total_discount -->
</div>

<form id="form" method="POST" action="">

  <div class="form-row">
    <select name="item[]">
      <option value="item-id-1">Item 1</option>
      <option value="item-id-2">Item 2</option>
      <option value="item-id-3">Item 3</option>
    </select>
    <input type="number" class="unit" value="1" name="unit[]" />
    <input type="number" class="price" name="price[]" />
    <input type="number" class="discount" name="discount[]" />
    <input type="number" class=name="sum[]" />
  </div>

  <div class="form-row">
    <select name="item[]">
      <option value="item-id-1">Item 1</option>
      <option value="item-id-2">Item 2</option>
      <option value="item-id-3">Item 3</option>
    </select>
    <input type="number" class="unit" value="1" name="unit[]" />
    <input type="number" class="price" name="price[]" />
    <input type="number" class="discount" name="discount[]" />
    <input type="number" class="sum" name="sum[]" />
  </div>

  <!-- and users can dynamically add as many form-rows as they want -->

  <div class="form-row">
    <select name="item[]">
      <option value="item-id-1">Item 1</option>
      <option value="item-id-2">Item 2</option>
      <option value="item-id-3">Item 3</option>
    </select>
    <input type="number" class="unit" value="1" name="unit[]" />
    <input type="number" class="price" name="price[]" />
    <input type="number" class="discount" name="discount[]" />
    <input type="number" class="sum" name="sum[]" />
  </div>

</form>

And what I am trying to achieve is two-folded:

I believe I need something that gets all .form-rows, which is triggered whenever there is a change in the form (or every 1 second, perhaps?), and loop through them to calculate respective sum, and calculate the total of sums and discounts when looping is over. I can do this if it's PHP, but I am quite new to jQuery or Javascript so I have no idea where to look into first.

[Adddd]

One thing I did not mention in above explanation is that unit[] has default value of 1 and price[] is at first automatically appended using AJAX, and then users can change the value.

My AJAX to automatically retrieve price when user selects an item.

<script>
jQuery(document).ready(function($) {
    /*  Get Item Price and Item Currency */
    $('#form').on('change', '.item_id', function(){
        var this$ = $(this);
        var $item_id    =  this$.val();

        var ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>';

        // call ajax for item price (returns 0 if item has no price)
        $.ajax({
            url: ajaxurl,
            data:' action=get_item_price_by_id&item_id='+$item_id,
            type:'GET',
            success:function(results) {
                this$.parent().parent().find('.price').empty();
                this$.parent().parent().find('.price').val(results);
            }
        });
    });
});
</script>

Thanks to the advice from Manish Jangir Blogadditic, I came to have below code:

<script>
jQuery(document).ready(function($) {
// Calculate sub-sums on any form changes
    $("#form").change(function() {
        var sum = 0;
        $('.form-row').each(function() {
          sum = Number( $(this).find('unit').val()) * Number( $(this).find('price').val() );
          alert( sum );
        });
    });
});
</script>

However, it works when the form is manually changed, but doesn't work when price is automatically appended by ajax.

Any other suggestions?

Upvotes: 1

Views: 1559

Answers (4)

Sampath Liyanage
Sampath Liyanage

Reputation: 4896

You have to create a delegated event.

jQuery(document).ready(function() {
// Calculate sub-sums on any form changes
    $("#form").on('change','.price, .unit',function() {
        var sum = 0;
        $('.form-row').each(function() {
          sum = Number( $(this).find('.unit').val()) * Number( $(this).find('.price').val() );
          alert( sum );
        });
    });
});

Upvotes: 0

Lakhan
Lakhan

Reputation: 13216

Try this code it will resolve your issue.

jQuery(document).ready(function() {
// Calculate sub-sums on any form changes
    $("#form").on('change',function() {
        var sum = 0;
        $('.form-row').each(function() {
          sum +=  parseInt($(this).find('.unit').val()) +  parseInt($(this).find('.price').val());
        });
    });
});

Upvotes: 0

Rui Wan
Rui Wan

Reputation: 1

Value changed by Javascript will not trigger onchange event. And this rule applied on JQuery's change function too. So you may need to manually trigger onchange event after the updating. With Jquery you may use .trigger(), check here: http://api.jquery.com/trigger/

Upvotes: 0

Manish Jangir
Manish Jangir

Reputation: 5437

If your button #form comes with the last added dynamic element then you can try this out because .change or .on don't work with dynamically appended html elements. jQuery has given a $(document).on event to do that.

jQuery(document).ready(function($) {
// Calculate sub-sums on any form changes
    $(document).on('click','#form',function() {
        var sum = 0;
        $('.form-row').each(function() {
          sum += Number( $(this).find('.unit').val()) * Number( $(this).find('.price').val() );
          alert( sum );
        });
    });
});

Upvotes: 1

Related Questions