Morteza Negahi
Morteza Negahi

Reputation: 3493

Can Vue.js add commas while user typing numbers?

I see this topic, But this is Jquery, how can I change it to Vue.js ? Is v-on supported in Vue.js? Where is my mistake?

<div id="vue">
    <input v-model="amountModel" v-on:keyup="AddCammas()" value="{{price}}">
</div>

<script>
   el: #vue,
   methods:{
      AddCammas : funtion(){
          if(event.which >= 37 && event.which <= 40) return;

          $(this).val(function(index, value) {
             this.message = this.amountModel
                .replace(/\D/g, "")
                .replace(/\B(?=(\d{3})+(?!\d))/g, ",");
           });
      } 
   }   
</script>

Upvotes: 7

Views: 29991

Answers (6)

JosselinTD
JosselinTD

Reputation: 621

If you want to use your method, you can make your AddCommas method like this :

AddCommas: function(event) {
  event.target.value = event.target.value.replace(",", ".");
}

There is a little thing to know about event listener in VueJS. You can access the event object in the handler, but for this, you need either to use this syntax v-on:keyup="AddCommas" (no parentheses), or this syntax v-on:keyup="AddCommas($event)" (useful when you have multiple parameters)

Upvotes: 1

younesfmgtc
younesfmgtc

Reputation: 19

<template>
  <div class="form-group">
    <label :class="{required:$attrs.required}">{{ label }}</label>
    <input v-model="model" class="form-control" :class="{invalid : error}" type="text" pattern="\d+((\.|,)\d+)?"
           v-bind="$attrs">
    <div v-if="error" class="invalid-tooltip">{{ error[0] }}</div>
  </div>
</template>

<script>
export default {
  name: "InputNumber",
  emits: ['update:modelValue'],
  inheritAttrs: false,
  props: {modelValue: '', error: '', label: ''},
  computed: {
    model: {
      get() {
        // return this.modelValue ? this.modelValue.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,") : this.modelValue
        return this.modelValue ? this.modelValue.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") : this.modelValue
      },
      set(value) {
        this.$emit('update:modelValue', Number(value.replaceAll(',','')))
      }
    },
  }
}
</script>

Upvotes: 0

Mahmoud.Ismail
Mahmoud.Ismail

Reputation: 67

I used Inputmask with vanilla, for vue 2, and it works perfectly. Inputmask

    <script src="../src/assets/js/libs/jquery-inputmask/inputmask.min.js"></script>
  <script src="../src/assets/js/libs/jquery-nputmask/bindings/inputmask.binding.js">

<script>
  $(document).ready(function () {
    var selector = document.getElementById("txtOrderQty");
    var im = new Inputmask({ alias: "currency", digits: 0, allowMinus: false }
    im.mask(selector);
</script>

Upvotes: 0

Syed
Syed

Reputation: 16543

To people who are looking for doing mask for multiple fields then it's kinda pain to use watch, so may be we can use v-money (docs included). And check the demo here.

Upvotes: 4

Jonathan Lee
Jonathan Lee

Reputation: 1432

If you are using Vuetify, a new light-weight library called 'vuetify-money' has been published. Super easy to use for money value inputs, it is a text field that will add commas as you type. Here's a demo.

All properties you use on a v-text-field can also be used, so it is easily customizable.

Step 1

npm install vuetify-money --save

Step 2

Create a src/plugins/vuetify-money.js file with the following content:

import Vue from "vue";
import VuetifyMoney from "vuetify-money";
Vue.use(VuetifyMoney);
export default VuetifyMoney;

Step 3

Add file to src/main.js :

import "./plugins/vuetify-money.js";

(main.js is the file where you usually put this)

new Vue({render: h => h(App)
}).$mount('#app');

Step 4 Use it in your code !

<template>
  <div>
    <vuetify-money
      v-model="value"
      v-bind:options="options"
    />
    Parent v-model: {{ value }}
  </div>
</template>
<script>
export default {
  data: () => ({
    value: "1234567.89",
    options: {
      locale: "ja-JP",
      prefix: "$",
      suffix: "",
      length: 10,
      precision: 2
    }
  })
};
</script>

You now have a text field that will add commas as you type while keeping the v-model values perfectly fine. It also prevents any non-number inputs so you hardly need front-end validation checks excluding customized cases.

Upvotes: 2

Roy J
Roy J

Reputation: 43899

You don't need jQuery at all for this. You watch your variable, and in the watch function, compute the reformatted version, then set it back to your variable using nextTick (so it's not mutating before the watch is complete).

new Vue({
  el: '#vue',
  data: {
    price: 0
  },
  watch: {
    price: function(newValue) {
      const result = newValue.replace(/\D/g, "")
        .replace(/\B(?=(\d{3})+(?!\d))/g, ",");
      Vue.nextTick(() => this.price = result);
    }
  }
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/1.0.28/vue.min.js"></script>
<div id="vue">
  <input type="text" v-model="price" />{{price}}
</div>

Upvotes: 24

Related Questions