0

I want to accept only letters, numbers, and commas in an input.

I have tried

document.getElementById('input').onkeydown = function (e) {
  const charCode = (typeof e.which === 'number') ? e.which : e.keyCode;
  return (charCode >= 48 && charCode <= 57) || // numbers
         (charCode >= 65 && charCode <= 90) || // letters
         charCode === 188                      // comma
};

It works, but it also rejects using the arrow keys, enter, delete, and backspace (and potentially other important keys).

I could add another or clause and tell if the user pressed a key arrow, enter, delete or backspace, but is this the correct way to do it? Am I missing some keys? Are the key codes the same on both tablet, desktop and smartphone?

Edit

What if I also want to make sure the user never inputs two consecutive commas? So it won't accept a,b,,c?

davidhu
  • 9,523
  • 6
  • 32
  • 53
mortensen
  • 1,167
  • 2
  • 13
  • 23

2 Answers2

2

According to MDN, charCode and which are both deprecated, and they recommend using keyboardEvent.key.

It is interesting that you tagged regex for this question but I don't explicitly see a regular expression in your question. However, the below sample should suffice. See String.prototype.match for more information about native regular expression support in most browsers...

document.getElementById('input').onkeydown = function (e) {
  var value =  e.target.value;
  //only allow a-z, A-Z, digits 0-9 and comma, with only 1 consecutive comma ...
  if (!e.key.match(/[a-zA-Z0-9,]/) || (e.key == ',' && value[value.length-1] == ',')) {
    e.preventDefault();  
  }
};
Type Value: <input id="input" type="text" />

You could also use character classes- e.g. \d and \w, though \w includes the underscore character (_):

document.getElementById('input').onkeydown = function (e) {
  var value =  e.target.value;
  //only allow a-z, A-Z, digits 0-9 and comma, with only 1 consecutive comma ...
  if (e.key.match(/_/) || !e.key.match(/[\w\d,]/) || (e.key == ',' && value[value.length-1] == ',')) {
    e.preventDefault();  
  }
};
Type Value: <input id="input" type="text" />
Sᴀᴍ Onᴇᴌᴀ
  • 8,218
  • 8
  • 36
  • 58
  • It seems I can't use `e.key` in Chrome? Isn't it weird? I am using Version 47.0.2526.106. – mortensen Oct 05 '16 at 08:23
  • 1
    Ah - I am using version 53.0.2785.143... MDN reports that [KeyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) is supported on Chrome 51+ - I chose that because [charCode](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/charCode) and [which](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/which) are both deprecated... also - are extended ASCII characters okay, like accents: ñ,é,É,etc...? – Sᴀᴍ Onᴇᴌᴀ Oct 05 '16 at 15:11
  • This one accepts the ' character. How to block it too? – Pedro Rabbi Oct 15 '22 at 22:35
  • @PedroRabbi it appears that characters not matching the pattern can be pasted (e.g. with mouse context menu, keyboard shortcut, etc.) - notice that the [`onkeydown` event only fires after a key is pressed](https://developer.mozilla.org/en-US/docs/Web/API/Element/keydown_event). Additional event handlers could be added -e.g. for the [paste event](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/paste_event). one could also consider the [html5 pattern attribue](https://stackoverflow.com/a/18185341/1575353) though that doesn't block the input from being entered. – Sᴀᴍ Onᴇᴌᴀ Oct 18 '22 at 16:16
-3

if ((event.keyCode >= 48 && event.keyCode <= 90)) This Helped For Me , It Allow Only Numbers And Letter Input