HTML input that takes only numbers and the + symbol

unpollito picture unpollito · May 23, 2016 · Viewed 16.8k times · Source

I am trying to build a custom text input for phone numbers that accepts only numbers and the plus (+) symbol; all other characters need to be discarded and not shown on the field.

I am trying to do this using an event handler (onkeydown/onkeypress) and discarding inputs corresponding to other keys. However, I can't figure out a cross-browser way to do it. Here are the approaches that I have tried and don't work:

  • Using the onkeypress event and looking at event.key to figure out which key was pressed: doesn't work on Chrome (see http://caniuse.com/keyboardevent-key). Is there any cross-browser workaround?

  • Using the onkeycode event and looking at event.keyCode: does not work when we need to press multiple keys to print a character (for instance, an English keyboard layout requires pressing Shift and = to give +). Furthermore, it allows characters such as !@#$%ˆ&*() to appear, as these appear when pressing Shift and a number. (This is the approach followed in JavaScript keycode allow number and plus symbol only, but it does not help me much ;))

  • Using the HTML pattern attribute: this does not really seem to prevent people from writing whatever they feel like.

Thanks!

Answer

R3tep picture R3tep · May 23, 2016

There is another solution, you can use Array.prototype.filter() to remove the bad characters, and Array.prototype.join() to recreate the string before insert it into the input.

You can use oninput event. It execute a JavaScript when a user writes something in an <input> field.


See example below

var inputEl = document.getElementById('tel');
var goodKey = '0123456789+ ';

var checkInputTel = function(e) {
  var key = (typeof e.which == "number") ? e.which : e.keyCode;
  var start = this.selectionStart,
    end = this.selectionEnd;

  var filtered = this.value.split('').filter(filterInput);
  this.value = filtered.join("");

  /* Prevents moving the pointer for a bad character */
  var move = (filterInput(String.fromCharCode(key)) || (key == 0 || key == 8)) ? 0 : 1;
  this.setSelectionRange(start - move, end - move);
}

var filterInput = function(val) {
  return (goodKey.indexOf(val) > -1);
}

inputEl.addEventListener('input', checkInputTel);
<input type='tel' id='tel' />


Note : I use input type tel to show default number pad in a smartphone or a tablet.

tel: A control for entering a telephone number; line-breaks are automatically removed from the input value, but no other syntax is enforced. You can use attributes such as pattern and maxlength to restrict values entered in the control. The :valid and :invalid CSS pseudo-classes are applied as appropriate.

Reference : MDN <input>