hendry
hendry

Reputation: 10823

Converting monetary amount to cents in VueJS?

I want to be able to safely take monetary values, that look like 5 or 5.12 dollars and convert them to cents, like 500 and 512 respectively.

new Vue({
  el: "#app",
  data: {
    price: 5.1
  },
  computed: {
    amount() {
      return (this.price * 100);
    }
  },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">

  <label>Total amount (formatted)<br>
<input v-model="price"></label>
  </label>

  <p>

    <label>Total amount (cents) {{ amount }}<br>
<input v-model.number="amount" name="amount" required type="number"></label>
</div>

I've noticed that values like "5.10" can makes it not convert to cents cleanly.

I also want to avoid people entering values like 5.1 and 5.12345, since they are not really monetary. Cents should be double digits right?

Any tips to avoid costly mistakes here please?

Upvotes: 1

Views: 366

Answers (2)

hgb123
hgb123

Reputation: 14891

First, you could use Math.round to round the cent to the nearest integer

Moreover, to detect entering value over 2 decimal place, watch that value and check

new Vue({
  el: "#app",
  data: {
    price: 5.1
  },
  computed: {
    amount() {
      return Math.round(this.price * 100);
    }
  },
  watch: {
    price(newPrice, oldPrice) {
      if (String(newPrice).split('.')[1]?.length > 2) {
        alert('Should not input number over 2 decimal places')
        this.price = oldPrice
      }
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">

  <label>Total amount (formatted)<br>
<input v-model="price"></label>
  </label>

  <p>

    <label>Total amount (cents) {{ amount }}<br>
<input v-model.number="amount" name="amount" required type="number"></label>
</div>

Upvotes: 1

Alan Omar
Alan Omar

Reputation: 4217

you can use Number.toFixed specifying 2 the number of digits after the decimal point. this will return a string then you can convert it back again to number using Number.parseFloat

new Vue({
  el: "#app",
  data: {
    price: 5.1
  },
  computed: {
    amount() {
      return Number.parseFloat((this.price * 100).toFixed(2));
    }
  },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">

  <label>Total amount (formatted)<br>
<input v-model="price"></label>
  </label>

  <p>

    <label>Total amount (cents) {{ amount }}<br>
<input v-model.number="amount" name="amount" required type="number"></label>
</div>

Upvotes: 0

Related Questions