40

Is it possible to restrict the input of certain characters in HTML5/JavaScript? For example, could I have an input textbox on the screen and if the user tries to type a letter in it, it wouldn't show up in the box because I've restricted it to only numbers?

I know you can use a pattern which will be checked on submit, but I want the "bad" characters to just never be entered at all.

2
  • I'm not sure how you could completely restrict them, but maybe you could add an event on keyup (or keydown even) to check the field's value and remove non-number characters? Commented Nov 28, 2012 at 14:30
  • Can you explain what you mean by Bad Chars? The solutions given below are straight methods to define what char are acceptable. For Bad char, you may need a list or array to hold the values and run a function() to vaidate the inputs. Commented Feb 17 at 1:16

12 Answers 12

15

The input textbox

<input type="text" onKeyDown="myFunction()" value="" />

JavaScript

function myFunction() {
    var e = event || window.event;  // get event object
    var key = e.keyCode || e.which; // get key cross-browser

    if (key < 48 || key > 57) { //if it is not a number ascii code
        //Prevent default action, which is inserting character
        if (e.preventDefault) e.preventDefault(); //normal browsers
        e.returnValue = false; //IE
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

this also blocks any control keys!
KeyboardEvent.keyCode is deprecated now. Instead, you can use the element.input event and a regex replace. See my answer below.
13

Use html5 pattern attribute for inputs:

<input type="text" pattern="\d*" title="Only digits" />

OR

Use html5 number type for input :

<input type="number" />

5 Comments

Just a note, according to html5pattern.com pattern is only this is only supported by "Firefox 4b7 & Chrome 6 & Opera 9 & Safari 5.0.3" and up.
This allows you to enter anything but then when you submit it tells you it's wrong. Not what I'm looking for.
The problem with discarding invalid characters as you type is that users may think their keyboard is broken. It might be better to wait until they submit the input to validate it and then reject it/give a message. Maybe there's something available to reject a key immediately with a persistent message that stays visible until several good characters have been entered?
like the poster, I want to restrict input to only numbers. Not too concerned if a user entering a telephone number thinks his keyboard is broken because a letter doesn't appear. Bad to assume, but I'm assuming my users know that telephone numbers are made up of numbers.
7

To slightly improve off of jonhopkins excellent answer, I added backspace and delete key acceptance like so:

    function inputValidate(){
   var e = event || window.event;  
   var key = e.keyCode || e.which;                              
   if (((key>=48)&&(key<=57))||(key==8)||(key == 46)) { //allow backspace //and delete
           if (e.preventDefault) e.preventDefault(); 
           e.returnValue = false; 
   }
 }

3 Comments

This should probably include 37 (left-arrow) and 39 (right-arrow) so that the user can move between characters and shift-select the text.
Hmm yeah at that point (2+) I'd say just create an array of allowed characters to check against.
also there is a ! missing, that IF is actually checking for the allowed keys and prevent the numbers to be typed
7

For Restricting Characters symbols like '-' and ','

<input type="text" pattern="[^-,]+">

for restricting numbers

<input type="text" pattern="[^0-9]+">

for restricting letters of the alphabet

<input type="text" pattern="[^a-zA-Z]+">

1 Comment

This is also not an answer, see the question "I know you can use a pattern which will be checked on submit, but I want the "bad" characters to just never be entered at all."
7

KeyboardEvent.keyCode is deprecated, so here's a solution using the HMLElement.input event. This solution uses a simple regex, and handles copy-paste nicely as well by just removing the offending elements from any input.

My regex: /[^\w\d]/gi

  • Matches anything not (^) a word character (\w: a-z) or a digit (\d: 0-9).
  • g modifier makes regex global (don't return after first match)
  • i modifier makes regex case insensitive

With this regex, special characters and spaces won't be allowed. If you wanted to add more, you'd just have to add allowed characters to the regex list.

function filterField(e) {
  let t = e.target;
  let badValues = /[^\w\d]/gi;
  t.value = t.value.replace(badValues, '');
}

let inputElement = document.getElementById('myInput');
inputElement.addEventListener('input', filterField);
<input id="myInput" type="text" style="width: 90%; padding: .5rem;" placeholder="Type or paste (almost) anything...">

1 Comment

If you wanted to add a message on bad input for the user, you could check inside the filderField function for whether a match was detected, and if so, show the message with a short timeout.
2
//improved wbt11a function

function numberFieldStrictInput(allowcomma, allownegative) {
    var e = event || window.event;  // get event object
    var key = e.keyCode ||`enter code here` e.which; // get key cross-browser


    if(key==8 || key==46 || key == 9 || key==17 || key==91 || key==18 || 
            key==116 || key==89 || key==67 || key==88 || key==35 || key==36) //back, delete tab, ctrl, win, alt, f5, paste, copy, cut, home, end
        return true;

    if(key == 109 && allownegative)
        return true;

    if(key == 190 && allowcomma)
        return true;

    if(key>=37 && key<=40) //arrows
        return true;

    if(key>=48 && key<=57) // top key
        return true;

    if(key>=96 && key<=105) //num key
        return true;
    console.log('Not allowed key pressed '+key);

    if (e.preventDefault) e.preventDefault(); //normal browsers
        e.returnValue = false; //IE

}   

//on input put onKeyDown="numberFieldStrictInput(1,0)"

Comments

2

What about this (it supports special keys, like copy, paste, F5 automatically)?

function filterNumericInput() {
    var e = event || window.event;  // get event object
    if (e.defaultPrevented) {
      return;
    }
    const key = e.key || e.code;
    if ((e.key.length <= 1) && (!(e.metaKey || e.ctrlKey || e.altKey))) {
      if (!((key >= '0' && key <= '9') || (key === '.') || (key === ',') || (key === '-') || (key === ' '))) {
        if (e.preventDefault) {
          e.preventDefault();
        } else {
          e.returnValue = false;
        }
      }
    }
}

Comments

1

Limit input to letters, numbers and '.' (for React users only)

Here is my simple solution, I couldn't find a better solution for React and made my own. 3 steps.

First, create a state.

const [tagInputVal, setTagInputVal] = useState("");

Then, use the state as input value (value={tagInputVal}) and pass the event to the onChange handler.

<input id="tag-input" type="text" placeholder="Add a tag" value={tagInputVal} onChange={(e) => onChangeTagInput(e)}></input>

Then, set the value of the event inside onChange handler.

function onChangeTagInput(e) {
    setTagInputVal(e.target.value.replace(/[^a-zA-Z\d.]/ig, ""));
}

Comments

1

Since many of the answers above didn't satisfy me, I propose my solution which solves the problem of the input event being uncancelable by storing the previous value in a custom attribute, and restoring it in case the pattern is not matched:

const input = document.querySelector('#input-with-pattern')
input.addEventListener('keyup', event => {
  const value = event.target.value;
  if (!/^[a-zA-Z]+$/.test(value) && value !== '') { // it will allow only alphabetic
    event.target.value =  event.target.getAttribute('data-value');
  } else {
    event.target.setAttribute('data-value', value);
  }
});
<input id="input-with-pattern">

Comments

0

var keybNumberAndAlpha = new keybEdit(' 0123456789abcdefghijklmnopqrstuvwxyz');

function keybEdit(strValid, strMsg) {
    var reWork = new RegExp('[a-z]','gi');		//	Regular expression\
    //	Properties
    if(reWork.test(strValid))
            this.valid = strValid.toLowerCase() + strValid.toUpperCase();
    else
            this.valid = strValid;
    if((strMsg == null) || (typeof(strMsg) == 'undefined'))
            this.message = '';
    else
            this.message = strMsg;
    //	Methods
    this.getValid = keybEditGetValid;
    this.getMessage = keybEditGetMessage;
    function keybEditGetValid() {
            return this.valid.toString();
    }
    function keybEditGetMessage() {
            return this.message;
    }
}

function editKeyBoard(ev, objForm, objKeyb) {
    strWork = objKeyb.getValid();    
    strMsg = '';							// Error message
    blnValidChar = false;					// Valid character flag
    var BACKSPACE = 8;
    var DELETE = 46;
    var TAB = 9;
    var LEFT = 37 ;
    var UP = 38 ;
    var RIGHT = 39 ;
    var DOWN = 40 ;
    var END = 35 ;
    var HOME = 35 ;
    
    // Checking backspace and delete  
    if(ev.keyCode == BACKSPACE || ev.keyCode == DELETE || ev.keyCode == TAB 
        || ev.keyCode == LEFT || ev.keyCode == UP || ev.keyCode == RIGHT || ev.keyCode == DOWN)  {
            
        blnValidChar = true;
        
    }
    
    if(!blnValidChar) // Part 1: Validate input
            for(i=0;i < strWork.length;i++)
                    if(ev.which == strWork.charCodeAt(i) ) {
                            blnValidChar = true;
                            break;
                    }
                            // Part 2: Build error message
    if(!blnValidChar) 
    {
                //if(objKeyb.getMessage().toString().length != 0)
                    //		alert('Error: ' + objKeyb.getMessage());
            ev.returnValue = false;		// Clear invalid character
            
            
                ev.preventDefault();
        
            objForm.focus();						// Set focus
    }
}
<input type="text"name="worklistFrmDateFltr" onkeypress="editKeyBoard(event, this, keybNumberAndAlpha)" value="">

2 Comments

While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value.
Made it little flexible so that you can add which ever character you want to allow for input
0

I found that onKeyDown captures Shift key, arrows, etc. To avoid having to account for this, I could filter out character input easily by subscribing to onKeyPress instead.

Comments

0

I modified Cullub's answer. The issue is that (with my browser at least) whenever a character is replaced it places the cursor at the end of the input.

HTML

<input id="element">

Javascript

document.getElementById("element").addEventListener("input", checkValue);
function checkValue(e) {
   var position = e.target.selectionStart;
   var length = e.target.value.length;
   e.target.value = e.target.value.replace(/[^\w\d]/gi, '');
   e.target.selectionStart = e.target.selectionEnd = position - (length - e.target.value.length);
}

The function saves the start and end of the cursor position after insertion. If the length changes it resets them and subtracts the number of characters removed. The reason for this is that when entering or pasting characters the cursor moves forward by the number of inserted characters.

Replace [^\w\d] with whatever characters are needed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.