Kyle Underhill
Kyle Underhill

Reputation: 109

jQuery - Adding sums by data-attribute

I want to sum all calculated totals by data-id but the code only correctly sums the data-id="active" and seemingly calculates a random value for the data-id="pending". The correct value is supposed to be 1550.

$(document).ready(function() {
  $('[data-id="active"]').each(function() {
    const item = $(this);
    var qty = item.find(".sold").text();
    var price = item.find(".cost").text();
    var total = Number(qty) * Number(price);
    item.find(".total").text(total);
    var sum = 0;
    $(".total").each(function() {
      sum += parseInt(
        $(this)
        .text()
        .replace(",", "")
      );
      $("#active_total").text(sum);
    });
    item.find(".total").text(total);
  });
  $('[data-id="pending"]').each(function() {
    const item = $(this);
    var qty = item.find(".sold").text();
    var price = item.find(".cost").text();
    var total = Number(qty) * Number(price);
    item.find(".total").text(total);
    var sum = 0;
    $(".total").each(function() {
      sum += parseInt(
        $(this)
        .text()
        .replace(",", "")
      );
      $("#pending_total").text(sum);
    });
    item.find(".total").text(total);
  });
});
.item {
  border: 1px solid
}

.total {
  font-weight: 900
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Active:
<div class="item" data-id="active">
  <div class="sold">10</div>
  <div class="cost">5</div>
  <div class="total">0</div>
</div>
<div class="item" data-id="active">
  <div class="sold">20</div>
  <div class="cost">30</div>
  <div class="total">0</div>
</div>
Pending:
<div class="item" data-id="pending">
  <div class="sold">10</div>
  <div class="cost">100</div>
  <div class="total">0</div>
</div>
<div class="item" data-id="pending">
  <div class="sold">22</div>
  <div class="cost">25</div>
  <div class="total">0</div>
</div>
Active:
<div id="active_total">0</div>
Pending:
<div id="pending_total">0</div>

Upvotes: 0

Views: 56

Answers (2)

Evik Ghazarian
Evik Ghazarian

Reputation: 1791

You are re-using the sold and cost and total classes. pending adds all the classes 1550 + 650 = 2200.

$(document).ready(function() {
  $('[data-id="active"]').each(function() {
    const item = $(this);
    var qty = item.find(".sold").text();
    var price = item.find(".cost").text();
    var total = Number(qty) * Number(price);
    item.find(".total").text(total);
    var sum = 0;
    $(".total").each(function() {
      sum += parseInt(
        $(this)
        .text()
        .replace(",", "")
      );
      $("#active_total").text(sum);
    });
    item.find(".total").text(total);
  });
  $('[data-id="pending"]').each(function() {
    const item = $(this);
    var qty = item.find(".soldp").text();
    var price = item.find(".costp").text();
    var total = Number(qty) * Number(price);
    item.find(".totalp").text(total);
    var sum = 0;
    $(".totalp").each(function() {
      sum += parseInt(
        $(this)
        .text()
        .replace(",", "")
      );
      $("#pending_total").text(sum);
    });
    item.find(".totalp").text(total);
  });
});
.item {
  border: 1px solid
}

.total {
  font-weight: 900
}
.totalp {
  font-weight: 900
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Active:
<div class="item" data-id="active">
  <div class="sold">10</div>
  <div class="cost">5</div>
  <div class="total">0</div>
</div>
<div class="item" data-id="active">
  <div class="sold">20</div>
  <div class="cost">30</div>
  <div class="total">0</div>
</div>
Pending:
<div class="item" data-id="pending">
  <div class="soldp">10</div>
  <div class="costp">100</div>
  <div class="totalp">0</div>
</div>
<div class="item" data-id="pending">
  <div class="soldp">22</div>
  <div class="costp">25</div>
  <div class="totalp">0</div>
</div>
Active:
<div id="active_total">0</div>
Pending:
<div id="pending_total">0</div>

Upvotes: 1

Nimitt Shah
Nimitt Shah

Reputation: 4587

When you are calculating sum by running a loop on .total. Instead of running a loop directly on .total you should run a loop on .total under data-id="active/pending"..

So for active your loop will be $('[data-id="active"]').find(".total") and for pending total, your loop will be $('[data-id="pending"]').find(".total")

See the Snippet below:

$(document).ready(function() {
  $('[data-id="active"]').each(function() {
    const item = $(this);
    var qty = item.find(".sold").text();
    var price = item.find(".cost").text();
    var total = Number(qty) * Number(price);
    item.find(".total").text(total);
    var sum = 0;
    $('[data-id="active"]').find(".total").each(function() {
      sum += parseInt(
        $(this)
        .text()
        .replace(",", "")
      );
      $("#active_total").text(sum);
    });
    item.find(".total").text(total);
  });
  $('[data-id="pending"]').each(function() {
    const item = $(this);
    var qty = item.find(".sold").text();
    var price = item.find(".cost").text();
    var total = Number(qty) * Number(price);
    item.find(".total").text(total);
    var sum = 0;
    $('[data-id="pending"]').find(".total").each(function() {
      sum += parseInt(
        $(this)
        .text()
        .replace(",", "")
      );
      $("#pending_total").text(sum);
    });
    item.find(".total").text(total);
  });
});
.item {
  border: 1px solid
}

.total {
  font-weight: 900
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Active:
<div class="item" data-id="active">
  <div class="sold">10</div>
  <div class="cost">5</div>
  <div class="total">0</div>
</div>
<div class="item" data-id="active">
  <div class="sold">20</div>
  <div class="cost">30</div>
  <div class="total">0</div>
</div>
Pending:
<div class="item" data-id="pending">
  <div class="sold">10</div>
  <div class="cost">100</div>
  <div class="total">0</div>
</div>
<div class="item" data-id="pending">
  <div class="sold">22</div>
  <div class="cost">25</div>
  <div class="total">0</div>
</div>
Active:
<div id="active_total">0</div>
Pending:
<div id="pending_total">0</div>

Solution #2

You should not run loop on .total. You are already running a loop on data-id=active and data-id=pending. Calculate the total in that loop only.

See the Snippet below:

$(document).ready(function() {
var activeTotal = 0;
var pendingTotal = 0;
  $('[data-id="active"]').each(function() {
    const item = $(this);
    var qty = item.find(".sold").text();
    var price = item.find(".cost").text();
    var total = Number(qty) * Number(price);
    item.find(".total").text(total);
    activeTotal += parseInt(item.find(".total").text());
    /*var sum = 0;
     $('[data-id="active"]').find(".total").each(function() {
      sum += parseInt(
        $(this)
        .text()
        .replace(",", "")
      );
      $("#active_total").text(activeTotal);
    });*/
      $("#active_total").text(activeTotal);
    item.find(".total").text(total);
  });
  $('[data-id="pending"]').each(function() {
    const item = $(this);
    var qty = item.find(".sold").text();
    var price = item.find(".cost").text();
    var total = Number(qty) * Number(price);
    item.find(".total").text(total);
    pendingTotal += parseInt(item.find(".total").text());
    /*var sum = 0;
    $('[data-id="pending"]').find(".total").each(function() {
      sum += parseInt(
        $(this)
        .text()
        .replace(",", "")
      );
      $("#pending_total").text(sum);
    });*/
      $("#pending_total").text(pendingTotal);
    item.find(".total").text(total);
  });
});
.item {
  border: 1px solid
}

.total {
  font-weight: 900
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Active:
<div class="item" data-id="active">
  <div class="sold">10</div>
  <div class="cost">5</div>
  <div class="total">0</div>
</div>
<div class="item" data-id="active">
  <div class="sold">20</div>
  <div class="cost">30</div>
  <div class="total">0</div>
</div>
Pending:
<div class="item" data-id="pending">
  <div class="sold">10</div>
  <div class="cost">100</div>
  <div class="total">0</div>
</div>
<div class="item" data-id="pending">
  <div class="sold">22</div>
  <div class="cost">25</div>
  <div class="total">0</div>
</div>
Active:
<div id="active_total">0</div>
Pending:
<div id="pending_total">0</div>

Upvotes: 1

Related Questions