1

I'm using the Ajax.Autocompleter component, which works great - except ampersands in some browsers. The problem is that instead of printing the ampersand sign into the search field, it acts as an 'up' arrow in the ajax suggestion list. This makes my users unable to write names with ampersands into the search box.

http://github.com/madrobby/scriptaculous/wikis/ajax-autocompleter

Specific behavior cases:

  • If I try to type the ampersand into my search field before the list with suggestions is shown, the ampersand gets added to the search field and all is well.

  • If I try to type the ampersand after the suggestion list is already visible, it will navigate to the end of the list instead, and nothing will get added to the search field (Chrome).

  • If I repeat this scenario in IE11, it will also navigate to the end of the list, but also add the ampersand to the search field. However, the ajax search will not get triggered in this case - the suggestion list will remain as it was before I hit the '&' key, regardless of the fact that the search field not ends with a &.

  • Firefox just adds the '&' char to the search box and refreshes the autocomplete suggestion list. As I would expect.

By trial and error, I noticed that:

  • When I open F12 in chrome, and debug the javascript, the ampersand gets printed instead of navigating through the suggestion list. When the debug is off it doesn't print anything and navigates instead.
  • If I use ctrl+v to paste the ampersand into the search field, it works fine in all browsers. On the other hand left alt + 38 does the things mentioned above, same as normal key.

My code:

<input name="searchTxt" id="searchTxt" type="text" autocomplete="off" />
<div id="autocompleteResults" style="display:none;border:1px solid black;background-color:white;text-align:left;"></div>

<script type="text/javascript" language="javascript" charset="utf-8">
  new Ajax.Autocompleter('searchTxt','autocompleteResults','someUrlToGetAutocompleteResults', {});
</script>

The only clues I was able to find so far are pretty weak:

Any help is appreciated - I'll get into studying the Ajax.Autocompleter project in more detail, but since this seemed it might also be something browser-related, I asked with hopes that someone might have at least a partial answer.

Community
  • 1
  • 1
Arides
  • 111
  • 7

2 Answers2

0

After more debugging I found what is causing this problem. The scriptaculous library consists of several .js files - the first problem is in file 'controls.js', line 129.

Here is a function which handles some key strokes - for instance UP and DOWN arrows to navigate through the suggestion list. In chrome, this function gets called after pressing the '&' and '(' keys, instead of the arrows, thus causing the issue.

  onKeyPress: function(event) {
    if(this.active)
      switch(event.keyCode) {
       case Event.KEY_TAB:
       case Event.KEY_RETURN:
         this.selectEntry();
         Event.stop(event);
       case Event.KEY_ESC:
         this.hide();
         this.active = false;
         Event.stop(event);
         return;
       case Event.KEY_LEFT:
       case Event.KEY_RIGHT:
         return;
       case Event.KEY_UP:
         this.markPrevious();
         this.render();
         Event.stop(event);
         return;
       case Event.KEY_DOWN:
         this.markNext();
         this.render();
         Event.stop(event);
         return;
      }
     else
       if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
         (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;

    this.changed = true;
    this.hasFocus = true;

    if(this.observer) clearTimeout(this.observer);
      this.observer =
        setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
  }

While this is still not the root cause, it's definitely something to work with and can be used at least for workarounds (if chrome then ignore arrow keys in this function, etc.)

Arides
  • 111
  • 7
0

Culprit found!

As it turns out, chrome and IE11 (and possibly more) browsers have the same keyCode value for both the UP arrow, and the '&' key in the 'onKeyPress' function. To read a bit more, see this thread. Some recommend using the 'keyDown' event instead of 'keyPress', i went with a workaround instead.

I have changed the onKeyPress function code in file 'controls.js', line 129. The workaround is not 100% - but it makes ampersand work via shift+7, while retaining the arrow key functionality in firefox.

  onKeyPress: function(event) {

    //Added this workaround
    var is_shift;
    if (window.event) {
        is_shift = window.event.shiftKey ? true : false;
    } else {
        is_shift = event.shiftKey ? true : false;
    }

    if(this.active)
      ...
       case Event.KEY_UP:
         if (!is_shift) //Added this workaround
         {
             this.markPrevious();
             this.render();
             Event.stop(event);
             return;
         }
       case Event.KEY_DOWN:
         if (!isShift) //Added this workaround
         {
             this.markNext();
             this.render();
             Event.stop(event);
             return;
         }
      }
    ...
  }

The shift workaround idea comes from here, while the code to get the shift status is taken from here.

Community
  • 1
  • 1
Arides
  • 111
  • 7