Display jQuery UI autocomplete as a table

I use jQuery UI autocomplete. I have several values, as well as a small set of keywords, one of which is assigned to each value. I would like to display each pair in a mini-table, with a keyword in one cell and a value in another. To do this, I rewrite _renderItem as indicated in the documentation . However, when I do this, clicking on a value (or keyword) does not actually do anything, so I cannot select any values. I suspect this is due to the fact that data("item.autocomplete", item) not in the right place. Or maybe I need to rewrite another function above ( _renderMenu or _suggest ?)

 $( "#tags" ).autocomplete({ source: getItems }) .data( "autocomplete" )._renderItem = function( ul, item ) { return $( '<table></table>' ) .data( "item.autocomplete", item ) .append( '<tr><td>' + item.keyword + '</td><td> ' + item.value + "</td></tr>" ) .appendTo( ul ); }; 
+6
source share
4 answers

I think this may help you, here is js:

 $(function() { //overriding jquery-ui.autocomplete .js functions $.ui.autocomplete.prototype._renderMenu = function(ul, items) { var self = this; //table definitions ul.append("<table><thead><tr><th>ID#</th><th>Name</th><th>Cool&nbsp;Points</th></tr></thead><tbody></tbody></table>"); $.each( items, function( index, item ) { self._renderItemData(ul, ul.find("table tbody"), item ); }); }; $.ui.autocomplete.prototype._renderItemData = function(ul,table, item) { return this._renderItem( table, item ).data( "ui-autocomplete-item", item ); }; $.ui.autocomplete.prototype._renderItem = function(table, item) { return $( "<tr class='ui-menu-item' role='presentation'></tr>" ) .data( "item.autocomplete", item ) .append( "<td >"+item.id+"</td>"+"<td>"+item.value+"</td>"+"<td>"+item.cp+"</td>" ) .appendTo( table ); }; //random json values var projects = [ {id:1,value:"Thomas",cp:134}, {id:65,value:"Richard",cp:1743}, {id:235,value:"Harold",cp:7342}, {id:78,value:"Santa Maria",cp:787}, {id:75,value:"Gunner",cp:788}, {id:124,value:"Shad",cp:124}, {id:1233,value:"Aziz",cp:3544}, {id:244,value:"Buet",cp:7847} ]; $( "#project" ).autocomplete({ minLength: 1, source: projects, //you can write for select too focus: function( event, ui ) { //console.log(ui.item.value); $( "#project" ).val( ui.item.value ); $( "#project-id" ).val( ui.item.id ); $( "#project-description" ).html( ui.item.cp ); return false; } }) }); 

You can check this fiddle

+7
source

You cannot create a <table> in _renderItem to render an element directly. The plugin uses <ul> as a container for menu items.

You must adhere to the <li> elements and you can customize the layout inside the <li> by inserting your table element into it.

But I would not use a table to do this. Can't you just use span elements?

+2
source

Good example given in Fiddle.

However, after the latest versions, updating jQuery and jQuery UI, which just stopped working. Not really, however the jQuery UI now returns an error on menufocus, which is pretty annoying.

JS Fiddle example with jQuery 2.1.3 and jQuery UI 1.11.3

 $(function() { //overriding jquery-ui.autocomplete .js functions $.ui.autocomplete.prototype._renderMenu = function(ul, items) { var self = this; //table definitions ul.append("<table><thead><tr><th>ID#</th><th>Name</th><th>Cool&nbsp;Points</th></tr></thead><tbody></tbody></table>"); $.each( items, function( index, item ) { self._renderItemData(ul, ul.find("table tbody"), item ); }); }; $.ui.autocomplete.prototype._renderItemData = function(ul,table, item) { return this._renderItem( table, item ).data( "ui-autocomplete-item", item ); }; $.ui.autocomplete.prototype._renderItem = function(table, item) { return $( "<tr class='ui-menu-item' role='presentation'></tr>" ) //.data( "item.autocomplete", item ) .append( "<td >"+item.id+"</td>"+"<td>"+item.value+"</td>"+"<td>"+item.cp+"</td>" ) .appendTo( table ); }; //random json values var projects = [ {id:1,value:"Thomas",cp:134}, {id:65,value:"Richard",cp:1743}, {id:235,value:"Harold",cp:7342}, {id:78,value:"Santa Maria",cp:787}, {id:75,value:"Gunner",cp:788}, {id:124,value:"Shad",cp:124}, {id:1233,value:"Aziz",cp:3544}, {id:244,value:"Buet",cp:7847} ]; $( "#project" ).autocomplete({ minLength: 1, source: projects, focus: function( event, ui ) { if (ui.item != undefined) { console.log(ui.item.value); $( "#project" ).val( ui.item.value ); $( "#project-id" ).val( ui.item.id ); $( "#project-description" ).html( ui.item.cp ); } return false; }//you can write for select too /*select:*/ }) }); 
0
source

Update: one day after I found the plugin 10,000 times better for my project context. Select2 , check the example of loading the downloaded data.

Original answer:

I updated the previous samples to use current jQuery versions:

JS Fiddle example with jQuery 2.1.4 and jQuery UI 1.11.4

In addition, I modified this autocomplete to use it as a custom widget and included support for keyboard navigation.

the code:

 $.widget('custom.tableAutocomplete', $.ui.autocomplete, { options: { open: function (event, ui) { // Hack to prevent a 'menufocus' error when doing sequential searches using only the keyboard $('.ui-autocomplete .ui-menu-item:first').trigger('mouseover'); }, focus: function (event, ui) { event.preventDefault(); } }, _create: function () { this._super(); // Using a table makes the autocomplete forget how to menu. // With this we can skip the header row and navigate again via keyboard. this.widget().menu("option", "items", ".ui-menu-item"); }, _renderMenu: function (ul, items) { var self = this; var $table = $('<table class="table-autocomplete">'), $thead = $('<thead>'), $headerRow = $('<tr>'), $tbody = $('<tbody>'); $.each(self.options.columns, function (index, columnMapping) { $('<th>').text(columnMapping.title).appendTo($headerRow); }); $thead.append($headerRow); $table.append($thead); $table.append($tbody); ul.html($table); $.each(items, function (index, item) { self._renderItemData(ul, ul.find("table tbody"), item); }); }, _renderItemData: function (ul, table, item) { return this._renderItem(table, item).data("ui-autocomplete-item", item); }, _renderItem: function (table, item) { var self = this; var $tr = $('<tr class="ui-menu-item" role="presentation">'); $.each(self.options.columns, function (index, columnMapping) { var cellContent = !item[columnMapping.field] ? '' : item[columnMapping.field]; $('<td>').text(cellContent).appendTo($tr); }); return $tr.appendTo(table); } }); $(function () { var result_sample = [{ "id": 26, "value": "Ladislau Santos Jr.", "email": " klber_moraes@email.net ", "address": "9867 Robert St" }, { "id": 14, "value": "Pablo Santos", "email": " pablo@xpto.org ", "address": "7540 Moreira Ponte" }, { "id": 13, "value": "Souza, Nogueira e Santos", "email": null, "address": "3504 Melo Marginal" }]; $('input#search_field').tableAutocomplete({ source: result_sample, columns: [{ field: 'value', title: 'Name' }, { field: 'email', title: 'E-mail' }, { field: 'address', title: 'Address' }], delay: 500, select: function (event, ui) { if (ui.item != undefined) { $(this).val(ui.item.value); $('#selected_id').val(ui.item.id); } return false; } }); }); 
0
source

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


All Articles