lharby lharby - 2 months ago 6
jQuery Question

Get sums of rows with jquery

I am trying to create a simple totaller, my basic html looks like this:

<ul>
<li class="header">
<span>&nbsp;</span>
...
<span>Total</span>
</li>
<li>
<span>0</span>
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
<span class="total">0</span>
</li>
<li>
<span>1</span>
<span>10</span>
<span>20</span>
<span>30</span>
<span>40</span>
<span>50</span>
<span class="total">0</span>
</li>
<li>
<span>5</span>
<span>1</span>
<span>1</span>
<span>9</span>
<span>3</span>
<span>2</span>
<span class="total">0</span>
</li>
</ul>


jQuery function:

var eaList = $('ul li span').not('.total, .header span');
var sum = 0;
eaList.each(function(){
var total = $(this).parent().find('.total');
sum += parseFloat($(this).text());
total.text(sum);
});


This is currently cumulatively adding to the total at the end of the function, not by row.

I was hoping it would be a case of a simple selector
var total = $(this).parent().find('.total');
(I have also tried
var total = $(this).closest('.total');
.

Do I need an empty array to push the total to before outputting the sum to the
.total
element? Or is there something in built in jquery which should return the sum using the correct selector?

JSFIDDLE: https://jsfiddle.net/lharby/y991hkf6/

Answer

The selector $('ul li span').not('.total, .header span'); will select all the spans except those classes and add them and update the total in the DOM.

Use nested each to get the textContent of spans and add them.

// Get all the `li`s inside `ul` except header
$('ul li:not(.header)').each(function () {

    // Initialize total to zero
    var total = 0;

    // Get all the spans inside current `li`
    // except the `.total`
    $(this).find('span:not(.total)').each(function () {

        // Add the value to total
        // If no value, then add zero
        total += Number($(this).text()) || 0;
    });

    // Update the total in the `.total` of current `li`
    $('.total', this).text(total);
});

$('ul li:not(.header)').each(function() {
	var total = 0;
    $(this).find('span:not(.total)').each(function() {
        total += Number($(this).text()) || 0;
    });
    $('.total', this).text(total);
});
body {
    font-family: sans-serif;
    font-size: 11px;
    background: #F3F5F6;
}

ul {
    margin: 0;
    padding: 0;
}

li {
    list-style: none;
    margin: 0 1px 3px 0;
}

.header span {
    background: none;
}

span {
    display: inline-block;
    width: 25px;
    height: 25px;
    background: #FFF;
    text-align: center;
    line-height: 25px;
}

.total {
    font-weight: bold;
    font-size: 1.2em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
    <li class="header">
        <span>&nbsp;</span>
        <span>&nbsp;</span>
        <span>&nbsp;</span>
        <span>&nbsp;</span>
        <span>&nbsp;</span>
        <span>&nbsp;</span>
        <span>Total</span>
    </li>
    <li>
        <span>0</span>
        <span>1</span>
        <span>2</span>
        <span>3</span>
        <span>4</span>
        <span>5</span>
        <span class="total">0</span>
    </li>
    <li>
        <span>1</span>
        <span>10</span>
        <span>20</span>
        <span>30</span>
        <span>40</span>
        <span>50</span>
        <span class="total">0</span>
    </li>
    <li>
        <span>5</span>
        <span>1</span>
        <span>1</span>
        <span>9</span>
        <span>3</span>
        <span>2</span>
        <span class="total">0</span>
    </li>
</ul>