Posts Tagged ‘eventhandling’

I just stumbled over a really annoying bug in jQuery 1.4.1. Internet Explorer 7 and 8 didn’t fire any change event on my text boxes. At least till one other change event from a radio button or drop down list was triggered before. Fortunately I wasn’t the first one to discover the bug and John has already commited a bugfix to git. So the problem will be gone with version 1.4.2.

If you don’t want to or can’t wait for the next version, you can easily fix your current jquery.js file. Go to line 2255 and look for the beforeactivate function. The if-clause limits the initial data storage for change events to radio buttons. That’s why the other change events won’t be registered in IE. Remove the if-clause and everything will work again.

2255
2256
2257
2258
beforeactivate: function(e) {
  var elem = e.target;
  jQuery.data(elem, "_change_data", getVal(elem));
}

I had to add functionality for keyboard navigation to my latest project at work recently. It started out with the need to disable the browser’s postback when someone hits ENTER in a formular. Of course more had to be added once our usability guy realized that theoretically eliminates the need for a mouse. The following example is a bit more basic though and covers only what’s need to understand the concepts.

First of all we have to register the event on the document. Unfortunately keypressed isn’t supported on all browsers and keyup is a little too late to prevent all browser functions so we have to go with keydown.

1
$(document).keydown(function(event){

For cross-browser compatibility two properties of the event need to be checked: event.keyCode and event.which.

2
    var key = event.keyCode || event.which;

And the last thing you have to know is whether the focus is on a textbox or a textarea. Otherwise we can screw up the ability to edit text very easy if we work with ENTER, DELETE or BACKSPACE. The check is done by looking at event.target.type.

3
    if(event.target.type !== 'textarea'){

For the rest of the example, let’s say we have three buttons on our page, selected by jQuery, which get shown and hidden dynamically according to the context: one back button, $back, one forward button, $forward and one button to submit the form, $save.

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
        //ENTER
        if (key === 13) {
            //The button has to be visible to be used.
            if ($save.is(':visible')) {  
                $save.click();  
            } else if ($forward.is(':visible')) {  
                $forward.click();
            }
            //Preventing any other action by the browser
            //even if no button is visible  
            return false;  
        }
        //Not in a textarea or textbox
        if (event.target.type !== 'text') {
            //BACKSPACE  
            if (key === 8) {
                //SHIFT is also pressed
                if (event.shiftKey) {
                    if ($forward.is(':visible')) {
                        $forward.click();
                    }
                } else {
                    if ($back.is(':visible')) {
                        $back.click();
                    }
                }
                return false;
            }
        }
    }
});

That’s it, our application’s enhanced with a few simple keyboard commands.

A little tip at the end: To make your code easier to write and understand here’s a handy object maps the real key codes of the most important special keys to easy to use constants. Just put it in front of the rest of your code.

var keyCode = {
  BACKSPACE: 8,
  CAPS_LOCK: 20,
  COMMA: 188,
  CONTROL: 17,
  DELETE: 46,
  DOWN: 40,
  END: 35,
  ENTER: 13,
  ESCAPE: 27,
  HOME: 36,
  INSERT: 45,
  LEFT: 37,
  NUMPAD_ADD: 107,
  NUMPAD_DECIMAL: 110,
  NUMPAD_DIVIDE: 111,
  NUMPAD_ENTER: 108,
  NUMPAD_MULTIPLY: 106,
  NUMPAD_SUBTRACT: 109,
  PAGE_DOWN: 34,
  PAGE_UP: 33,
  PERIOD: 190,
  RIGHT: 39,
  SHIFT: 16,
  SPACE: 32,
  TAB: 9,
  UP: 38  }