Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue.js: Only allow numbers in range with one decimal

I'm having a problem when trying to allow only numbers (it could be with one dot and one decimal) and numbers must be between 0 and 10. Examples:

  • 2 -> allowed
  • 8.5 -> allowed
  • 7.14 -> not allowed
  • 7.1 -> allowed
  • 10.1 -> not allowed
  • 10 -> allowed
  • 15.2 -> not allowed

First of all, here is a piece of code:

HTML:

<b-form-input
  v-model="userDto.score"
  @keypress="restrictScoreValue"
  type="number"
  min=0
  max=10
/>

JavaScript:

restrictScoreValue($event) {
  const keyCode = ($event.keyCode ? $event.keyCode : $event.which)

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

  // restrict to 1 decimal place
  if (this.userDto.score !== null && this.userDto.score.indexOf('.') > -1 && (this.userDto.score.split('.')[1].length > 0)) {
    $event.preventDefault()
  }
}

It works allowing only numbers and one decimal after the dot. But it doesn't work allowing only numbers between 0 and 10 (I can input a lot of numbers before the dot), and if I paste an incorrect score (example: 15.43) it allows.

How can I improve the code to fit the requirements?

like image 956
Mike Jensens Avatar asked Oct 16 '25 21:10

Mike Jensens


1 Answers

I came up with this solution. Using :formatter solves your issue with the reactivity of b-form-input, and so there is no need to remove it. I have a configurable validation variable that you can configure and adjust your validation to set the max, min, and decimal values.

new Vue({
  el: "#app",
  data: function() {
    return {
      value: 0,
      last_value: 0,
      validation: {
        min: 0,
        max: 10,
        decimal: 10
      }
    }
  },
  methods: {
    format_number(e) {
      if (e > this.validation.max) {
        return this.validation.max
      } else if (e < this.validation.min) {
        return this.validation.min
      } else if (Math.round(e * this.validation.decimal) / this.validation.decimal != e) {
        return this.last_value
      } else {
        this.last_value = e
        return e
      }
    }
  }
});
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script>

<div id="app">
  <b-form-input type="number" :step="0.1" v-model="value" :formatter="format_number" />
</div>
like image 92
Iman Shafiei Avatar answered Oct 19 '25 12:10

Iman Shafiei