Custom jQuery UI Autocomplete Markup

I am using jQuery UI Autocomplete with a categorized search result and I want to give it CSS.

Unfortunately, the jQuery user interface doesn’t simplify the work and the default markup hardly works:

<input class="ui-autocomplete-input"/> <ul class="ui-autocomplete ui-menu ui-widget ui-widget-content ui-corner-all"> <li class='ui-autocomplete-category'>Category 1</li> <li class="ui-menu-item"> <a class="ui-corner-all">item 1</a> </li> <li class="ui-menu-item"> <a class="ui-corner-all">item 2</a> </li> <li class="ui-menu-item"> <a class="ui-corner-all">item 3</a> </li> <li class='ui-autocomplete-category'>Category 2</li> <li class="ui-menu-item"> <a class="ui-corner-all">item 1</a> </li> <li class="ui-menu-item"> <a class="ui-corner-all">item 2</a> </li> <li class="ui-menu-item"> <a class="ui-corner-all">item 3</a> </li> </ul> 

The markup I want is this:

 <input class="ui-autocomplete-input"/> <ul class="ui-autocomplete ui-catcomplete"> <div class="ui-block"> <div class="ui-autocomplete-category">Category 1</div> <div class="ui-list"> <li class="ui-menu-item"> <a class="ui-corner-all">item 1</a> </li> <li class="ui-menu-item"> <a class="ui-corner-all">item 2</a> </li> <li class="ui-menu-item"> <a class="ui-corner-all">item 3</a> </li> </div> </div> <div class="ui-block"> <div class="ui-autocomplete-category">Category 1</div> <div class="ui-list"> <li class="ui-menu-item"> <a class="ui-corner-all">item 1</a> </li> <li class="ui-menu-item"> <a class="ui-corner-all">item 2</a> </li> <li class="ui-menu-item"> <a class="ui-corner-all">item 3</a> </li> </div> </div> </ul> 

And this is when I reach my limit.

I really managed to create markup, but I could no longer select and submit by clicking on an element.

Here is the code I came up with:

 $.widget( "custom.catcomplete", $.ui.autocomplete, { _renderMenu: function( ul, items ) { var self = this, currentCategory = "", i = 0; $.each( items, function( index, item ) { if ( item.category != currentCategory ) { ul.append( "<div class='ui-autocomplete-category'>" + item.category + "</div>"); currentCategory = item.category; } self._renderItem( ul, item ); }); /* This is how I thought it would work */ ul.find('.ui-autocomplete-category').each(function() { $(this).nextUntil('div') .andSelf() .wrapAll('<div class="ui-block">') .nextUntil('div') .wrapAll('<div class="ui-list">'); }); }, _renderItem: function( ul, item) { return $( "<li></li>" ) .data( "item.autocomplete", item ) .append( "<a>" + item.label + "</a>" ) .appendTo( ul ); }, }); $(function() { $( "#ui-autocomplete-input" ).catcomplete({ source: '<?php echo SITEURL?>/users/complete/', delay: 0, autoFocus: true, select: function(event, ui) { if(ui.item) { $('#ui-autocomplete-input').attr('value',ui.item.value); } $('#ui-autocomplete-form').submit(); } }); }); 

Thus, the select: function part does not work at all.

Can anyone help me with this?

I am sure there is an easy way to change the default markup and make it work fine.

Here is what I want it to look like this:

Screenshot of drop-down list with multiple rows and header on left

+4
source share
2 answers

I ended up finding a solution myself, and it includes some CSS tricks and some simple jQuery.

CSS

 .ui-autocomplete { width:424px; margin:0; padding:0 0 14px 0; } .ui-autocomplete-category { width:100px; position: absolute; padding:0 20px; margin:20px 0 0 0; } .ui-menu-item { padding-left:140px; } .ui-first { padding-top:20px; } 

JQuery

 $( "#search" ).catcomplete({ delay: 0, source: data, autoFocus: true, select: function(event, ui) { if(ui.item) { $('#search').attr('value',ui.item.value);} $('#form').submit(); }, /* This is the important part! */ open: function() { $('.ui-autocomplete-category').next('.ui-menu-item').addClass('ui-first'); } }); 

Basically, I play with absolute positioning to place the category name on the left and add the class to the first LI element using jQuery to create some spacing with PADDING.

It is not perfect, but it works flawlessly :)

+4
source

You can solve this problem without changing the HTML with a bit of CSS cheating:

 ul.ui-autocomplete { padding-left: 200px; } ul.ui-autocomplete li.ui-autocomplete-category { width: 200px; height: 50px; margin-left: -200px; margin-bottom: -50px; } 

This is not ideal (the height of the li category may exceed the height of the results - OR it may not match the contents of li), but it works.

Btw: the only valid child of ul is li. So that won't help you either.

+1
source

Source: https://habr.com/ru/post/1387097/


All Articles