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.