如何在jQuery自动完成中显示一个空白选项?

9
我正在使用带有组合框的jquery自动完成功能。我想显示一个空选项,但是每当我将我的初始选择的值设置为空字符串时,它不会显示在组合框中。
该项目存在,但它没有高度。
是否可能在自动完成组合框上有一个空选项?

1
你是否尝试在获取建议后,将'<li></li>'追加到建议列表顶部?你可以在“open”事件中插入它。 - orolo
2
这不起作用,因为组合框在没有实际内容的情况下会将行高减少到零。 - BentOnCoding
6个回答

6

我曾经遇到过同样的问题,我是这样解决的:

$autocomplete.data("autocomplete")._renderItem = function(ul, item) {
    return $j( "<li></li>" )
        .data( "item.autocomplete", item )
        .append(item.label === '' ? '<a>&nbsp;</a>' : "<a>" + item.label + "</a>" )
        .appendTo(ul);
}

当项目标签为空 (item.label === '') 时,我会添加一个包含非打断空格 (&nbsp;) 的链接,而不是标签。
编辑:
我意识到这可能会引入XSS漏洞。如果项目标签可能包含用户输入,请确保对其进行转义。可以使用一些转义函数,例如 underscore.js的转义函数
"<a>" + _.escape(item.label) + "</a>"

您可以使用jQuery构建锚点元素,如下所示:

或者使用以下代码:

$('<a/>').text(item.label)

这对我有用。但是,我必须使用 ui-autocomplete 来处理数据项。 - scott.korin

6
这里发布的两个解决方案对我没有用。 对于空选项,_renderItem甚至都不被调用。
下面是适用于我的解决方案:我对将Select选项映射到自动完成项的函数进行了非常小的编辑。
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
    };
}));

我所做的就是注释掉了部分条件。
/*this.value && */

然后我在我的样式表中添加了一个自动完成项目的规则。

.ui-autocomplete .ui-menu-item a
{
    min-height: 15px;
}

4

所以我们找到了解决方案。您需要使用_renderItem方法进行工作。

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

请注意,在进行此操作之前,您必须在初始列表中添加一个空字符串项才能使其正常工作。

4
$("#ctrl").autocomplete({
    source: [ "\u00A0", "One", "Two" ]
});

我喜欢这个解决方案,非常容易设置。干杯! - asgeo1

1

最近我遇到了这个问题,虽然其他解决方案大多是正确的,但我发现还缺少一步。

if (this.value && (!request.term || matcher.test(text)))

需要更改为

if (!request.term || matcher.test(text))

否则,源中将没有空项。
与其他解决方案一样,将_renderItem更改为
input.data('autocomplete')._renderItem = function(ul, item) {
        return $('<li></li>')
            .data('item.autocomplete', item)
            .append(item.label === '<strong></strong>' ? '<a>&nbsp;</a>' : '<a>' + item.label + '</a>' )
            .appendTo(ul);
        }    

这是BentOnCoding和Tim Büthe方案的混合。


0
您可以像这样扩展自动完成小部件:
$.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');
            }
        });
    }
});

然后像这样使用它:

$( "#textbox" ).autocomplete({
        source: contactNames,
        blankItem: true
    })

这里有一个Fiddle

如果您因某种原因不想扩展小部件,您可以像这样将函数添加到change方法中:

$( "#textbox" ).autocomplete({
    create: function(){
        $(this).data('ui-autocomplete')._renderMenu = function( ul, items ) {
            [ _renderMenu function contents... ]
        }
    }
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接