Kolla
Kolla

Reputation: 75

How do I sum up several columns with javascript and jQuery?

I have a table with two different columns that I would like to add up to their respective sums. Right now I just add up one of the columns, I could add up the second column by just making the same JS again but with different names for the values but that is not so pretty. How would I do to change it so it counts the ue column as well as the egen and spit out two results, sum and sum2.

<table>
    <tr>
    <td><asp:TextBox ID="TextBox1" runat="server">Number</asp:TextBox></td>
    <td class="egen"><asp:TextBox ID="TextBox56" runat="server" Columns="1">56</asp:TextBox></td>
    <td class="ue"><asp:TextBox ID="TextBox57" runat="server" Columns="1">57</asp:TextBox></td>
    </tr>
    <tr>
    <td><asp:TextBox ID="TextBox2" runat="server">Worker</asp:TextBox></td>
    <td class="egen"><asp:TextBox ID="TextBox58" runat="server" Columns="1">58</asp:TextBox></td>
    <td class="ue"><asp:TextBox ID="TextBox59" runat="server" Columns="1">59</asp:TextBox></td>
    </tr>
    <tr>
    <td align="right">Sum:</td>
    <td align="center"><span id="sum"></span></td>
    <td align="center"><span id="sum2"></span></td
    </tr>
</table>

This is my javascript that I use to add up the values in the column egen.

$(document).ready(function () {

    //iterate through each td based on class / input and add keyup
    //handler to trigger sum event
    $(".egen :input").each(function () {

        $(this).keyup(function () {
            calculateSum();
        });
    });

});
function calculateSum() {

    var sum = 0;
    // iterate through each td based on class and add the values from the input
    $(".egen :input").each(function () {

        var value = $(this).val();
        // add only if the value is number
        if (!isNaN(value) && value.length != 0) {
            sum += parseFloat(value);
        }
    });
    $('#sum').text(sum);
};

Upvotes: 1

Views: 2823

Answers (2)

bipen
bipen

Reputation: 36541

changed your sum <span> id to its respective class_sum like

<span id="egen_sum"></span>
<span id="ui_sum"></span>
...

so that we can get this working with one function

try this

$('.egen :input, .ue :input').keyup(function(){
     var keyupClass= $(this).parent().hasClass('egen') ? 'egen' : 'ue';
     calculateSum(keyupClass);
 });

function calculateSum(keyupClass) {

  var sum = 0;
  $("."+ keyupClass+" :input").each(function () {

    var value = $(this).val();
    // add only if the value is number
    if (!isNaN(value) && value.length != 0) {
        sum += parseFloat(value);
    }
  });
  $('#'+keyupClass+"_sum").text(sum);
};

this will work for any number of input ... just need to make sure the corresponding sum span is given the right id...

Upvotes: 1

David Hedlund
David Hedlund

Reputation: 129802

You can target all elements in .egen or .ue by the following selector:

 $('.egen :input, .ue :input')

Or if you prefer:

$('.egen, .ue').find(':input')

By the way you don't need to iterate over the collection of elements to bind keyup listeners to them, you can bind to the entire collection immediately:

$('.egen :input, .ue :input').keyup(calculateSum);

EDIT

I note from the presence of #sum and #sum2 that you may want to sum up the columns separately. You could do something like this:

$('.egen :input').keyup(function() { calculateSum('.egen'); });
$('.ue :input').keyup(function() { calculateSum('.ue'); });

function calculateSum(container) {
   var sum = 0;
   $(container).find(':input').each(function() {
       ... 
   });
}

And then of course set the value of #sum or #sum2, respectively. That could be acheived in a number of ways. Either you pass the id, just as we're passing the class above, or you use a class named sum, and have the respective td's reuse the egen and ue classes. That way you could access the correct sum with $(container+'.sum').val(). Another solution would be to just return the sum, and setting it in your keyup listener:

$('.ue :input').keyup(function() {
   $('#sum2').val( calculateSum('.ue') );
});

Note also that your parsing could be simplified. parseFloat will yield NaN for a lot of invalid values, including empty strings and null, so you do not need to check your values closely before calling it. NaN will evaluate to false, so you could always sum by (parsedResult || 0), as the result would be 0, leaving the sum unaffected, if parsedResult is NaN.

Thus:

var sum = 0;
$(container).find(':input').each(function() {
   sum += (parseFloat( $(this).val() ) || 0);
});

Upvotes: 2

Related Questions