3

This question is related to this one Autocomplete: first item focused only when the user type on tab key.

In order to make the first item focused only when the user type on tab key by using jqueryUi is possible to make something like this http://jsfiddle.net/uymYJ/8/ (1).

The bad thing about this implementation is the modification of the event object event.keyCode = $.ui.keyCode.DOWN;.
In fact by doing this way, it will impact all other listeners on this event: all listener on the keydown event running later (which includes all delegated listeners) will see the event.keycode as being $.ui.keyCode.ENTER.

My questions are:

  1. Are my concerns about the modification of the event object justified? If not why?
  2. Can you suggest another way to achieve the same result?
  3. One opition, as suggested by @AaronDigulla, could be to use document.createEvent(). What is the proper way to use this method in this context? I did try the following code (3) but it does not work.

P.S.:
Here is the code about autocomplete (2).


(1)

$("#box").keydown(function(e){
    if( e.keyCode != $.ui.keyCode.TAB) return;
    
   e.keyCode = $.ui.keyCode.DOWN;
   $(this).trigger(e);

   e.keyCode = $.ui.keyCode.ENTER;
   $(this).trigger(e);
    
   $(this).siblings("input").select();
});

(2)

function (e) {
    var f = typeof e == "string",
        g = Array.prototype.slice.call(arguments, 1),
        h = this;
    return e = !f && g.length ? a.extend.apply(null, [!0, e].concat(g)) : e, f && e.charAt(0) === "_" ? h : (f ? this.each(function () {
        var d = a.data(this, c),
            f = d && a.isFunction(d[e]) ? d[e].apply(d, g) : d;
        if (f !== d && f !== b) return h = f, !1
    }) : this.each(function () {
        var b = a.data(this, c);
        b ? b.option(e || {})._init() : a.data(this, c, new d(e, this))
    }), h)
}

(3)

$("#box").keydown(function(){

    e = document.createEvent('KeyboardEvent');
    e.initEvent("keydown", true, true);
    $(this).dispatchEvent(e);

    if( e.keyCode != $.ui.keyCode.TAB) return;
    
   e.keyCode = $.ui.keyCode.DOWN;
   $(this).trigger(e);

   e.keyCode = $.ui.keyCode.ENTER;
   $(this).trigger(e);
    
   $(this).siblings("input").select();
});
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
js999
  • 2,063
  • 4
  • 26
  • 34
  • Autocomplete stops the delegation of the `ENTER` keypress. It's somewhat intentional to reuse the object as all its other properties need to be the same. Other solutions might be to modify the js source or maybe try and call the internal autocomplete methods. – Nal Aug 20 '12 at 18:58
  • @Nal thanks for your comment. What about call the internal autocomplete methods, can you give me an exmaple? – js999 Aug 20 '12 at 19:37
  • So I dug through the autocomplete source code. You still need to have an event object to call the relevant methods. `.trigger` just does it at the highest level. The other simplest workaround would be to just fork autocomplete and add the functionality. The modification of the event object is fine as it won't go beyond the autocomplete event listener although you could use a new `$.Event` for each `.trigger`. – Nal Aug 20 '12 at 20:50
  • @Nal, what do you mean exactly with `although you could use a new $.Event for each .trigger`? Can you give me an example, please? – js999 Aug 21 '12 at 07:41

1 Answers1

1

You're correct: The event will be modified an all listeners will see the modified key code.

But the more important question is: Is this dangerous?

To answer this, we need to know which listeners are bound to the element. Surely, all the listeners from the autocomplete plugin are designed to handle this situation. For them, this is OK.

The trouble starts when you bind your own events to the widgets.

A solution would be to create new events (using document.createEvent() + copying all important attributes) and send the clone to avoid modifying the original event.

Some links:

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • Thanks for your response. I did try to write something but it does not work: jsfiddle.net/uymYJ/18 . Can you write me few lines of code about how to use document.createEvent() ? – js999 Aug 21 '12 at 08:22
  • You will have to set all properties of the event (keyCode, charCode, target, character, ...). I've added some links to my answer. – Aaron Digulla Aug 21 '12 at 11:44