1

While trying to get the sum total of the values of an html table column, my variable is returning concatenated strings: instead of 1 + 2 + 3 = 6, I am seeing 1 + 2 + 3 = 123.

The "votes" column values are incremented by an ajax call when the users click on the colors, which is correct. But I also hope to see the sum of all values when "total" is clicked.

Jquery:

$('#total').on('click', function() {
  var sumofval = 0;
  $(".val").each(function () {
    sumofval = sumofval + ($(this).html());
    $('#totalr').html(sumofval);
    console.log(sumofval);
  });
});

The HTML Color-Votes Table:

<table id="tcol" style="width:60%;">
    <thead>
        <tr>
            <th>Color</th>
            <th>Votes</th>
        </tr>
    </thead>
    <tr>
        <td id="red"><a href="#">Red</a></td>
        <td id="redr" class="val"></td>
    </tr>
    <tr>
        <td id="orange"><a href="#">Orange</a></td>
        <td id="oranger" class="val"></td>
    </tr>
    <tr>
        <td id="yellow"><a href="#">Yellow</a></td>
        <td id="yellowr" class="val"></td>
    </tr>
    <tr>
        <td id="green"><a href="#">Green</a></td>
        <td id="greenr" class="val"></td>
    </tr>
    <tr>
        <td id="blue"><a href="#">Blue</a></td>
        <td id="bluer" class="val"></td>
    </tr>
    <tr>
        <td id="indigo"><a href="#">Indigo</a></td>
        <td id="indigor" class="val"></td>
    </tr>
    <tr>
        <td id="total"><a href="#">TOTAL</a></td>
        <td id="totalr"></td>
    </tr>
</table>
Wolfpack'08
  • 3,982
  • 11
  • 46
  • 78
Joe Smith
  • 29
  • 6
  • You add strings to eachother. Use parseInt to cast a string to an integer. https://www.w3schools.com/jsref/jsref_parseint.asp – Wimanicesir Mar 10 '20 at 15:55
  • Does this answer your question? [Sum column values in table](https://stackoverflow.com/questions/41756911/sum-column-values-in-table) – Mister Jojo Mar 10 '20 at 15:58
  • Wimanicesir, I already tried, but I get "NaN" – Joe Smith Mar 10 '20 at 16:06
  • you get `NaN` because you not have any value there currently.. its just empty field. add a values and it will not be `NaN` – Yosef Tukachinsky Mar 10 '20 at 16:11
  • YosefTukachinsky, the values are added when I click on each color via Ajax, it's just that the values are not displayed immediately after the page is completely loaded. – Joe Smith Mar 10 '20 at 16:19

3 Answers3

1
  1. Convert it to number. (You can do it by adding + at the start, or using parseInt function)

  2. sumofval = sumofval +.. can be replaced with sumofval+=..

  3. do $('#totalr').html(sumofval); at each step in the loop is redandent. better do it once at the end

$('#total').on('click', function() {
var sumofval = 0;
$(".val").each(function () {
    sumofval += +$(this).html() || 0;
});
$('#totalr').html(sumofval);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tcol" style="width:60%;">
<thead>
<tr>
<th>Color</th>
<th>Votes</th>
</tr>
</thead>
<tr>
<td id="red"><a href="#">Red</a></td>
<td id="redr" class="val"></td>
</tr>
<tr>
<td id="orange"><a href="#">Orange</a></td>
<td id="oranger" class="val">2</td>
</tr>
<tr>
<td id="yellow"><a href="#">Yellow</a></td>
<td id="yellowr" class="val">3</td>
</tr>
<tr>
<td id="green"><a href="#">Green</a></td>
<td id="greenr" class="val">4</td>
</tr>
<tr>
<td id="blue"><a href="#">Blue</a></td>
<td id="bluer" class="val">5</td>
</tr>
<tr>
<td id="indigo"><a href="#">Indigo</a></td>
<td id="indigor" class="val">6</td>
</tr>
<tr>
<td id="total"><a href="#">TOTAL</a></td>
<td id="totalr"></td>
</tr>

Also you can do:

$('#totalr').html(Array.from($(".val")).reduce(function(a,b){return (+$(b).html() ||0)+a}, 0));
Yosef Tukachinsky
  • 5,570
  • 1
  • 13
  • 29
  • Yosef Tukachinsky, is not working, I still get the values one after other or NaN displayed. Remember the that values are not displayed immediately in the table, they are displayed when I click in each color respectively. – Joe Smith Mar 10 '20 at 16:29
  • good to know.. I updated the snipped. just cast `NaN` to `0`. take a look now – Yosef Tukachinsky Mar 10 '20 at 16:32
  • Excellent, Yosef, thank you so much. Can you also explain me a little bit how this works? I mean, how "|| 0" changed the output? – Joe Smith Mar 10 '20 at 16:43
0

As suggested, use parseInt to parse strings and convert them to integers. Then you can add them to the sumofval correctly.

$('#total').on('click', function() {
  var sumofval = 0;
  $(".val").each(function() {
      if ($(this).text() !== '') {
      sumofval = sumofval + parseInt(($(this).text()));
      $('#totalr').text(sumofval);
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tcol" style="width:60%;">
  <thead>
    <tr>
      <th>Color</th>
      <th>Votes</th>
    </tr>
  </thead>
  <tr>
    <td id="red"><a href="#">Red</a></td>
    <td id="redr" class="val">2</td>
  </tr>
  <tr>
    <td id="orange"><a href="#">Orange</a></td>
    <td id="oranger" class="val"></td>
  </tr>
  <tr>
    <td id="yellow"><a href="#">Yellow</a></td>
    <td id="yellowr" class="val">3</td>
  </tr>
  <tr>
    <td id="green"><a href="#">Green</a></td>
    <td id="greenr" class="val">3</td>
  </tr>
  <tr>
    <td id="blue"><a href="#">Blue</a></td>
    <td id="bluer" class="val">3</td>
  </tr>
  <tr>
    <td id="indigo"><a href="#">Indigo</a></td>
    <td id="indigor" class="val">3</td>
  </tr>
  <tr>
    <td id="total"><a href="#">TOTAL</a></td>
    <td id="totalr"></td>
  </tr>
</table>

Also, consider using .text() to get the value of the element instead of .html().

Juan Marco
  • 3,081
  • 2
  • 28
  • 32
  • Thank you for your answer, but the only thing that changed was NaN to be displayed in the id="totalr" cell. I guess it was because if the .text() function, but still don't get the total sum of the values. – Joe Smith Mar 10 '20 at 16:17
  • @JoeSmith use a conditional to check if the cell element is empty. See updated example above. – Juan Marco Mar 10 '20 at 18:26
  • Thank you so much, Juan. Just one more question, why is it necessary the conditional in this function? – Joe Smith Mar 11 '20 at 00:23
  • Because if the cell happens to be empty, you don't want to add a blank line to `sumofval`. A conditional prevents this by checking if the cell is empty to begin with. – Juan Marco Mar 11 '20 at 02:37
  • Ok, will the blank line (empty cell) prevent the next statement to execute (do the sum of the values are present in the table)? – Joe Smith Mar 11 '20 at 12:03
  • No, it will continue to iterate over the remaining cell elements (if any). – Juan Marco Mar 11 '20 at 17:36
0

If one term isn't a number, JavaScript will treat everything as string and concatenate the values instead. So you need to make sure the value's you're adding up are all number types:

$('#total').on('click', function() {

    var sumofval = 0;
    $(".val").each(function () {
        sumofval = sumofval + getInt($(this).html());
        $('#totalr').html(sumofval);  //this line should be moved outside .each loop
        console.log(sumofval);
    )};

});

function getInt(t){
    if(!isNaN(parseFloat(t)) && isFinite(t)){
        return parseInt(t,10);
    }
    return 0;
}
Dirk Maes
  • 26
  • 2