0

I'm trying to have a textfield only allow numbers. (i.e. "0-9" not decimals.) I came upon this popular answer which said to do:

<input type="text" onkeypress='return event.charCode >= 48 && event.charCode <= 57'></input>

I tried that, but the problem is, it allows you to paste any character in. How can I disallow pasted 'illegal' characters? Also, will this code work with different keyboards such as German keyboards?

Please don't post about type="number". I'm not using that for many reasons.

Community
  • 1
  • 1
Jessica
  • 9,379
  • 14
  • 65
  • 136

5 Answers5

0

You can intercept the paste event specifically and handle your case in there.

Community
  • 1
  • 1
Nick Larsen
  • 18,631
  • 6
  • 67
  • 96
0

Intercept the oninput event and deal with the pasted text there. Note this event is also fired on key input.

<script>
function validate(element) {
  if (element.value.match('\\D')) {
    alert('Please enter only numeric values\n(You entered ' + element.value + ')');
    element.value = '';
  }
}
</script>

<input type="text" oninput="validate(this);">
Riaz
  • 874
  • 6
  • 15
  • Thanks for the answer! How can I remove the 'illegal' chars in the `onpaste` event? – Jessica Jan 26 '16 at 06:11
  • See my edited answer. I didn't realize `onpaste` fired before the text is actually pasted, so you can't (easily) get a handle to the text being pasted. `oninput` might be a better option in your case. – Riaz Jan 27 '16 at 00:26
0

HTML Code :

<form name="myForm" action="" onsubmit="return checkInp()" method="post">
  First name: <input type="text" name="age">
 <input type="submit" value="Submit">

Javascript Code :

function checkInp()
   {
     var x=document.forms["myForm"]["age"].value;
       if (isNaN(x)) 
          {
            alert("Must input numbers");
            return false;
          }
   }
0

You can just use keypress event which will check the input every time a new character is entered.

var txt = document.getElementById("phone");
txt.onkeypress = function(key) {
  if (key.charCode < 48 || key.charCode > 57) return false;
}
txt.addEventListener("paste",
  function(e) {
    e.preventDefault();
    var pastedData = e.clipboardData.getData('Text');
    if (!isNaN(pastedData)) {
      txt.value += pastedData;
    }
  }, true);
<fieldset>
  <label for="phone">Phone:</label>
  <input type="text" id="phone" />
</fieldset>
P. Jairaj
  • 1,033
  • 1
  • 6
  • 8
  • I like this, but there are 2 things I don't like about it. 1 - it lets you add an 'illegal' char, then it removes it. 2 - If you have numbers there, then you paste an 'illegal' char, everything in the input gets removed. – Jessica Jan 26 '16 at 05:29
  • @Jessica I have edited the answer. Its in javascript and works as you wanted. Please have a look. – P. Jairaj Jan 26 '16 at 06:23
  • Thanks! Why is `useCapture` set to true? Does it have to be like that? – Jessica Jan 27 '16 at 21:40
  • Also, is `e.clipboardData.getData('Text')` supported by all browsers? – Jessica Jan 27 '16 at 22:04
  • This will answer your question: http://stackoverflow.com/questions/2176861/javascript-get-clipboard-data-on-paste-event-cross-browser – P. Jairaj Jan 28 '16 at 06:56
0

For a user friendly interface, it's usually best to validate based on the actual value of the input, so don't use charCode, use the input's value. For that a simple regular expression suits:

if (/\D/.test(value)) {
  // a non–digit was entered
}

It's often best to validate when the user is finished with the input, e.g. for banking I might copy and paste the balance of my credit card as "1,203.43" and then remove the comma. Then the field is validated when I leave it (onblur or onsubmit) with a suitable onscreen message, leaving me to fix it if it's wrong.

But in some cases it also suits to use keyup or some other suitable event.

So in the case of an input that should have digits only, you might do something like the following:

function validate(el) {
  if (el.classList.contains('numsOnly')) {
    document.getElementById(el.id + 'Err').innerHTML = /\D/.test(el.value)? "Must contain only digits" : '';
  }
}
.screenHint {font: sans-serif; font-size: 80%; color: #999999}
<label for="aNum">A number:<input name="aNum" id="aNum" class="numsOnly"
       onblur="validate(this)" onkeyup="validate(this)" onpaste="validate(this)"
       placeholder="1234"></label><span class="screenHint">Digits only</span><br>
<span style="color:red; background-color: white;" id="aNumErr"></span>

Of course you would likely add the listeners dynamically and have a much more extensive set of validations but the above shows some of the principles.

RobG
  • 142,382
  • 31
  • 172
  • 209
  • Thanks for the answer! I'm doing this for a color slider so the user can enter the values. I've never seen an on screen message for a slider input. What do you suggest? – Jessica Jan 26 '16 at 16:22
  • @Jessica—difficult to say without seeing your interface, but you might just need to indicate the value range, e.g. (0-9) for integers or (0.0-9.9) for decimals. – RobG Jan 27 '16 at 01:24