ImranR
ImranR

Reputation: 516

How can I prevent other characters from being inputted on an input except numbers using Javascript

I am using Vue.JS (Bootstrap-Vue) to build a form, my input has the following code:

<b-form-input
            v-mask="'####'"
            number
            type="number"
            no-wheel
            pattern="[0-9]"
            step="1"
            :class="{ 'hasError': $v.form.dobYear.$error }"
            v-model.number="$v.form.dobYear.$model"
            class="form-input"
            name="year"
            id="year"
            maxlength="4"
            min="1900"
            max="2020"
            @keydown="filterKey"
          ></b-form-input>

When a user presses down I want to prevent more than 4 characters to be entered, this works, but when testing, I can see period and dashes and other similar characters can also be added into the input and ignores the maximum of 4 characters. How can I update the following code to ensure nothing but numbers can be added to my input on mobile. I'm trying to detect if any of those unwanted keys are pressed then prevent the default action. (I've tested on Android Chrome)

filterKey(e) {
      const value = e.target.value;
      const key = e.key;
      console.log(value, this.amount);
      if (String(value).length === 4) {
        //check if a number is pressed after 4 have been entered
        if (!isNaN(Number(key))) {
          e.preventDefault();
          return;
        } else if (key == 190 || key == 189 || key == 107 || key == 69) {
          e.preventDefault();
          return;
        }
      }
    }

Upvotes: 0

Views: 3652

Answers (3)

Harshit Vadodaria
Harshit Vadodaria

Reputation: 76

The following snippet will not allow anything to be entered into the input element if the length of the input's value is already 4, or if a non-numeric character is typed (but will allow 'Backspace' and 'Delete' keys):

EDIT : Implemented Hiws' suggestion to let the user type in numbers even if the length is 4, if some text is selected in the input element

function filterKey(e) {
    let previousValue = e.target.value;
    let key = e.keyCode || e.charCode;
    if (key != 8 && key != 46) { // Ignore backspace and delete
        if (
            // preventDefault if length of input is 4 and no text is selected in the input
            ( String(e.target.value).length >= 4 && e.target.selectionStart === e.target.selectionEnd ) ||
            // preventDefault if entered a space or non-number
            !e.key.trim() || isNaN(e.key)
            ) {
            // Prevent input if input length crosses 4,
            // or if input is not a number
            e.preventDefault();
            // Include below line only if you have no other event listeners on the element, or its parents
            e.stopImmediatePropagation();
            return;
        }
    }

}

Upvotes: 2

Haibrayn Gonz&#225;lez
Haibrayn Gonz&#225;lez

Reputation: 181

You can use a regex to test against the value of the input field and avoid messing with keyCodes.

if ( !/^[0-9]{0,4}$/.test(String(value)) ) {
    e.preventDefault();
    return;
}

Upvotes: 0

winiar
winiar

Reputation: 174

You block keys other than numbers only if number value already equals to 4. Try changing your blocking logic to:

if (String(value).length > 4 || !isNaN(Number(key)) || unwanted keyCodes) {
   e.preventDefault();
   return;

Upvotes: 1

Related Questions