views:

40

answers:

3

I'm just wondering if this is possible, and if not, the best way to set up event handlers to make this happen...

If I have a spreadsheet-like HTML table like so:

<table>
   <tr id="row1">
      <td><input type="text" class="number" value="1"/></td>
      <td><input type="text" class="number" value="2"/></td>
      <td><input type="text" class="total" /></td>
   </tr>
</table>

can I write a function along the lines of:

function getTotal() {
   var total = 0;
   $("#row1 .number").each(function() {
       total += Number($(this).val());
   };
   return total;
}

$("#row1 .total").val(getTotal);

So that the value of the input total automatically changes to the sum of the number inputs in that row (without having to set onchange event handlers for each number input)?

Ideally, I want the value of total to just change because it's set to be the sum of the other inputs, so that it will set itself to the sum both with the page loads and for any changes to the inputs that its value is derived from.

I'm trying to make a page where the user enters values in the non-total cells, and a function will validate the input, and ideally I'd like to avoid having to update every row each time a user makes a change, but at the same time I don't want to make things overly-complicated by having to write out that the total cell should only update when a cell in its row changes.

A: 

When you do .val(getTotal) you're setting val to a function object (which won't work). If you did .val(getTotal()) you'd only get the total at that moment.

Why not say something like:

$("#row1 .number).change(function () {
    $("#row1 .total").val(getTotal());
});
Skilldrick
+1  A: 

Something like this:

$('#row1 input.number').change(function(){
    var total = 0;
    $('.number').each(function(){
        total += +$(this).val();
    }
    $('.total').val(total);
});

You must have some event that causes recalculation. Here I have made it the change event for all input.number elements, which you say you don't want. You could make it a button event, or anything you like, but there is no way for .total to "just change" without something making that happen.

Sorpigal
+1  A: 

You can do this without using onchange and call it anywhere:

function setTotal() {
   var total = 0;
   $("#row1 .number").each(function() {
       total += parseInt($(this).val());
   };
  $("#row1 .total").val(total);
}

If you wanted to trigger automatically, just add the onchange and pageload like this:

$(function( {
  $("#row1 .number").change(setTotal); //When changing
  setTotal(); //On page load
});
Nick Craver
or `$("#row1 .number").change(setTotal).change()`
karim79
@karim79 - That'd calculate the total `n` times on page load, seems overkill for the shortening you get.
Nick Craver
@Nick - you are spot on, I totally overlooked that. Nice!
karim79
I decided to go a different route, where I have the previous values stored in an array and on any value change, it takes the validated value subtracted from the previous value and adds that to the total field. But it's good to know that I wasn't overlooking some obvious trick for binding the value to the sum of the other fields on load.
Anthony