6

我一直在努力让 jQuery UI Autocomplete 输出自定义 HTML。这是我的代码。

        $(document).ready(function(){

        $.widget( "custom.catcomplete", $.ui.autocomplete, {
            _renderMenu: function( ul, items ) {
                var self = this,
                    currentCategory = "";
                $.each( items, function( index, item ) {
                    if ( item.category != currentCategory ) {
                        ul.append( "<li class='ui-autocomplete-category'>" + item.category + "<ul class='autocomplete-category'></ul></li>" );
                        currentCategory = item.category;
                    }
                    self._renderItem( ul, item);
                });
            }
        });

        var data = [
            { label: "anders", category: "Antigen" },
            { label: "andreas", category: "Antigen" },
            { label: "antal", category: "Antigen" },
            { label: "annhhx10", category: "Products" },
            { label: "annk K12", category: "Products" },
            { label: "annttop C13", category: "Products" },
            { label: "anders andersson", category: "People" },
            { label: "andreas andersson", category: "People" },
            { label: "andreas johnson", category: "People" }
        ];

        $( "#typeAhead" ).catcomplete({
            delay: 0,
            source: data,
        })
        .data( "catcomplete" )._renderItem = function( ul, item ) {
            return $( "<li></li>" )
                .data( "item.catcomplete", item )
                .append( $( "<a class='ui-menu-item'></a>" ).text( item.label ) )
                .appendTo( $('ul').last('.autocomplete-category'));
        };
    });

通过将列表嵌套在 renderItem 函数中,我似乎遇到了麻烦。HTML 输出正是我想要的。但是,当我“keydown”时,我得到一个 javascript 错误(项目未定义)。

有什么想法或建议吗?我几乎什么都试过了。

4

1 回答 1

12

你快到了!我只进行了两项更改以使其正常工作(在 OP 评论后更新):

深入研究 jQueryUI 自动完成源代码后,自动完成小部件使用的底层菜单似乎对嵌套元素不太友好。

我对此可能是错的,但我认为菜单需要一个简单<ul>的只有 children<li>包含一个锚标签。

编辑:这一行证实了我对菜单的怀疑(在 jqueryUI 1.8.9 的菜单小部件中找到):

    var items = this.element.children("li:not(.ui-menu-item):has(a)")
        .addClass("ui-menu-item")
        .attr("role", "menuitem");

    items.children("a")
        .addClass("ui-corner-all")
        .attr("tabindex", -1)
        // mouseenter doesn't work with event delegation
        .mouseenter(function( event ) {
            self.activate( event, $(this).parent() );
        })
        .mouseleave(function() {
            self.deactivate();
        });

基本上,由于您的a标签被埋在嵌套列表中,因此菜单无法识别它们。

我敢打赌,您在原始代码中注意到,当您将鼠标悬停在自动完成菜单项上时,它们并没有突出显示。这种突出显示实际上与小部件认为哪个菜单项处于活动状态相吻合,这会导致您的小部件在用户选择一个项目时失败。

li由于只给类别一个不同的类在语义上或视觉上没有任何错误,我会像这样重组小部件的菜单:

JavaScript:

_renderItem功能:

.data( "catcomplete" )._renderItem = function( ul, item ) {
    return $( "<li></li>" )
        .data( "item.autocomplete", item )
        .append( $( "<a class='ui-menu-item'></a>" )
                 .text( item.label ) )
        .appendTo(ul);
};

你的_renderMenu功能:

_renderMenu: function( ul, items ) {
    var self = this,
        currentCategory = "";
    $.each( items, function( index, item ) {
        if ( item.category != currentCategory ) {
            ul.append( "<li class='ui-autocomplete-category'>" + item.category + "</li>" );
            currentCategory = item.category;
        }
        self._renderItem( ul, item);
    });
}

为自动完成菜单生成的 HTML:

<ul class="ui-autocomplete>
    <li class="ui-autocomplete-category">Antigen</li>
    <li class="ui-menu-item" role="menuitem">
         <a class="ui-menu-item ui-corner-all" tabindex="-1">anders</a>
    </li>
    <li class="ui-menu-item" role="menuitem">
        <a class="ui-menu-item ui-corner-all" tabindex="-1">andreas</a>
    </li>
    <li class="ui-menu-item" role="menuitem">
        <a class="ui-menu-item ui-corner-all" tabindex="-1">antal</a>
    </li>
    <!-- More categories, items, etc.-->
</ul>

从您的评论来看,您似乎希望菜单的 HTML 嵌套在每个类别ul的 s 内。li让我知道是否出于某种原因无法更改生成菜单的 HTML。

我已经更新了这个例子:http: //jsfiddle.net/andrewwhitaker/pjs7a/2/

希望有帮助。

于 2011-02-05T17:46:08.677 回答