Only allow numbers and one dot with 2 decimal places restriction in keypress vuejs

Working example: https://jsfiddle.net/0s14cbqx/

In template:

<input placeholder="Name a price" v-model="price" @keypress="onlyForCurrency">

In js:

data(){
   return{
     price:null
   }
},
methods: {
   onlyForCurrency ($event) {
     // console.log($event.keyCode); //keyCodes value
     let keyCode = ($event.keyCode ? $event.keyCode : $event.which);

     // only allow number and one dot
     if ((keyCode < 48 || keyCode > 57) && (keyCode !== 46 || this.price.indexOf('.') != -1)) { // 46 is dot
      $event.preventDefault();
     }

     // restrict to 2 decimal places
     if(this.price!=null && this.price.indexOf(".")>-1 && (this.price.split('.')[1].length > 1)){
     $event.preventDefault();
     }
   }
}

In this way, users only can key in numbers and one dot and can't key in anything after 2 decimal places.


For input with type number, this is what we settled with:

<input type="number" v-model.number="price" @input="handleInput">
  data () {
    return {
      price: null,
      previousPrice: null
    }
  },

  methods: {
    handleInput (e) {
      let stringValue = e.target.value.toString()
      let regex = /^\d*(\.\d{1,2})?$/
      if(!stringValue.match(regex) && this.price!== '') {
        this.price = this.previousPrice
      }
      this.previousPrice = this.price
    }
  }

The idea is to check the user's input result. If it doesn't match the required regex pattern, then we reset the data back to its previous state using previousPrice. Demo: https://jsfiddle.net/edwardcahyadi/qj9mw5gk/2/


Using the autoNumeric Javascript library works very well.

There is a Vue.js component that wraps it: vue-autoNumeric.

Also, it works well with Vuetify's v-text-field, see https://codesandbox.io/s/yw07v978mj.