Kyle Underhill
Kyle Underhill

Reputation: 109

jQuery - Total and Subtotal with items

The HTML structure is broken out into individual Orders with multiple Item's on each Order.

The problem with my code is that the total for each Order is cumulative and doesn't just add the subtotal for that instance of Order. How do I get the total for each Order instance instead of having the totals accumulate with each additional Order?

$.fn.digits = function () {
  return this.each(function () {
    $(this).text(
      $(this)
        .text()
        .replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,")
    );
  });
};
$(document).ready(function () {
  var historyTotal = 0;
  var historyXp = 0;
  $('[data-id="history"]').each(function () {
    const item = $(this);
    var xp = 10;
    var fee = 0.15;
    var qty = item.find(".history__sold").text();
    var price = item.find(".history__cost").text();
    var subtotal = Number(qty) * Number(price);
    var xptotal = Number(qty) * Number(xp);
    var bonusXp = Number(
      item.closest("[data-id='order']").find(".bonus__xp").text()
    );
    item.find(".history__subtotal").text(subtotal.toFixed(2)).digits();
    item
      .find(".history__fee")
      .text((subtotal * (1 * fee)).toFixed(2))
      .digits();
    historyTotal += parseInt(
      item.find(".history__subtotal").text().replace(",", "")
    );
    item
      .closest("[data-id='order']")
      .find(".order__total")
      .text(((1 + fee) * historyTotal).toFixed(2))
      .digits();
    item
      .closest("[data-id='order']")
      .find(".order__fee")
      .text((fee * historyTotal).toFixed(2))
      .digits();

    //XP:
    item.find(".xp__total--history").text(xptotal).digits();
    historyXp += parseInt(
      item.find(".xp__total--history").text().replace(",", "")
    );
    item
      .closest("[data-id='order']")
      .find(".xp__total--order")
      .text(historyXp)
      .digits();
  });
  $("[data-id='order']").each(function () {
    var sum = 0;
    const item = $(this).find(".xp__total--order");
    sum += parseInt(item.text().replace(",", ""));
    $("#total_xp").text(sum).digits();
  });
  $("[data-id='order']").each(function () {
    var sum = 0;
    const item = $(this).find(".order__total");
    sum += parseInt(item.text().replace(",", ""));
    $("#total_grand").text(sum).digits();
  });
});
span {
  margin-right: 0.3rem;
}
.header {
  padding: 0.9rem 2.3rem;
  border: 3px solid blue;
}
.header__label {
  display: flex;
  width: 200px;
}
.header__label span {
  margin-left: auto;
}
.history__name {
  background: #fafafa;
  padding: 0.9rem 0;
}
[data-id="order"] {
  padding: 0.9rem 2.3rem;
  border: 2px solid;
  margin: 2.3rem 0
}
[data-id="history"] {
  margin: 1.3rem 0.9rem;
  padding: 0.9rem;
  border: 2px solid green;
}
[data-id="history"] > * {
  margin: 0.3rem 0;
}
.history__subtotal {
  border: 1px solid;
}
.order__header {
  background: #ececec;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="header">
  <div class="header__label">Grandtotal:<span id="total_grand">0</span> </div>
  <div class="header__label">XP:<span id="total_xp">0</span></div>
</div>
<div data-id='order'>
  <div class="order__header">
    <div class="header__label">Order Total: <span class="order__total">000</span></div>
    <div class="header__label">Order Fee: <span class="order__fee">000</span></div>
    <div class="header__label">Order XP: <span class="xp__total--order">000</span></div>
  </div>
  <div data-id='history'>
    <div class="history__name">Item 1 (10xp)</div>
    <div><span class="history__sold">25</span>Sold</div>
    <div><span class="history__cost">10</span>Cost</div>
    <div><span class="history__subtotal">000</span>Subtotal</div>
    <div>Fee:<span class="history__fee">0</span></div>
    <div><span class="xp__total--history">000</span>XP</div>
  </div>
  <div data-id='history'>
    <div class="history__name">Item 2 (10xp)</div>
    <div><span class="history__sold">10</span>Sold</div>
    <div><span class="history__cost">50</span>Cost</div>
    <div><span class="history__subtotal">000</span>Subtotal</div>
    <div>Fee:<span class="history__fee">0</span></div>
    <div><span class="xp__total--history">000</span>XP</div>
  </div>
</div>
<div data-id='order'>
  <div class="order__header">
    <div class="header__label">Order Total: <span class="order__total">000</span></div>
    <div class="header__label">Order Fee: <span class="order__fee">000</span></div>
    <div class="header__label">Order XP: <span class="xp__total--order">000</span></div>
  </div>
  <div data-id='history'>
    <div class="history__name">Item 1 (10xp)</div>
    <div><span class="history__sold">25</span>Sold</div>
    <div><span class="history__cost">10</span>Cost</div>
    <div><span class="history__subtotal">000</span>Subtotal</div>
    <div>Fee:<span class="history__fee">0</span></div>
    <div><span class="xp__total--history">000</span>XP</div>
  </div>
  <div data-id='history'>
    <div class="history__name">Item 2 (10xp)</div>
    <div><span class="history__sold">10</span>Sold</div>
    <div><span class="history__cost">50</span>Cost</div>
    <div><span class="history__subtotal">000</span>Subtotal</div>
    <div>Fee:<span class="history__fee">0</span></div>
    <div><span class="xp__total--history">000</span>XP</div>
  </div>
</div>

Upvotes: 0

Views: 44

Answers (1)

Alwaysa Learner
Alwaysa Learner

Reputation: 496

You need to run a nested .each loop if you want to show individual subtotals, as shown here....

 $.fn.digits = function () {
            return this.each(function () {
                $(this).text(
                    $(this)
                        .text()
                        .replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,")
                );
            });
        };
        $(document).ready(function () {


            $('[data-id="order"]').each(function () {
                var historyTotal = 0;
                var historyXp = 0;

                $(this).find('[data-id="history"]').each(function () {

                    const item = $(this);
                    var xp = 10;
                    var fee = 0.15;
                    var qty = item.find(".history__sold").text();
                    var price = item.find(".history__cost").text();
                    var subtotal = Number(qty) * Number(price);
                    var xptotal = Number(qty) * Number(xp);

                    var bonusXp = Number(
                        item.closest("[data-id='order']").find(".bonus__xp").text()
                    );

                    item.find(".history__subtotal").text(subtotal.toFixed(2)).digits();

                    item.find(".history__fee").text((subtotal * fee).toFixed(2)).digits();

                    historyTotal += subtotal;

                    /*
                    historyTotal += parseInt(
                        item.find(".history__subtotal").text().replace(",", "")
                    );*/

                    item.closest("[data-id='order']").find(".order__total").text(((1 + fee) * historyTotal).toFixed(2)).digits();

                    item.closest("[data-id='order']").find(".order__fee").text((fee * historyTotal).toFixed(2)).digits();

                    //XP:
                    item.find(".xp__total--history").text(xptotal).digits();

                    historyXp += parseInt(item.find(".xp__total--history").text().replace(",", ""));

                    item.closest("[data-id='order']").find(".xp__total--order").text(historyXp).digits();
                });




            });



            var sum = 0;
            $("[data-id='order']").each(function () {
                const item = $(this).find(".xp__total--order");
                sum += parseInt(item.text().replace(",", ""));
                $("#total_xp").text(sum).digits();
            });

            var sum = 0;
            $("[data-id='order']").each(function () {
                const item = $(this).find(".order__total");
                sum += parseFloat(item.text().replace(",", ""));
            });

            $("#total_grand").text(sum.toFixed(2)).digits();

        });
        span {
            margin-right: 0.3rem;
        }

        .header {
            padding: 0.9rem 2.3rem;
            border: 3px solid blue;
        }

        .header__label {
            display: flex;
            width: 200px;
        }

            .header__label span {
                margin-left: auto;
            }

        .history__name {
            background: #fafafa;
            padding: 0.9rem 0;
        }

        [data-id="order"] {
            padding: 0.9rem 2.3rem;
            border: 2px solid;
            margin: 2.3rem 0
        }

        [data-id="history"] {
            margin: 1.3rem 0.9rem;
            padding: 0.9rem;
            border: 2px solid green;
        }

            [data-id="history"] > * {
                margin: 0.3rem 0;
            }

        .history__subtotal {
            border: 1px solid;
        }

        .order__header {
            background: #ececec;
        }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="header">
        <div class="header__label">Grandtotal:<span id="total_grand">0</span> </div>
        <div class="header__label">XP:<span id="total_xp">0</span></div>
    </div>
    <div data-id='order'>
        <div class="order__header">
            <div class="header__label">Order Total: <span class="order__total">000</span></div>
            <div class="header__label">Order Fee: <span class="order__fee">000</span></div>
            <div class="header__label">Order XP: <span class="xp__total--order">000</span></div>
        </div>
        <div data-id='history'>
            <div class="history__name">Item 1 (10xp)</div>
            <div><span class="history__sold">25</span>Sold</div>
            <div><span class="history__cost">10</span>Cost</div>
            <div><span class="history__subtotal">000</span>Subtotal</div>
            <div>Fee:<span class="history__fee">0</span></div>
            <div><span class="xp__total--history">000</span>XP</div>
        </div>
        <div data-id='history'>
            <div class="history__name">Item 2 (10xp)</div>
            <div><span class="history__sold">10</span>Sold</div>
            <div><span class="history__cost">50</span>Cost</div>
            <div><span class="history__subtotal">000</span>Subtotal</div>
            <div>Fee:<span class="history__fee">0</span></div>
            <div><span class="xp__total--history">000</span>XP</div>
        </div>
    </div>

    <div data-id='order'>
        <div class="order__header">
            <div class="header__label">Order Total: <span class="order__total">000</span></div>
            <div class="header__label">Order Fee: <span class="order__fee">000</span></div>
            <div class="header__label">Order XP: <span class="xp__total--order">000</span></div>
        </div>
        <div data-id='history'>
            <div class="history__name">Item 1 (10xp)</div>
            <div><span class="history__sold">25</span>Sold</div>
            <div><span class="history__cost">10</span>Cost</div>
            <div><span class="history__subtotal">000</span>Subtotal</div>
            <div>Fee:<span class="history__fee">0</span></div>
            <div><span class="xp__total--history">000</span>XP</div>
        </div>
        <div data-id='history'>
            <div class="history__name">Item 2 (10xp)</div>
            <div><span class="history__sold">10</span>Sold</div>
            <div><span class="history__cost">50</span>Cost</div>
            <div><span class="history__subtotal">000</span>Subtotal</div>
            <div>Fee:<span class="history__fee">0</span></div>
            <div><span class="xp__total--history">000</span>XP</div>
        </div>
    </div>

Upvotes: 1

Related Questions