CIT041J Index > Lecture Notes - Key Events

CIT041J Lecture Notes - Key Events

Creating JavaScript to capture key presses, and making it work in both Mozilla and Internet Explorer is actually much more difficult than it appears.

The Problem

We want an input field that allows only integers, and checks the input as you type. Here’s the pseudocode:

onkeydown, onkeyup, or onkeypress

The question is which of these three events to look at. It turns out that Internet Explorer will let you cancel a keydown event, but Mozilla will not. On the other hand, keypress on Mozilla will detect the backspace key; but Internet Explorer (IE) won’t. In the application at hand, which is to allow only integers in an input field, we do not need to detect backspace, so we will go with keypress.

Setting the handler

The easiest thing to do is to simply set the handler directly in the HTML element. This works on both Mozilla and Internet Explorer, so here’s the form:

Enter an integer:


<form action="#" onsubmit="return false">
<p>Enter an integer: <input type="text" id="number"
	onkeypress="return checkInteger( event );" /></p>
</form>

The Code

The function code follows. Numbers in black squares like this: 0 denote references to notes in the text. You may click a number to go directly to the corresponding note.

function checkInteger( evt )
{
    var ch;             // the character to process
    
    var keyOK = false;  // presume it's bad

    var isSpecial;      // non-printing character?
    
    var source;         // the event source
    
    var intPattern = /^[+-]?\d*$/;

    if (!evt) 1
    {
        evt = window.event;
    }

    ch = evt.charCode; 2
    if (!ch)
    {
        ch = evt.keyCode;
    }

    isSpecial = ( ch == evt.DOM_VK_TAB || 3
        ch == evt.DOM_VK_BACK_SPACE );

    if (isSpecial)
    {
        keyOK = true;
    }
    else
    {
        ch = String.fromCharCode( ch ); 4

        if (evt.target) 5
        {
            source = evt.target;
        }
        else
        {
            source = evt.srcElement;
        }

        keyOK = intPattern.test( source.value + ch ); 6
    }
    return keyOK; 7
}

1 The checkInteger() function will receive an event object in Mozilla; in older versions of IE, it receives a null. This if statement makes sure that the variable is set correctly.

2 In Mozilla, the charCode property is set if the key you pressed generates a printable character; otherwise, keyCode is set. In Internet Explorer, keyCode is set for printable characters, and charCode is undefined.

3 Once we have the keycode, we need to check if it is a TAB or backspace key. he constants such as evt.DOM_VK_TAB and evt.DOM_VK_BACK_SPACE are pre-defined as properties of a Document Object Model event. Note that we are disallowing left and right arrow; allowing them would make the code much more difficult.

4 If it’s not a special key, then we need to convert it from a numeric code to a character. This is done with the String.fromCharCode() method.

5 We need to see if this character is valid when added to the current value in the input field. We could get the input field’s value with document.getElementById("number").value, but then our function would work only on that particular field. To make the program more generic, we want to find the source of the key event–which input field generated the keypress–and look at its value. Again, Mozilla and IE differ on their names for finding the source of an event. Mozilla uses the target property whereas IE uses the srcElement property.

6 Now that we have access to the event source (the input field, in this case), we can append the character to the field’s current value and check it against a pattern for valid integers. Rather than use the search() the string for a pattern, it’s easier to test() the pattern against the string, returning a boolean value. Notice that the pattern allows zero or more digits; this permits a leading plus or minus as the first character in the field.

7 If the resulting value is true, the keypress will be processed; if false, the event is cancelled.