Jquery UI自动完成自定义HTML(项目未定义)

时间:2011-02-05 17:03:10

标签: javascript jquery jquery-ui autocomplete jquery-ui-autocomplete

我一直在试图让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错误(项目未定义)。

有任何想法或建议吗?我已经尝试了一切。

1 个答案:

答案 0 :(得分:12)

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

在深入研究jQueryUI自动完成源之后,看起来自动完成小部件使用的底层菜单对嵌套元素不太友好。

我可能错了,但我认为菜单需要一个简单的<ul>,只有子<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内嵌套li。如果您出于某种原因无法更改生成菜单的HTML,请告诉我。

我已更新示例:http://jsfiddle.net/andrewwhitaker/pjs7a/2/

希望有所帮助。