chipit24
chipit24

Reputation: 6987

How to prevent Vue input from setting value?

I have the following Vue code:

// HTML
<div id="app">
  Value: <pre>{{ value }}</pre>
  <input type="text" :value="value" @input="setValue">
</div>

// JS
new Vue({
  el: "#app",
  data: {
    value: '',
  },
  methods: {
    setValue(event){
      /* Remove non-numeric values */
        this.value = event.target.value.replace(/[^\d]/g, '');
    }
  }
});

I have it set up on JSFiddle here: http://jsfiddle.net/eywraw8t/353729/.

Why does the input allow me to enter non-numeric values?

If you run the code above, and enter non-numeric gibberish into the input element (e.g. asdasfa), you'll see that the input element will contain your entered text (asdasfa), but the element above the input will be empty!

I would like to restrict users to only being allowed to enter numbers into the input. I would like to do this using only Vue, no 3rd party libraries or type="number".

Upvotes: 2

Views: 6051

Answers (2)

Phil
Phil

Reputation: 164795

The issue is Vue doesn't see a change to your value data property because when you filter out non-numbers, you are essentially assigning the same string value back to it. Since strings are immutable and identical when their contents are the same, this doesn't trigger Vue's reactivity.

An easy solution is to manually set the <input> value to the new, number-only value.

this.value = event.target.value = event.target.value.replace(/\D/g, '')

http://jsfiddle.net/9o2tu3b0/

Upvotes: 1

Sphinx
Sphinx

Reputation: 10729

because the value of this.value doesn't change (always ='') so it will not trigger re-render.

The solution:

you can use this.$forceUpdate() to force re-render.

or use bind key with different value.

new Vue({
  el: "#app",
  data: {
    value: '',
    errorDescription: ''
  },
  methods: {
  	setValue(event){
      /* Remove non-numeric values */
    	this.value = event.target.value.replace(/[^\d]/g, '')
      this.errorDescription = 'Only Number allow'
      this.$forceUpdate()
    }
  }
})
.error {
  background-color:red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
  Value: <pre>{{ value }}</pre><span class="error">{{errorDescription}}</span>
  <input type="text" :value="value" @input="setValue">
</div>

Upvotes: 3

Related Questions