The SitePoint Forums have moved.

You can now find them here.
This forum is now closed to new posts, but you can browse existing content.
You can find out more information about the move and how to open a new account (if necessary) here.
If you get stuck you can get support by emailing forums@sitepoint.com

If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Response to Javascript Force Numeric Input article

This article is about forcing the keyboard input fields of form inputs to accept only valid numbers, and Gary (the author) wants to know how to modify his script to be cross-browser compatible.

With the way the script currently is, there are a couple of issues that have to be addressed for cross-browser support. These issues are:

Preventing keystrokes

Keycode compatibility

Passing the event

Preventing Keystrokes

Non-IE browsers use a different event model from IE, so preventing keystrokes is performed in a different manner. Setting different event properties may work in a majority of the cases, but the guaranteed way to success is to just return true or false to the event itself. That can be easily achieved by setting an "allowed" variable in the code and returning it at the end of the function.

The keydown events are the biggest problem. Keys like the fullstop have different codes across different browsers. The <a href="http://unixpapa.com/js/key.html">Javascript Madness: Keyboard Events</a>[<a href="http://unixpapa.com/js/key.html" target="_blank" title="New Window">^</a>] article does a good job of explaining the problem.

The solution is to set the event on keypress instead. When you do that the navigation keycodes won't be required anymore, and you can use String.fromCharCode(event.keyCode) to retrieve the key that was pressed as a normal string character.

In my experience the most bombproof way to handle this entire situation is not to handle it. Just use the keyup event to remove anything that shouldn't be there, that way the user sees it happening and doesn't wonder why certain keys do nothing.

I thought that by the the keyup event it's too late to cancel the event to prevent the key from occurring.

*checks*

Yes, the Quirksmode page about keydown, keypress, keyup states that keyup occurs after the default action for that key has occured, and charts that you cannot prevent the default keyup on any browser.

That's the point - you don't try to cancel the event or read the keycode. All input is allowed initially to appear, then the keyup event is used to read the entire content of the field and remove anything unwanted. That way the user will see the unwanted characters being removed and is more likely to understand why, and no keycode incompatibilities to worry about.

For example, instead of using boolean values to specify whether negatives or decimals are allowed, the class name should be used for that instead. It will start off by accepting all numbers, and you can add class names of positive and integer to force it to limit what it accepts as desired.

The class name should also be used to attach the function to the element, with a class name of something like numeric.

Suitable combinations for the class name would be

number

positive number

decimal number

positive decimal number

Then the html code can look like this:

Code html4strict:

<inputid="myNumber"type="text"class="decimal number">

and the html code has all that it needs to let you know what's acceptable for that particular input.

The javascript just needs to find the inputs with a class of number and attach the function on to them, and to do that it needs to run some code after the page has finished loading.

To run code after the page has loaded, you attach a function on to the onload event.

Normally you check if el<els.length in the for loop, but in this case it's more expressive to use el=els[i] which tells you that the loop will continue as long as el can be successfully assigned a value.

When we force the numeric input of a field, how are we going to tell what class values we can use? We can make that very clear in the function itself.

The number expression is going to be one of the following regular expressions, for an integer number, positive integer number, decimal number and a positive decimal number.

-?\d*
\d*
-?\d*\.?\d*
\d*\.?\d*

the -? is an optional minus sign
the \d* is for zero or more digits
and the \.? is for an optional period

Because we are validating the value as each character is typed, we have to allow some normally invalid numbers, such as "-", "0.", which can perhaps be captured on a second level of validation server-side. Remember, don't trust anything from the client side, even if you have javascript validation. The javascript side of things is just to make things easier for the user, it can't guarantee anything though as far as validation is concerned because javascript can always be turned off.