0

I have a textbox with an autocomplete tied to it. I'm also adding a custom element to the autocomplete dropdown when the text of the input box contains certain char. I'm adding this custom element customizing the _renderItem function of the plugin:

$tb.autocomplete({
    /* OPTIONS HERE */
}).data("autocomplete")._renderItem = function (ul, item) {
  if ($tb.val().indexOf('someText') > -1){
    ul.append('<li class="dropdown-element"><a href="#" class="my-option">My custom option</a></li>');
  }
  return false;
}

I want that whenever the user types something that contains 'someText' and presses Enter (without selecting anything on the dropdown before), the 'select' event of the autocomplete is raised for my custom element.

I tried just adding a handler for the 'keyup' event on the textbox but the handler is called every time I press enter (even if there was some element selected in the dropdown) and I cannot cancel the propagation of the event from the 'select' event handler of the autocomplete. (I tried e.stopPropagation and e.originalEvent.stopPropagation but it still gets handled by the 'keyup' handler).

Any ideas on how to achieve this? Thanks

The Alpha
  • 143,660
  • 29
  • 287
  • 307
willvv
  • 8,439
  • 16
  • 66
  • 101

2 Answers2

0

How about taking the approach of having someText as a valid option, removing it via the open event if the user hasn't typed the whole thing, but then leave it if they have - http://jsfiddle.net/tj_vantoll/bgstB/.

The only trouble with this approach is that if you need the event to be called when the user types something like foo bar someText the open event will not be called.

TJ VanToll
  • 12,584
  • 4
  • 43
  • 45
  • The issue wasn't with adding or not the element, what I wanted to do was process the "Enter" when the user hadn't selected one of the items of the dropdown (the custom item or one of the default items). – willvv Jul 15 '12 at 16:58
0

Ok, took me a while to find a solution but here it is:

var autocomplete = $tb.autocomplete({
    /* OPTIONS HERE */
  select:function(e, ui){
    // The 'autocompleteselected' event wraps a 'menuselected' event that wraps a 'keydown' event
    // we stop the propagation of this event to prevent the event handler of keydown from processing the enter when an item was selected by that enter
    event.originalEvent.originalEvent.stopPropagation();

    ProcessSelectedElement(ui);
  }
});
autocomplete.data("autocomplete")._renderItem = function (ul, item) {
  if ($tb.val().indexOf('someText') > -1){
    ul.append('<li class="dropdown-element"><a href="#" class="my-option">My custom option</a></li>');
  }
  return false;
}

autocomplete.keydown(function(e){
    if (e.keyCode == 13 && !e.isPropagationStopped() && tb.val().indexOf('someText') > -1) {
      ProcessCustomElement();
    }
});

Basically what I do is stop the propagation of the original keydown event when this event selected one of the existing items. In the keydown event handler I just verify that the propagation of that event hasn't been stopped and process the enter accordingly.

A possible issue might be that for some reason the event handler for the keydown is executed before the 'autocompleteselected' event handler, in which case the event propagation won't be stopped, but the tests I've done don't show this problem.

willvv
  • 8,439
  • 16
  • 66
  • 101