Skip to main content

Search and Top Navigation

#9549 closed bug (invalid)

Opened September 11, 2013 02:13PM UTC

Closed September 27, 2013 08:33AM UTC

Last modified August 29, 2014 12:13PM UTC

Displaying a single non selectable item raises js error

Reported by: s_welte Owned by: s_welte
Priority: minor Milestone: none
Component: ui.menu Version: 1.10.3
Keywords: Cc:
Blocked by: Blocking:
Description

Problem:

Displaying only a single non selectable item in the autocomplete result will cause an js error on (menu) focus change.

Minimal Example:

http://jsfiddle.net/kZEjJ/

Proposed fix:

The _move function in ui.menu does make some invalid assumptions: Displaying a single menu item does not automatically imply that this menu item is selectable. We found that adding this simple guard fixed our problem:

diff --git jquery-ui-1.10.3.custom.js jquery-ui-1.10.3.custom.js
--- jquery-ui-1.10.3.custom.js
+++ jquery-ui-1.10.3.custom.js
@@ -2442,8 +2442,9 @@ $.widget( "ui.menu", {
     if ( !next || !next.length || !this.active ) {
             next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
     }
-
-    this.focus( event, next );
-
+    if (next.length !== 0) {
+      this.focus(event, next);
+    }
   },

   nextPage: function( event ) {

Unfortunately we do not know the jquery ui codebase too well, so there might be side effects or architecture related things we don't know about.

Attachments (0)
Change History (6)

Changed September 11, 2013 02:44PM UTC by tj.vantoll comment:1

owner: → s_welte
status: newpending

Hi s_welte,

Thanks for taking the time to contribute to the jQuery UI project. The autocomplete widget is expecting data with a key of "ui-autocomplete-item" to be associated with each

<li>
in the results. See https://github.com/jquery/jquery-ui/blob/37bba1eb920298994903e866625bb662f391a1f5/ui/jquery.ui.autocomplete.js#L522.

For example: http://jsfiddle.net/tj_vantoll/n3Eqn/

Out of curiosity why did you override

_renderMenu
? I'm wondering if we could do anything here to make the extension a little easier.

Changed September 11, 2013 04:17PM UTC by s_welte comment:2

status: pendingnew

Hi,

I added ui-autocomplete-item but it does not help in this case. Your example (http://jsfiddle.net/tj_vantoll/n3Eqn/) also throws the js error on key_down (Tested in Chrome + Firefox + IE).

To give you an idea how we're using _render_menu have a look at https://gist.github.com/svenwelte/e6cc614010d38af1289e

As you can see there are quite a bit of different usecases implemented that can also occur at the same time:

  • Display autocomplete result formatted in various ways
  • Group results
  • Only show a non selectable message (e.g. "No results found"). That's what this bug is about.
  • Create additional menu items in addition to the normal autocomplete result that trigger custom actions. e.g. You enter 'foo' which autocompletes to 'foobar', 'foodball', 'Action: Create new "foo" '

HTH,

Sven

Changed September 12, 2013 12:42PM UTC by tj.vantoll comment:3

status: newpending

Whoops, this one should work http://jsfiddle.net/tj_vantoll/n3Eqn/1/.

I had a misspelling, and menu also requires each

<li>
to contain an
<a>
. For your no results found use case I would recommend displaying that message outside of the main list.

I think it would potentially confusing to the user to have a message appear in a list where valid options normally appear.

You also might be able to call

_renderItemData
so that you don't have to explicitly store the data as
"ui-autocomplete-item"
youself.

Changed September 12, 2013 02:26PM UTC by scottgonzalez comment:4

_renderMenu() calls _renderMenuItemData(), which calls _renderMenu() and then stores the data. This is done specifically so that users overriding _renderMenuItem() don't need to concern themselves with storing the data.

Changed September 27, 2013 08:33AM UTC by trac-o-bot comment:5

resolution: → invalid
status: pendingclosed

Because we get so many tickets, we often need to return them to the initial reporter for more information. If that person does not reply within 14 days, the ticket will automatically be closed, and that has happened in this case. If you still are interested in pursuing this issue, feel free to add a comment with the requested information and we will be happy to reopen the ticket if it is still valid. Thanks!

Changed August 29, 2014 12:13PM UTC by lankymart comment:6

_comment0: Not sure if this is intended but there are various examples of implementing a header (non selectable list element) but I've found that whatever I try and can't stop the default "ui-menu-item" class being applied to my listitem. I've managed to workout that the examples that work are using 1.8 but I'm using 11.0 and it's defaulting to the "ui-menu-item" and doesn't seem to over-ridable. \ \ '''Example of working header''' \ \ http://jsfiddle.net/IrvinDominin/rMkER/ \ \ '''Code Excerpt''' \ \ \ {{{ \ $("#list").autocomplete("instance")._renderMenu = function(ul, items) { \ var self = this; \ $.each( items, function( index, item ) { \ self._renderItemData(ul, item); \ // prepended element still ends up with "ui-menu-item" class?? \ if (index == 0) ul.prepend('<li class="ui-header"><span>Returned ' + items.length + ' record(s)</span></li>'); \ }); \ // attempt to hack css! \ ul.find("li:first-child").removeClass("ui-menu-item"); \ }; \ }}} \ 1409314477456597
_comment1: Not sure if this is intended but there are various examples of implementing a header (non selectable list element) but I've found that whatever I try and can't stop the default "ui-menu-item" class being applied to my listitem. I've managed to workout that the examples that work are using 1.8 but I'm using 11.0 and it's defaulting to the "ui-menu-item" and doesn't seem to be over-ridable. \ \ '''Example of working header''' \ \ http://jsfiddle.net/IrvinDominin/rMkER/ \ \ '''Code Excerpt''' \ \ \ {{{ \ $("#list").autocomplete("instance")._renderMenu = function(ul, items) { \ var self = this; \ $.each( items, function( index, item ) { \ self._renderItemData(ul, item); \ // prepended element still ends up with "ui-menu-item" class?? \ if (index == 0) ul.prepend('<li class="ui-header"><span>Returned ' + items.length + ' record(s)</span></li>'); \ }); \ // attempt to hack css! \ ul.find("li:first-child").removeClass("ui-menu-item"); \ }; \ }}} \ 1409314619517725
_comment2: Not sure if this is intended but there are various examples of implementing a header (non selectable list element) but I've found that whatever I try and can't stop the default "ui-menu-item" class being applied to my listitem. I've managed to workout that the examples that work are using 1.8 but I'm using 11.0 and it's defaulting to the "ui-menu-item" and doesn't seem to be over-ridable. \ \ '''Example of working header''' \ \ http://stackoverflow.com/a/20676143/692942 \ \ http://jsfiddle.net/IrvinDominin/rMkER/ \ \ '''Code Excerpt''' \ \ \ {{{ \ $("#list").autocomplete("instance")._renderMenu = function(ul, items) { \ var self = this; \ $.each( items, function( index, item ) { \ self._renderItemData(ul, item); \ // prepended element still ends up with "ui-menu-item" class?? \ if (index == 0) ul.prepend('<li class="ui-header"><span>Returned ' + items.length + ' record(s)</span></li>'); \ }); \ // attempt to hack css! \ ul.find("li:first-child").removeClass("ui-menu-item"); \ }; \ }}} \ 1409324869576439
_comment3: Not sure if this is intended but there are various examples of implementing a header (non selectable list element) but I've found that whatever I try and can't stop the default "ui-menu-item" class being applied to my listitem. I've managed to workout that the examples that work are using 1.8 but I'm using 11.0 and it's defaulting to the "ui-menu-item" and doesn't seem to be over-ridable. \ \ '''Example of working header''' \ \ http://stackoverflow.com/a/20676143/692942 \ \ http://jsfiddle.net/IrvinDominin/rMkER/ \ \ '''Code Excerpt''' \ \ \ {{{ \ $("#list").autocomplete("instance")._renderMenu = function(ul, items) { \ var self = this; \ $.each( items, function( index, item ) { \ self._renderItemData(ul, item); \ // prepended element still ends up with "ui-menu-item" class?? \ if (index == 0) ul.prepend('<li class="ui-header"><span>Returned ' + items.length + ' record(s)</span></li>'); \ }); \ // attempt to hack css! \ ul.find("li:first-child").removeClass("ui-menu-item"); \ }; \ }}} \ \ I've now pin pointed what I think is the cause it appears after 1.10.4 and is present in 1.11.0 it's in the refresh() method in menu.js (previously jquery.ui.menu.js). \ \ It looks like it's due to the requirement for an anchor to be present being removed (see https://github.com/jquery/jquery-ui/blob/3a61627a501cb7ba1ce80046bfabbff0f7f2f517/ui/jquery.ui.menu.js#L325)1409325067017919
_comment4: Not sure if this is intended but there are various examples of implementing a header (non selectable list element) but I've found that whatever I try and can't stop the default "ui-menu-item" class being applied to my listitem. I've managed to workout that the examples that work are using 1.8 but I'm using 11.0 and it's defaulting to the "ui-menu-item" and doesn't seem to be over-ridable. \ \ '''Example of working header''' \ \ http://stackoverflow.com/a/20676143/692942 \ \ http://jsfiddle.net/IrvinDominin/rMkER/ \ \ '''Code Excerpt''' \ \ \ {{{ \ $("#list").autocomplete("instance")._renderMenu = function(ul, items) { \ var self = this; \ $.each( items, function( index, item ) { \ self._renderItemData(ul, item); \ // prepended element still ends up with "ui-menu-item" class?? \ if (index == 0) ul.prepend('<li class="ui-header"><span>Returned ' + items.length + ' record(s)</span></li>'); \ }); \ // attempt to hack css! \ ul.find("li:first-child").removeClass("ui-menu-item"); \ }; \ }}} \ \ I've now pin pointed what I think is the cause it appears after 1.10.4 and is present in 1.11.0 it's in the refresh() method in menu.js (previously jquery.ui.menu.js). \ \ It looks like it's due to the requirement for an anchor to be present being removed (see https://github.com/jquery/jquery-ui/blob/3a61627a501cb7ba1ce80046bfabbff0f7f2f517/ui/jquery.ui.menu.js#L325 and https://github.com/jquery/jquery-ui/commit/3a61627a501cb7ba1ce80046bfabbff0f7f2f517#commitcomment-7591515)1409325707142533
_comment5: → 1409325761052953

Wrong issue / related but wrong (removed comments) - migrated to http://bugs.jqueryui.com/ticket/10130#comment:2