I am using a jquery autocomplete with combobox nabled. I want to show an empty option h开发者_如何学Cowever whenever I set the value of my initial selection to an empty string it is not shown in the combobox.
The item is present it just contains no height.
Is it possible to have a blank option on an autocomplete combobox ?
The two solutions posted here did not work for me. _renderItem is not even called for empty options.
Here is what worked for me: I made a very small edit to the function that maps Select options to autocomplete items.
response(select.children("option").map(function () {
var text = $(this).text();
if (/*this.value && */(!request.term || matcher.test(text)))
return {
label: text.replace(
new RegExp(
"(?![^&;]+;)(?!<[^<>]*)(" +
$.ui.autocomplete.escapeRegex(request.term) +
")(?![^<>]*>)(?![^&;]+;)", "gi"
), "<strong>$1</strong>"),
value: text,
option: this
};
}));
All what I did is commenting part of the condition.
/*this.value && */
Then I added to my stylesheet a rule for the autocomplete items.
.ui-autocomplete .ui-menu-item a
{
min-height: 15px;
}
I had the same problem, solved it like this:
$autocomplete.data("autocomplete")._renderItem = function(ul, item) {
return $j( "<li></li>" )
.data( "item.autocomplete", item )
.append(item.label === '' ? '<a> </a>' : "<a>" + item.label + "</a>" )
.appendTo(ul);
}
When item label is empty (item.label === ''
) I just add a link containing a nonbreaking space (
) instead of the label.
EDIT:
I realized this might introduce an XSS vulnerability. Make sure you escape the item label if it could contain user input. Either use some escape function, for example underscore.js's escape function:
"<a>" + _.escape(item.label) + "</a>"
or build the anchor element using jQuery like this:
$('<a/>').text(item.label)
$("#ctrl").autocomplete({
source: [ "\u00A0", "One", "Two" ]
});
So we figured out the solution. You need to work with the _renderItem
method.
input.data("autocomplete")._renderItem = function(ul, item) {
var listItem;
if (item.label == "<strong></strong>") {
listItem = $("<li></li>")
.data("item.autocomplete", item)
.append("<a><br></a>")
.appendTo(ul);
} else {
listItem = $("<li></li>")
.data("item.autocomplete", item)
.append("<a>" + item.label + "</a>")
.appendTo(ul);
}
return listItem;
};
Take note that you must have a blank string item in your initial list for this to work.
I had this issue recently and while other solutions were mostly correct I found there was a step missing.
if (this.value && (!request.term || matcher.test(text)))
needs to be changed to
if (!request.term || matcher.test(text))
otherwise there will be no empty items in the source.
As with the other solutions, change _renderItem to
input.data('autocomplete')._renderItem = function(ul, item) {
return $('<li></li>')
.data('item.autocomplete', item)
.append(item.label === '<strong></strong>' ? '<a> </a>' : '<a>' + item.label + '</a>' )
.appendTo(ul);
}
This is a mix of BentOnCoding's and Tim Büthe's solution
You can extend the autocomplete widget like this:
$.widget( "ui.autocomplete", $.ui.autocomplete, {
_renderMenu: function (ul, items) {
var that = this;
// add a blank item
if (this.options.blankItem) {
var blank = [{
id: "",
label: "<none>",
value: ""
}];
items = blank.concat(items);
}
$.each(items, function (index, item) {
var rendered = that._renderItemData(ul, item);
// ensure min height on blank item. hmm, maybe a class would be better...
if (index === 0 && that.options.blankItem) {
$(rendered).find('div').css('minHeight', '30px');
}
});
}
});
And then use it like this:
$( "#textbox" ).autocomplete({
source: contactNames,
blankItem: true
})
Here's a Fiddle for that.
If you prefer not to extend the widget for some reason, you can add the function to the change
method like this:
$( "#textbox" ).autocomplete({
create: function(){
$(this).data('ui-autocomplete')._renderMenu = function( ul, items ) {
[ _renderMenu function contents... ]
}
}
})
精彩评论