3

From the MDN documentation about <input type="number">:

They include built-in validation to reject non-numerical entries.

Does it mean "reject when try to submit the HTML form"? I inputted "4e4--23". HTML has not rejected it.

enter image description here

Therefore, <input type="number"> can not prevent the inputting of non-number value. I don't care about I it if I can programically correct user's input. For example, user inputted the minus sign not in the first position - using JavaScript, theoretically I can remove it.

However here is unobvious JavaScript behavior: when input element has "number" attribute and value is invalid number, Element.value returns an empty string. It's very tricky programmatic validation: because we have empty string value, the validator will return "The input must not be empty. Please input the value." error while input in not empty!

document.getElementById("target").addEventListener("input", blackbox => {
 console.log(document.getElementById("target").value);
});
<input type="number" value="" id="target">

How can I get the actual inputted value? (If you know Vue, please add the solution for Vue, too.)

Takeshi Tokugawa YD
  • 670
  • 5
  • 40
  • 124
  • can u check with
    tag?
    – Antony Sep 03 '20 at 06:46
  • @Antony Thank you for the response. My answer: generally - no. I will not wrap every my component to `form`. – Takeshi Tokugawa YD Sep 03 '20 at 06:49
  • You can use the `.checkValidity()` to know if the value is correct, or else, use an input type text, and filter his `value` to match numbers. – Thibault Husté Sep 03 '20 at 06:51
  • https://stackoverflow.com/questions/31706611/why-does-the-html-input-with-type-number-allow-the-letter-e-to-be-entered-in – Antony Sep 03 '20 at 06:56
  • 1
    I don't think browsers validate on input, only when submitting. So a user can put anything in the input field, including complete words. If you need checking on input, you'll have to write your own script. – Michel Sep 03 '20 at 06:59

3 Answers3

5

try this:

I only accept numbers:
<input type="text" v-model="form.availability" oninput="this.value = this.value.replace(/[^0-9]/g, '');">
<br>
I only accept numbers inlcuding a point:
<input type="text" v-model="form.availability" oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1');">
<br>
EDIT: I accept negative numbers inlcuding a point:
<input type="text" v-model="form.availability" oninput="this.value = this.value.replace(/[^0-9.-]/g, '').replace(/(\..*)\./g, '$1');">
<br>
EDIT: I accept negative numbers inlcuding a point:
<input type="text" v-model="form.availability" oninput="this.value = this.value.replace(/[^0-9.-]/g, '').replace(/(\..*)\./g, '$1').replace(/(\..*)\./g, '$1');">
<br>
EDIT2: I accept negative numbers inlcuding a point (only one "minus" sign):
<input type="text" v-model="form.availability" oninput="this.value = this.value.replace(/[^0-9.-]/g, '').replace(/(\..*)\./g, '$1').replace(/(\..*)\./g, '$1').replace(/(\-.*)\-/g, '$1');">
<br>
EDIT3: I also accept "e" and "E"
<input type="text" v-model="form.availability" oninput="this.value = this.value.replace(/[^0-9\.\-\e\E]/g, '').replace(/(\..*)\./g, '$1').replace(/(\..*)\./g, '$1').replace(/(\-.*)\-/g, '$1').replace(/(\e.*)\e/g, '$1').replace(/(\E.*)\E/g, '$1');">
<br>

Different browsers treat the "input type number" differently

0

Try <input type="number" inputmode="numeric"> or <input type="tel" inputmode="numeric">

  • 1
    `inputmode="numeric"` is not supported by Safari and only after explicitly been enabled in Firefox. – Michel Sep 03 '20 at 07:04
  • Thank you for the answer. I am sorry, but looks like it does not work even in chrome. I inputted your solution to [JSFiddle](https://jsfiddle.net/96qby0rk/1/). Please try to input something like `4-6-5--` - it will not be prevented. – Takeshi Tokugawa YD Sep 03 '20 at 07:21
  • that's because the minus character is allowed in numbers. Admittedly, it should appear only once, but you should be liberal about user input editing before eventually validating the input, either on submit or perhaps when the input loses focus, rather than micromanaging every keystroke – brennanyoung Sep 09 '20 at 10:13
0

There is workaround in Vue.js. You can use $event.target which has more details. It contains object 'validity' whose properties 'badInput' tells us if value is not correct.

See example bellow, for wrong value like 'e23', '--1' we will get 'NaN' which can be use in validation rules.

Vue.component('input-element', {
    template: ' <input :type="type" :value="inputValue" @input="onInput($event.target)" />',
    props: {
        type: String,
        value: String | Number | Boolean
    },
    computed: {
        inputValue: {
            get() {
                if (this.type == 'number') {
                    return !isNaN(this.value) ? this.value : '';
                }

                return this.value;
            }
        }
    },
    methods: {
        onInput(eventTarget) {
            let value = eventTarget.value;

            if (this.type == 'number' && eventTarget.validity?.badInput) {
                value = eventTarget.valueAsNumber;
            }

            this.$emit('input', value);
        }
    }
});

new Vue({
    el: "#app",
    data: {
        numberValue: 0
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <input-element type="number" v-model="numberValue"></input-element> 
  <div>{{ numberValue }}</div>
</div>

                   
Michal
  • 11
  • 1