Mark Mark - 7 months ago 27
Javascript Question

Simple JavaScript/jQuery sum function using bind

I have an HTML form that has multiple instances of doing a basic SUM calculation in different textboxes. I don't have control of updating or rewriting the HTML. I need a way to write a generic sum function that will "listen" for the change in any of the textboxes, do the sum, and output the result in those textboxes result textbox.

For example:

<input id="txtBox1"/>
<input id="txtBox2"/>
<input id="txtSumOfBox1AndBox2"/>

<input id="txtBox3"/>
<input id="txtBox4"/>
<input id="txtSumOfBox3AndBox4"/>


What I would like to do is "bind" or "listen" (I'm not sure which to use) that will "listen" to a change in "txtBox1" or "txtBox2", do the math and then output the sum into the result box, "txtSumOfBox1AndBox2". It will do the same for boxes 3 and 4.

I could have 1 to many of these and they all need to use the same sum calculation and output to their respective result fields.

I could have an instance where I have the following as well:

<input id="txtBox5"/>
<input id="txtBox6"/>
<input id="txtBox7"/>
<input id="txtBox8"/>
<input id="txtBox9"/>
<input id="txtSumOfBox5Through9"/>


...and here is my javascript:

$('#txtProductAUsed,#txtProductBUsed').on('keypress change', {
inputs: "txtProductAUsed:txtProductBUsed",
output: "txtTotalUsed"
}, calc_sum);

$('#txtMixedInValue,#txtAmtNeeded,#txtLeftover').on('change', {
inputs: "txtMixedInValue:txtAmtNeeded:txtLeftover",
output: "txtTotalProduct"
}, calc_sum);

function calc_sum(event) {
var sum = 0;
var inputFields = event.data.inputs;
var totalField = event.data.output;

$.each(inputFields.split(':'), function() {
sum += Number($('#' + this).val());
});

$('#' + totalField).val(sum);
}


I've read through the documentation on jQuery bind but it's not making sense to me on how to get the parameters I need. I get the concept of looking for the 'change' event but not coding it to make it generic enough to accept any of the inputs.

EDIT
I played around with the "on" method and came up with this.

Here's the JSFiddle of my solution:
https://jsfiddle.net/mrhankuk/4ox7y1v1/1/

Answer

EDITED (for update the value when change the same input again):

So, I changed your way to listener your sum by selectors, so you can set on the array any selectors you want:

$.fn.sumListener = function() {
  var args = arguments;
  var $sumInput = $(this);
  $sumInput.prop("disabled", "disabled");
  for(i in args) {
    $(arguments[i]).on("change", function() {
        $sumInput.val(0);
        $(Array.from(args).join(",")).each(function() {
          $sumInput.val(+$sumInput.val() + +$(this).val());
        });
    });         
  }
};
$("#txtTotalUsed").sumListener("#txtProductAUsed", "#txtProductBUsed");
$("#txtTotalProduct").sumListener("#txtMixedInValue", "#txtAmtNeeded", "#txtLeftover", ".any");

Fiddle: https://jsfiddle.net/diegopolido/sexd7b28/2/

I hope it helps