17

Is there a way to block users from writing specific characters in input fields? I tried the code below, but when a user enters disallowed characters, they appear for a brief period before disappearing. I want the input to remain unchanged when invalid characters are written.

I want to use onchange because other restriction methods do not seem to work on mobile devices. The problem I want to solve is that characters appear briefly before being removed.

function checkInput(ob) {
  const invalidChars = /[^0-9]/gi;

  if(invalidChars.test(ob.value)) {
    ob.value = ob.value.replace(invalidChars, "");
  }
};
<input class="input" maxlength="1" onChange="checkInput(this)" onKeyup="checkInput(this)" type="text" autocomplete="off" />
FWDekker
  • 1,823
  • 2
  • 20
  • 26
user3459377
  • 241
  • 1
  • 2
  • 9

7 Answers7

14

you can use try this,

$('.input').keyup(function () {
    if (!this.value.match(/[0-9]/)) {
        this.value = this.value.replace(/[^0-9]/g, '');
    }
});

SEE THIS FIDDLE DEMO

Updated :

You can try this Code,

$(document).ready(function() {
    $(".input").keydown(function (e) {
        // Allow: backspace, delete, tab, escape and enter
        if ($.inArray(e.keyCode, [46, 8, 9, 27, 13, 110]) !== -1 ||
             // Allow: Ctrl+A
            (e.keyCode == 65 && e.ctrlKey === true) || 
             // Allow: home, end, left, right
            (e.keyCode >= 35 && e.keyCode <= 39)) {
                 // let it happen, don't do anything
                 return;
        }
        // Ensure that it is a number and stop the keypress
        if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
            e.preventDefault();
        }
    });
});

SOURCE

SEE UPDATED FIDDLE DEMO

UPDATED FOR ANDROID:

<EditText
android:id="@+id/editText1"
android:inputType="number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textView1"
android:layout_marginTop="58dp"
android:layout_toRightOf="@+id/textView1"
android:maxLength="1" >
</EditText>

I think it may help you... using android:inputType="number" you can do that.

Community
  • 1
  • 1
CJ Ramki
  • 2,620
  • 3
  • 25
  • 47
9

A combination of keypress and paste events does a trick:

var text = document.getElementById('text');
text.onkeypress = text.onpaste = checkInput;

function checkInput(e) {
    var e = e || event;
    var char = e.type == 'keypress' 
        ? String.fromCharCode(e.keyCode || e.which) 
        : (e.clipboardData || window.clipboardData).getData('Text');
    if (/[^\d]/gi.test(char)) {
        return false;
    }
}
<input class="input" maxlength="10" id="text" type="text" autocomplete="off" />

This code prevents from typing or pasting anything but a number. Also no blinking and invalid characters don't show up.

Works in IE7+.

Demo: http://jsfiddle.net/VgtTc/3/

dfsq
  • 191,768
  • 25
  • 236
  • 258
  • 1
    This code does not work with drag&drop, `e.keyCode` and `e.which` are deprecated, and `return false` should probably be `e.preventDefault()`. I think the modern approach is to [handle the `beforeinput` event to reject invalid inputs in a generic way](https://stackoverflow.com/a/74549391/). – FWDekker Nov 23 '22 at 15:45
8

All answers given so far suffer from at least one of the following accessibility issues:

  1. They validate key codes, which does not work with non-QWERTY keyboard layouts.
  2. They do not cover all input methods; especially drag&drop is often forgotten.
  3. They alter the value, which resets the position of the caret.
  4. They use the pattern attribute, but this does not provide feedback until the form is submitted.

Wouldn't it be a much better idea to actually validate the input before it's inserted?


The beforeinput event fires before the input's value is changed. The event has a data property which describes the content that the user wants to add to the input field. In the event handler, you simply check the data attribute, and stop the event chain if it contains disallowed characters.

We end up with the following very simple, very short code.

const input = document.getElementById("input");
const regex = new RegExp("^[0-9]*$");

input.addEventListener("beforeinput", (event) => {
  if (event.data != null && !regex.test(event.data)) 
    event.preventDefault();
});
<label for="input">Enter some digits:</label>
<input id="input" />

Some closing notes:

  • Accessibility: Provide a clear explanation of what input format is expected from the user. For example, you can use the title attribute of the input to show a tooltip explaining the expected format.
  • Security: This is client-side validation, and does not guarantee that the pattern is enforced when the form is sent to a server. For that, you'll need server-side validation.
FWDekker
  • 1,823
  • 2
  • 20
  • 26
  • 2
    This should be the accepted answer. It doesn't rely on any hacks and correctly intercepts the potential value before it actually changes in the `` element. It also shows how you can use a variable or other object attribute to control the regex of allowed characters. – E-Riz May 23 '23 at 13:25
2

Here's a little hack you could try: DEMO

What it does is that it colors every input text white and then changes it back to black if it suits your requirements. If you could live with the bit of lag that occurs when you enter a valid character.

function checkInput(ob) {
    var invalidChars = /[^0-9]/gi
    if (invalidChars.test(ob.value)) {
        ob.value = ob.value.replace(invalidChars, "");
    }
    else {
        document.getElementById('yourinput').style.color = '#000';
    }
};

function hideInput(ob) {
    document.getElementById('yourinput').style.color = '#FFF';
};

html

<input id="yourinput" class="input" maxlength="1" onKeydown="hideInput(this)" onKeyup="checkInput(this)" type="text" autocomplete="off" />

css

input {color:#FFF;}
Niklas
  • 13,005
  • 23
  • 79
  • 119
  • Aint any way of doing that without useing css? Its just a delay when you press restricted characters that i dont want to be displayed at all – user3459377 Mar 28 '14 at 09:32
  • Ur answer is good,as you said its a little hack but i still wonder how can i use this code without delay – user3459377 Mar 28 '14 at 09:32
  • 1
    Yeah, I'm trying some other things but I can't seem to get rid of the lag. – Niklas Mar 28 '14 at 09:43
1

check this code,

$('.input').keypress(function(e) {
    var a = [];
    var k = e.which;

    for (i = 48; i < 58; i++)
        a.push(i);

    if (!(a.indexOf(k)>=0))
        e.preventDefault();
});

CJ Ramki
  • 2,620
  • 3
  • 25
  • 47
Ashwani Panwar
  • 3,819
  • 3
  • 46
  • 66
1
<input id="testInput"></input>

<script>
testInput.onchange = testInput.oninput = restrict;

function restrict() {
    testInput.value = testInput.value.replace(/[^a-z]/g, "");
}
</script>

I came up with something slightly different. oninput instead of onkeyup/onkeydown, and onchange instead of onpaste.

Nick Bilyk
  • 352
  • 2
  • 8
  • 1
    Note that this resets the caret every time an invalid input is entered, which is annoying for the user if they want to edit the start of the input and press the wrong key. [You can use the `beforeinput` event to reject invalid inputs before they're even inserted.](https://stackoverflow.com/a/74549391) – FWDekker Nov 23 '22 at 15:47
0

I restrict invalid characters on both keypress and paste events like:

<input type="text" onkeydown="validateKey(event)" onpaste="validatePaste(this, event)">  

And define functions to handle these events inside tab or a separate javascript file:

<script>
function validateKey(e) {
  switch(e.keyCode) {
    case 8,9,13,37,39:
      break;
    default:
      var regex = /[a-z .'-]/gi;
      var key = e.key;
      if(!regex.test(key)) {
        e.preventDefault();
        return false;
      }
      break;
  }
}
function validatePaste(el, e) {
  var regex = /^[a-z .'-]+$/gi;
  var key = e.clipboardData.getData('text')
  if (!regex.test(key)) {
    e.preventDefault();
    return false;
  }
}
</script>
pixel
  • 9,653
  • 16
  • 82
  • 149