JQuery UI Autocomplete Custom HTML (element undefined)

I hit my head from my desk trying to get jQuery UI autocomplete for custom HTML output. Here is my code.

$(document).ready(function(){ $.widget( "custom.catcomplete", $.ui.autocomplete, { _renderMenu: function( ul, items ) { var self = this, currentCategory = ""; $.each( items, function( index, item ) { if ( item.category != currentCategory ) { ul.append( "<li class='ui-autocomplete-category'>" + item.category + "<ul class='autocomplete-category'></ul></li>" ); currentCategory = item.category; } self._renderItem( ul, item); }); } }); var data = [ { label: "anders", category: "Antigen" }, { label: "andreas", category: "Antigen" }, { label: "antal", category: "Antigen" }, { label: "annhhx10", category: "Products" }, { label: "annk K12", category: "Products" }, { label: "annttop C13", category: "Products" }, { label: "anders andersson", category: "People" }, { label: "andreas andersson", category: "People" }, { label: "andreas johnson", category: "People" } ]; $( "#typeAhead" ).catcomplete({ delay: 0, source: data, }) .data( "catcomplete" )._renderItem = function( ul, item ) { return $( "<li></li>" ) .data( "item.catcomplete", item ) .append( $( "<a class='ui-menu-item'></a>" ).text( item.label ) ) .appendTo( $('ul').last('.autocomplete-category')); }; }); 

I seem to have run into difficulties by nesting my lists in the renderItem function. HTML output is exactly what I want. However, when I "keydown", I get a javascript error (undefined element).

Any ideas or suggestions? I tried almost everything.

+6
javascript jquery jquery-ui autocomplete jquery-ui-autocomplete
source share
1 answer

You were almost there! I only made two changes to make this work ( Updated after comments from OP ):

After transcoding to the jQueryUI autocomplete source, it seems that the main menu used by the autocomplete widgets is not too friendly with the nested elements.

I could be wrong about this, but I think the menu expects a simple <ul> with just the children <li> containing the anchor tag.

Change This line confirms my suspicion of the menu (found in jqueryUI 1.8.9 widgets):

  var items = this.element.children("li:not(.ui-menu-item):has(a)") .addClass("ui-menu-item") .attr("role", "menuitem"); items.children("a") .addClass("ui-corner-all") .attr("tabindex", -1) // mouseenter doesn't work with event delegation .mouseenter(function( event ) { self.activate( event, $(this).parent() ); }) .mouseleave(function() { self.deactivate(); }); 

In principle, since a tags were buried inside a nested list, they were not recognized in the menu.

I bet you noticed in your source code that your autocomplete menu items didn't stand out when you came across them. This selection actually matches the menu item that considers the widget active, which caused your widget to crash when the user selected the item.

Since nothing is semantically wrong or visually wrong, just assigning the li category to another class, I would restructure the widget menu as follows:

JavaScript:

_renderItem Function:

 .data( "catcomplete" )._renderItem = function( ul, item ) { return $( "<li></li>" ) .data( "item.autocomplete", item ) .append( $( "<a class='ui-menu-item'></a>" ) .text( item.label ) ) .appendTo(ul); }; 

Your _renderMenu function:

 _renderMenu: function( ul, items ) { var self = this, currentCategory = ""; $.each( items, function( index, item ) { if ( item.category != currentCategory ) { ul.append( "<li class='ui-autocomplete-category'>" + item.category + "</li>" ); currentCategory = item.category; } self._renderItem( ul, item); }); } 

Generated HTML for autocomplete menu:

 <ul class="ui-autocomplete> <li class="ui-autocomplete-category">Antigen</li> <li class="ui-menu-item" role="menuitem"> <a class="ui-menu-item ui-corner-all" tabindex="-1">anders</a> </li> <li class="ui-menu-item" role="menuitem"> <a class="ui-menu-item ui-corner-all" tabindex="-1">andreas</a> </li> <li class="ui-menu-item" role="menuitem"> <a class="ui-menu-item ui-corner-all" tabindex="-1">antal</a> </li> <!-- More categories, items, etc.--> </ul> 

Judging by your comments, it seemed like you want the HTML menu to be a nested ul inside li for each category. Let me know if for any reason you do not change the HTML code of the generated menu.

I updated the example: http://jsfiddle.net/andrewwhitaker/pjs7a/2/

Hope this helps.

+12
source share

All Articles