jQuery: Calculate column totals for sections in table
<p>I have the following table:</p>

<pre><code>&lt;table class="stripeMe" cellpadding="0" cellspacing="0" width="100%"&gt;
&lt;tbody&gt;
    &lt;tr&gt;
        &lt;th&gt;
            MEALS
        &lt;/th&gt;
        &lt;th style="text-align: center;"&gt;
            02/6
        &lt;/th&gt;
        &lt;th style="text-align: center;"&gt;
            02/7
        &lt;/th&gt;
        &lt;th style="text-align: center;"&gt;
            02/8
        &lt;/th&gt;
        &lt;th style="text-align: center;"&gt;
            02/9
        &lt;/th&gt;
        &lt;th style="text-align: center;"&gt;
            02/10
        &lt;/th&gt;
        &lt;th style="text-align: center;"&gt;
            02/11
        &lt;/th&gt;
        &lt;th style="text-align: center;"&gt;
            02/12
        &lt;/th&gt;
        &lt;th style="text-align: center;"&gt;
            Total
        &lt;/th&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;
            CONGREGATE - HEALTHY BALANCE
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="sum" id="116|2/6/2011"
            name="116|2/6/2011" value="0" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="sum" id="116|2/7/2011"
            name="116|2/7/2011" value="18" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="sum" id="116|2/8/2011"
            name="116|2/8/2011" value="33" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="sum" id="116|2/9/2011"
            name="116|2/9/2011" value="20" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="sum" id="116|2/10/2011"
            name="116|2/10/2011" value="0" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="sum" id="116|2/11/2011"
            name="116|2/11/2011" value="0" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="sum" id="116|2/12/2011"
            name="116|2/12/2011" value="0" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" readonly="readonly" size="3" class="total"
            id="116|Total" name="116|Total" value="71" /&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr style="background: #79a2cb;"&gt;
        &lt;td&gt;
            &lt;strong&gt;Totals&lt;/strong&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="totalCategory" id="MEALS|2/6/2011"
            name="MEALS|2/6/2011" value="0" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="totalCategory" id="MEALS|2/7/2011"
            name="MEALS|2/7/2011" value="18" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="totalCategory" id="MEALS|2/8/2011"
            name="MEALS|2/8/2011" value="33" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="totalCategory" id="MEALS|2/9/2011"
            name="MEALS|2/9/2011" value="20" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="totalCategory" id="MEALS|2/10/2011"
            name="MEALS|2/10/2011" value="0" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="totalCategory" id="MEALS|2/11/2011"
            name="MEALS|2/11/2011" value="0" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="totalCategory" id="MEALS|2/12/2011"
            name="MEALS|2/12/2011" value="0" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" readonly="readonly" size="3" class="total"
            id="MEALS|Total" name="MEALS|Total" value="71" /&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;th&gt;
            BEVERAGES
        &lt;/th&gt;
        &lt;th style="text-align: center;"&gt;
            02/6
        &lt;/th&gt;
        &lt;th style="text-align: center;"&gt;
            02/7
        &lt;/th&gt;
        &lt;th style="text-align: center;"&gt;
            02/8
        &lt;/th&gt;
        &lt;th style="text-align: center;"&gt;
            02/9
        &lt;/th&gt;
        &lt;th style="text-align: center;"&gt;
            02/10
        &lt;/th&gt;
        &lt;th style="text-align: center;"&gt;
            02/11
        &lt;/th&gt;
        &lt;th style="text-align: center;"&gt;
            02/12
        &lt;/th&gt;
        &lt;th style="text-align: center;"&gt;
            Total
        &lt;/th&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;
            SKIM MILK
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="sum" id="67|2/6/2011"
            name="67|2/6/2011" value="0" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="sum" id="67|2/7/2011"
            name="67|2/7/2011" value="4" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="sum" id="67|2/8/2011"
            name="67|2/8/2011" value="10" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="sum" id="67|2/9/2011"
            name="67|2/9/2011" value="5" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="sum" id="67|2/10/2011"
            name="67|2/10/2011" value="10" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="sum" id="67|2/11/2011"
            name="67|2/11/2011" value="4" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="sum" id="67|2/12/2011"
            name="67|2/12/2011" value="0" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" readonly="readonly" size="3" class="total"
            id="67|Total" name="67|Total" value="33" /&gt;
        &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr style="background: #79a2cb;"&gt;
        &lt;td&gt;
            &lt;strong&gt;Totals&lt;/strong&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="totalCategory" id="BEVERAGES|2/6/2011"
            name="BEVERAGES|2/6/2011" value="0" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="totalCategory" id="BEVERAGES|2/7/2011"
            name="BEVERAGES|2/7/2011" value="4" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="totalCategory" id="BEVERAGES|2/8/2011"
            name="BEVERAGES|2/8/2011" value="10" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="totalCategory" id="BEVERAGES|2/9/2011"
            name="BEVERAGES|2/9/2011" value="5" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="totalCategory" id="BEVERAGES|2/10/2011"
            name="BEVERAGES|2/10/2011" value="10" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="totalCategory" id="BEVERAGES|2/11/2011"
            name="BEVERAGES|2/11/2011" value="4" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" size="3" class="totalCategory" id="BEVERAGES|2/12/2011"
            name="BEVERAGES|2/12/2011" value="0" /&gt;
        &lt;/td&gt;
        &lt;td style="text-align: center;"&gt;
            &lt;input type="text" style="text-align: center;" readonly="readonly" size="3" class="total"
            id="BEVERAGES|Total" name="BEVERAGES|Total" value="33" /&gt;
        &lt;/td&gt;
    &lt;/tr&gt;

&lt;/tbody&gt;
</code></pre>

<p></p>

<p>I'd like to be able to sum each column and insert the value into a texbox. I have it working for totals on a row level using the following jQuery:</p>

<pre><code>$('input.sum').change(function () {
            var sum = 0;
            $(this).closest('tr').find('input.sum').each(function (i) {
                var val = parseInt($(this).val(), 10);
                if (isNaN(val) || val === undefined) {
                    return;
                }
                sum += val;
            });
            $(this).closest('tr').find('input.total').val(sum);
        });
</code></pre>

<p>Each class for the column textbox totals has a name of totalCategory.</p>

<p>Any help with this on how to calculate the column totals would be greatly appreciated.</p>

<p>=========Edit============================</p>

<p>Ok. I'm working through this from the help below. I've changed my javascript to the following:</p>

<pre><code>$('input.sum').change(function () {
            var sum = 0;
            $(this).closest('tr').find('input.sum').each(function (i) {
                var val = parseInt($(this).val(), 10);
                if (isNaN(val) || val === undefined) {
                    return;
                }
                sum += val;
            });
            $(this).closest('tr').find('input.total').val(sum);

            var tableID = $(this).closest('tr').parents('table').attr('id');
            var columnIndex = $(this).closest('td').attr("cellIndex");
            sumOfColumns(tableID, columnIndex, true);

        });
</code></pre>

<p>I've also added a new function:</p>

<pre><code> function sumOfColumns(tableID, columnIndex, hasHeader) {
        var tot = 0;
        $("#" + tableID + " tr" + (hasHeader ? ":gt(0)" : ""))
          .children("td:nth-child(" + columnIndex + ") input.sum")
          .each(function () {
              tot += parseInt($(this).val());
          });
          alert(tot);
    }
</code></pre>

<p>The problem now is that I don't get the correct value from the function sumOfColumns. Am I missing something with the code?</p>

<p>Thanks for the help thus far.</p>

<p>======Solution=========</p>

<p>Here is the solution I came up with:</p>

<pre><code> function sumOfColumns(tableID, columnIndex, hasHeader) {
        var tot = 0;
        $("#" + tableID + " tr" + (hasHeader ? ":gt(0)" : ""))
          .children("td:nth-child(" + (columnIndex + 1) + ")").find('input.sum')
          .each(function () {
              var val = parseInt($(this).val(), 10);
              if (isNaN(val) || val === undefined) {
                  val = 0;
                  $(this).val(0);
              }
              tot += parseInt(val);
          });

          $("#" + tableID + " tr" + (hasHeader ? ":gt(0)" : "")).children("td:nth-child(" + (columnIndex + 1) + ")").find('input.totalCategory').val(tot);
    }


    $(document).ready(function () {
        $('input.sum').change(function () {
            //Initialize variable to hold the totals
            var sum = 0;
            var grandTotal = 0;

            //Sum the row numbers
            $(this).closest('tr').find('input.sum').each(function (i) {
                var val = parseInt($(this).val(), 10);
                if (isNaN(val) || val === undefined) {
                    return;
                }
                sum += val;
            });

            //Assign the row total to the textbox
            $(this).closest('tr').find('input.total').val(sum);

            //Calculate column totals
            var tableID = $(this).closest('tr').parents('table').attr('id');
            var columnIndex = $(this).closest('td').attr("cellIndex");
            sumOfColumns(tableID, columnIndex, true);

            //Calculate grand totals for the last row
            $("#" + tableID + " tr:last").find('input.totalCategory').each(function (i) {
                var val = parseInt($(this).val(), 10);
                if (isNaN(val) || val === undefined) {
                    return;
                }
                grandTotal += val;
            });

            $("#" + tableID + " tr:last").find('input.grandTotal').val(grandTotal);



        });
    });
</code></pre>

<p>Thanks for all the help!</p>
