Displaying JQuery UI autocomplete as a table

旧街凉风 提交于 2021-01-21 07:51:13

问题


I am using JQuery UI's autocomplete. I have a number of values, as well as a small collection of keywords, one of which is assigned to each value. I would like to display each pair in a mini-table, with the keyword in one cell and the value in the other. To do this, I am overwriting _renderItem, as mentioned in the documentation. However, when I do this, clicking on a value (or a keyword) doesn't actually do anything, so I cannot select any values. I suspect it has something to do with data("item.autocomplete", item) not being in the right place. Or maybe I need to overwrite some other function higher up (_renderMenuor _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 );
};

回答1:


I think this can help you,here is the 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 out this fiddle




回答2:


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

You have to stick to using <li> elements and are able only to customize the markup within the <li>, inserting your table element within it.

But I would personnaly not use a table to do that. Can't you simply use span elements ?




回答3:


Update: one day after i found a plugin 10000 times better for my project context. Select2, check the "loading remote data" example.

Original answer:

I upgraded the previous samples to use the current jQuery versions:

JS Fiddle example with jQuery 2.1.4 and jQuery UI 1.11.4

Also, i changed this autocomplete to use as a custom widget and included support for keyboard navigation.

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;
    }
});
});



回答4:


Nice example given in the Fiddle.

However after the latest versions upgrade of jQuery and jQuery UI that's just simply stopped working. Not absolutely, however jQuery UI now returning an error on menufocus, which is quite 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:*/
})
});


来源:https://stackoverflow.com/questions/8432204/displaying-jquery-ui-autocomplete-as-a-table

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!