1

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/vue@2.6.12/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

AndreasInfo
  • 1,062
  • 11
  • 26
  • Where do you perform the validation? Our are you relying on the browser to do that? Else, look into Vee-validate or vuelidate – Maarten Veerman Nov 21 '20 at 17:58
  • I updated the question. I'd like to validate it in the component and then send it to the parent via custom event. I hope my problem gets clearer. Point is, budget is going to be "" on both invalid input and empty input. – AndreasInfo Nov 21 '20 at 18:19

2 Answers2

0

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'.

Raeisi
  • 1,647
  • 1
  • 6
  • 18
  • This all was not satisfying because did not prevent entering leading zeros (even though they got cut because of v-model.number does parseFloat() to it). Anyway I wanted the input to be strictly robust so I end up doing a custom check you can see in my solution. – AndreasInfo Nov 27 '20 at 16:34
0

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>
AndreasInfo
  • 1,062
  • 11
  • 26