Keyboard Input Filtering
Question: Can I use JavaScript to allow digits only in a Answer: First, the usual word of caution: full form validation must occur on the server side because the users can always circumvent the client-side validation, e.g. by disabling JavaScript in the browser. Also, keyboard is not the only input device used in forms: some users might drag or cut-and-paste values into forms using the mouse alone! Now, assuming that we perform the keyboard input filtering (or, for that matter, any other kind of form validation) on the client-side in addition to the server-side validation, below we present a couple of examples showing how to filter out all non-digit input in a cross-browser fashion. Example 1: onkeypress and onkeyup event handlers within the form markup. This example has been tested in Internet Explorer 8.0, Firefox 3.6, Opera 11, Safari 5.0.3, and Chrome 10- and everywhere the validation works as expected.
The code of Example 1 is short and self-explanatory.
However, there are several drawbacks with this solution:
(1) Non-digit characters may briefly show up (one at a time) until the user releases the "offending" key. This is a usability issue, albeit a minor one. (2) The onkeypress and onkeyup event handlers
are present as HTML attributes of the form elements, cluttering the form markup.
A better alternative would be to register the event handlers programmatically.
(3) Instead of just one event handler, we are using two: onkeypress and onkeyup.
(If we try onkeypress only, testing shows that one "offending" character
may survive our filtering. If we try onkeyup only,
then a string of "offending" characters may appear on autorepeat if the user presses and holds a non-digit key.
That's because keypress events do occur on autorepeat,
while keyup events do not.)
Example 2 below addresses all these issues.
|
Source code of Example 1:
<form action=# name=f1 id=f1 onsubmit="return false"> <input type=text name=t1 id=t1 value="" size=25 style="width:300px;" onkeypress="if(this.value.match(/\D/)) this.value=this.value.replace(/\D/g,'')" onkeyup ="if(this.value.match(/\D/)) this.value=this.value.replace(/\D/g,'')" > <br><textarea name=t2 id=t2 cols=25 rows=2 style="width:300px;" onkeypress="if(this.value.match(/\D/)) this.value=this.value.replace(/\D/g,'')" onkeyup ="if(this.value.match(/\D/)) this.value=this.value.replace(/\D/g,'')" > </textarea> </form>
Example 2: one keypress per form element, registered programmatically.
Just like Example 1, this code also works in all browsers listed above. Left and right arrows, Home, End, Delete, Backspace keys, select-all (Ctrl+A), copy (Ctrl+C) and other common operations work as expected within the input field.
Source code of Example 2:
<form action=# name=f2 id=f2 onsubmit="return false">
<input type=text name=t1 id=t1f2 value="" size=25 style="width:300px;">
<br><textarea name=t2 id=t2f2 cols=25 rows=2 style="width:300px;">
</textarea>
</form>
<script type="text/javascript" language=JavaScript>
function inputDigitsOnly(e) {
var chrTyped, chrCode=0, evt=e?e:event;
if (evt.charCode!=null) chrCode = evt.charCode;
else if (evt.which!=null) chrCode = evt.which;
else if (evt.keyCode!=null) chrCode = evt.keyCode;
if (chrCode==0) chrTyped = 'SPECIAL KEY';
else chrTyped = String.fromCharCode(chrCode);
//[test only:] display chrTyped on the status bar
self.status='inputDigitsOnly: chrTyped = '+chrTyped;
//Digits, special keys & backspace [\b] work as usual:
if (chrTyped.match(/\d|[\b]|SPECIAL/)) return true;
if (evt.altKey || evt.ctrlKey || chrCode<28) return true;
//Any other input? Prevent the default response:
if (evt.preventDefault) evt.preventDefault();
evt.returnValue=false;
return false;
}
function addEventHandler(elem,eventType,handler) {
if (elem.addEventListener) elem.addEventListener (eventType,handler,false);
else if (elem.attachEvent) elem.attachEvent ('on'+eventType,handler);
else return 0;
return 1;
}
// onload: Call the init() function to add event handlers!
function init() {
addEventHandler(self.document.f2.elements[0],'keypress',inputDigitsOnly);
addEventHandler(self.document.f2.elements[1],'keypress',inputDigitsOnly);
}
</script>
Copyright © 1999-2011, JavaScripter.net.