Reputation: 68650
let el = document.querySelector('#input');
el.onkeyup = function(e) {
if (e.target.willValidate && !e.target.validity.valid) {
// invalid
e.preventDefault();
}
};
el.oninput = function(e) {
result.innerHTML = e.target.value;
};
<input type="number" min="0" max="10" id="input">
<span id="result"></span>
So if I type or paste an invalid value eg 11
, the result
doesn't update. How do I ensure the input just ignores invalid input and/or reverts to the last valid value?
Upvotes: 0
Views: 1751
Reputation: 370679
You can save a reference to the last valid value, and insert it when something invalid is put in:
let el = document.querySelector('#input');
let lastVal;
el.oninput = function(e) {
if (this.willValidate && !this.validity.valid) {
this.value = lastVal;
} else {
lastVal = el.value;
result.innerHTML = e.target.value;
}
};
<input type="number" min="0" max="10" id="input">
<span id="result"></span>
It could also be done by intercepting all methods which result in input changes, figuring out what the new value would be by checking the selection index and what the newly added values would be (and possibly deleting old sections of text, if they were selected), and then using preventDefault
to prevent the invalid text from being inputted at all, but that would be a whole lot more complicated for basically the same result.
An example snippet in Vue using the same method:
var app = new Vue({
el: '#app',
data: {
val: '',
oldVal: ''
},
watch: {
val(newVal) {
if (!(newVal >= 1 && newVal <= 10)) {
this.val = this.oldVal;
} else {
this.oldVal = newVal;
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<input v-model="val">
<span>{{ val }}</span>
</div>
Upvotes: 1
Reputation: 468
Here is a workaround using onpaste
event. But it takes the min
and max
value and then try to validate against the value manually. But it will prevent the input value from being changed if wrong values is pasted.
let el = document.querySelector('#input');
el.onpaste = function(e){
var pastedVal = (e.originalEvent || e).clipboardData.getData('text/plain');
if(pastedVal < parseInt(el.getAttribute("min")) || pastedVal > parseInt(el.getAttribute("max"))){
e.preventDefault();
}
};
<input type="number" min="0" max="10" id="input">
<span id="result"></span>
Upvotes: 2