vue.js v-model on input can not differentiate between empty input and invalid input

1.9k Views Asked by At

I am trying to validate some input data (e.g. number) on an input-tag connected to some data via v-model.

The problem is, if I have invalid data (e.g. "1e"), the data will be "". Same goes obviously for empty input.

How can I differentiates empty input or invalid input?

var app = new Vue({
  el: "#app",
  data: {
    budget: "",
  },
  methods: {
    updateBudget() {
      // do some input validation here. E.g.
      if (this.budget === "") {
        console.log("This is triggered on both:");
        console.log("(1) empty input -> budget = ''");
        console.log("(2) invalid input, e.g. -> budget = '1e'");
        console.log("Problem: I can't split this in the above cases!");
      };
    },
  },
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>

<div id="app">
  <input v-model="budget" type="number" placeholder="Budget" min="0" step="0.01" @input="updateBudget" />
</div>

I'd appreciate a hint. Thanks

2

There are 2 best solutions below

0
On BEST ANSWER

I did a custom solution based on some regex. Something like:

<template>
  <div id="app">
    <input v-model="budget" type="text" @input="validateAndUpdateInput" />
  </div>
</template>

<script>
[...]
methods: {
    validateAndUpdateInput: function() {
      if (!/^-?([0]?|[1-9]{1}\d{0,15})([.]{1}\d{0,2})?$/.test(this.budget)) {
        this.budget = this.previousInput;
        //alert("not valid");
      } else {
        this.previousInput = this.budget;
        this.$emit("update-input", this.budget);
      }
    },
[...]
</script>
1
On

1e is not a number (also +, -). The output is empty as it's not a valid number, try to insert 1e0 or -1, you'll be able to catch the value. There are some related issues:

To catch the exact number without worry about 'e' use the internal Vue implementation. It takes care of such situations. (v-model.number)

<input
    v-model.number="budget"
    type="number"
    placeholder="Budget"
    min="0"
    step="0.01"
    @input="updateBudget"
/>

By the way, if you want to check 'e' explicitly, I think, it's better to use 'type=text'.