4

I use replace() to remove non-numeric characters from an input field, like so:

<input type="number" oninput="this.value = this.value.replace(/[^\d]/g,'');">

It works well, but when I enter a few numbers followed by a minus sign or a dot (on Android it has to be two dots), the whole field is cleared. This only happens when the input type is set to "number", not when it's set to "text", but I need "number" to show the numeric keyboard on mobile.

Why could this happening?

To clarify, I only want to allow [0-9], not other possibly numeric characters like [.-e].

redburn
  • 542
  • 4
  • 24
  • 1
    Possible duplicate of [Phone: numeric keyboard for text input](http://stackoverflow.com/questions/6178556/phone-numeric-keyboard-for-text-input) – Chris May 03 '17 at 13:25
  • That thread doesn't answer my question, i.e. why is the field cleared, and neither do the answers offer valid solutions: the most popular answer doesn't bring up the numeric keyboard on my Android device, and the second uses the `number` type field and as such has the same issue. – redburn May 03 '17 at 13:57
  • okay. Thought it might've been helpful :) – Chris May 03 '17 at 13:58
  • It was helpful & interesting, but not a duplicate :) – redburn May 03 '17 at 17:13

1 Answers1

4

Here's a solution:

function cancelEvent(event) {// cross-browser code
  event.cancelBubble = true;
  event.returnValue = false;
  if(event.stopPropagation)
    event.stopPropagation();
  if(event.preventDefault)
    event.preventDefault();
}

document.getElementById('testInput').addEventListener('keydown', function(event) {
  var keyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;// cross-browser code
  if(keyCode != 8 && (keyCode < 48 || keyCode > 57)){// excludes non-numeric inputs
    cancelEvent(event);
  }
});

document.getElementById('testInput').addEventListener('textInput', function(event) {
  event = window.event || event;// cross-browser code
  if(/[^0-9]/.test(event.data)) {
    cancelEvent(event);
  }
});
<input type="number" id="testInput">

I took part of the cross-browser code from this answer: https://stackoverflow.com/a/585590/3514976

Community
  • 1
  • 1
nonzaprej
  • 1,322
  • 2
  • 21
  • 30
  • Did you test that? [^\d], [^0-9] or [^0123456789], the effect is the same. – redburn May 03 '17 at 13:49
  • 1
    No because I'm an idiot. I'm gonna edit it with a working solution. – nonzaprej May 03 '17 at 13:54
  • I appreciate the effort, but this still allows the - and . on Android's numeric keyboard. Unfortunately, both of these have the char code 229, and adding that to your if() doesn't stop them from being entered. – redburn May 03 '17 at 14:56
  • You're right, I tried everything and that stupid dot always passes through. I didn't find any solution online, either. I've already had to do with numeric keyboards on mobile and it was never pretty... I'll delete this answer since it doesn't solve the problem in your question. – nonzaprej May 03 '17 at 16:46
  • Ok, sorry for all the back-and-forth. This time the solution actually works :P – nonzaprej May 03 '17 at 19:57
  • Nicely done! It seems to work well. Perhaps the numpad key codes should be added for non-mobile users. I still wonder why the input field was cleared in the first place, but if there's no answer to that then I'll happily accept your solution. Thanks for the effort! – redburn May 03 '17 at 20:25
  • Initially I filtered the codes like this: `keyCode != 8 && (keyCode < 48 || (keyCode > 57 && keyCode < 96) || keyCode > 105)`, but when I tried it the codes of the numpad keys were still in the 48-57 range and I also could write "e" which had code 101. Btw, don't forget to set the answer as the correct one if it suits your need. I say it just in case 'cause even just today I saw several people forgetting about it. – nonzaprej May 03 '17 at 21:08