Search code examples
javascriptknockout.jsmagento2

Magento 2 Minicart / Knockout.js: Format calculated price / sum


In Magento 2 minicart (CE 2.4.6) I do not only want to show the price of each item in cart, but also the SUM of each item (if there is more than one unit of the same item in cart). I have therefore added the following line into minicart/item/default.html:

<span class="price" data-bind="text: (item.qty * item.product_price_value)"></span>

Output is the following format: 89.6999999999999

I would need European format with comma separator and two decimals. So I tried:

<span class="price" data-bind="text: (item.qty * item.product_price_value).toFixed(2)."></span>

This works for the decimals: 89.70

Then I tried:

<span class="price" data-bind="text: (item.qty * item.product_price_value).toLocaleString('de-DE')"></span>

This works for the comma: 89,6999999999999

However, I could not find a way to achieve both comma and number of decimals.

<span class="price" data-bind="text: (item.qty * item.product_price_value).toFixed(2).toLocaleString('de-DE')"></span>

This again shows only the correct decimals, but wrong separator.

Can anyone help? Thanks!


Solution

  • I suggest to move formatting of amount to application viewmodel. This will allow you to modify it more flexible. Then you could easily unit test it or adjust to use different cultures and rounding. If you can't update viewmodel that call external function simpleNumberFormat

    class AppViewModel {
        constructor() {
            this.qty = 12;
            this.product_price_value = 23.7343999;
        }
    
        amountFmt() {
            const rounded = (this.qty * this.product_price_value).toFixed(2);
            return  Number(rounded).toLocaleString("de");
        }
    }
    
    function simpleNumberFormat(amount) {
      return  Number(amount.toFixed(2)).toLocaleString("de", {minimumFractionDigits: 2});
    }
    
    ko.applyBindings(new AppViewModel());
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
    <div>
      Amount: <span data-bind="text: qty * product_price_value"></span><br />
      Amount formatted: <span data-bind="text: amountFmt()"></span><br />
      Amount external: <span data-bind="text: simpleNumberFormat(qty * product_price_value)"></span><br />
      Ending: <span data-bind="text: simpleNumberFormat(201)"></span><br />
        </div>