[ Team LiB ] Previous Section Next Section

8.11 Allowing Only Numbers (or Letters) in a Text Box

NN 4, IE 4

8.11.1 Problem

You want to restrict a text field's data entry to numbers only, letters only, or characters from a fixed set.

8.11.2 Solution

In IE 4 or later and Navigator 4 or later, you can allow onkeypress events to succeed only if the desired character keys are pressed. The following function, invoked from a text field's onkeypress event, allows only numerals 0 through 9 (no decimals or minus signs):

function numeralsOnly(evt) {
    evt = (evt) ? evt : event;
    var charCode = (evt.charCode) ? evt.charCode : ((evt.keyCode) ? evt.keyCode : 
        ((evt.which) ? evt.which : 0));
    if (charCode > 31 && (charCode < 48 || charCode > 57)) {
        alert("Enter numerals only in this field.");
        return false;
    }
    return true;
}

The field's event handler would be configured like the following:

onkeypress="return numeralsOnly(event)"

Use the charCode values derived in the numeralsOnly( ) function just shown to make your own variations that permit your desired characters to be entered into the field.

8.11.3 Discussion

Observe the logic of the if condition in the numeralsOnly( ) function just shown. Restated in English, it blocks any character code greater than 31 and any code that is outside the ASCII value of the ten numerals. It's important to allow ASCII values below 32 to pass through the field for most entries. All characters below 32 are nonalphanumeric characters, including the Backspace (8), Tab (9), and Return (13) keys. You usually don't want to block users from editing their entries.

You can cascade more character value comparisons as needed. For example, if you want to allow a decimal in the number, you'd add one more condition to the expression to block characters that met earlier conditions and were not the period's value of 46:

if (charCode > 31 && (charCode < 48 || charCode > 57) && charCode != 46) {...}

You should still perform validation on the entry to make sure the user hasn't entered more than one decimal.

When it comes to text box filtering that permits one or more letters, you must take upper- and lowercase letters into account. Upper- and lowercase versions of a character have their own ASCII values, and the numeric ranges are not contiguous (see Appendix A). Although you can go to great lengths to convert the ASCII value to a character and force its evaluation in strictly upper- or lowercase characters, it's easier to run your comparisons against two ranges of ASCII values. The following function permits letters of both cases (but no punctuation) to pass to the text box:

function lettersOnly(evt) {
    evt = (evt) ? evt : event;
    var charCode = (evt.charCode) ? evt.charCode : ((evt.keyCode) ? evt.keyCode : 
        ((evt.which) ? evt.which : 0));
    if (charCode > 31 && (charCode < 65 || charCode > 90) && 
        (charCode < 97 || charCode > 122)) {
        alert("Enter letters only.");
        return false;
    }
    return true;
}

Recipe 9.8 contains a function that works only in IE to convert characters that are typed as lowercase letters to uppercase characters by the time they reach the text box. If your database requires uppercase characters, you can also consider using the field's client-side validation routine to change the value of the text box to a string of all uppercase letters:

form.field.value = form.field.value.toUpperCase( );

Finally, here's a function that allows only a limited list of characters to be entered. For example, a database table may be set up to require a string entry of Y or N (for Yes or No). To make sure only those characters are entered into the field, the key filtering function (allowing upper- and lowercase letters) looks like the following:

function ynOnly(evt) {
    evt = (evt) ? evt : event;
    var charCode = (evt.charCode) ? evt.charCode : ((evt.keyCode) ? evt.keyCode : 
        ((evt.which) ? evt.which : 0));
    if (charCode > 31 && charCode != 78 && charCode != 89 && 
        charCode != 110 && charCode != 121) {
        alert("Enter \"Y\" or \"N\" only.");
        return false;
    }
    return true;
}

In this case, you could add some more protection against incorrect entries by limiting the text box to a single character:

Signature Present: <input type="text" name="signature" size="2" maxlength="1" 
onkeypress="return ynOnly(event)" /> (Y/N)

8.11.4 See Also

Recipe 9.8 for tips on examining the character the user typed before the character reaches the text field.

    [ Team LiB ] Previous Section Next Section