jQuery UI自动完成自定义标记

时间:2011-12-19 21:09:22

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

我正在使用带有分类搜索结果的 jQuery UI Autocomplete ,我想用CSS来加强它。

不幸的是,jQuery UI并不容易,默认标记真的难以使用:

<input class="ui-autocomplete-input"/>
<ul class="ui-autocomplete ui-menu ui-widget ui-widget-content ui-corner-all">
  <li class='ui-autocomplete-category'>Category 1</li>
  <li class="ui-menu-item">
      <a class="ui-corner-all">item 1</a>
  </li>
  <li class="ui-menu-item">
      <a class="ui-corner-all">item 2</a>
  </li>
  <li class="ui-menu-item">
      <a class="ui-corner-all">item 3</a>
  </li>
  <li class='ui-autocomplete-category'>Category 2</li>
  <li class="ui-menu-item">
      <a class="ui-corner-all">item 1</a>
  </li>
  <li class="ui-menu-item">
      <a class="ui-corner-all">item 2</a>
  </li>
  <li class="ui-menu-item">
      <a class="ui-corner-all">item 3</a>
  </li>    
</ul>

我想要的标记是:

<input class="ui-autocomplete-input"/>
<ul class="ui-autocomplete ui-catcomplete">
    <div class="ui-block">
        <div class="ui-autocomplete-category">Category 1</div>
        <div class="ui-list">
            <li class="ui-menu-item">
                <a class="ui-corner-all">item 1</a>
            </li>
            <li class="ui-menu-item">
                <a class="ui-corner-all">item 2</a>
            </li>
            <li class="ui-menu-item">
                <a class="ui-corner-all">item 3</a>
            </li>
        </div>
    </div>
    <div class="ui-block">
        <div class="ui-autocomplete-category">Category 1</div>
        <div class="ui-list">
            <li class="ui-menu-item">
                <a class="ui-corner-all">item 1</a>
            </li>
            <li class="ui-menu-item">
                <a class="ui-corner-all">item 2</a>
            </li>
            <li class="ui-menu-item">
                <a class="ui-corner-all">item 3</a>
            </li>
        </div>
    </div>
</ul>

这就是我达到极限的地方。

我实际上设法创建了标记,但是我无法再点击该项目来选择和提交。

以下是我提出的代码:

$.widget( "custom.catcomplete", $.ui.autocomplete, {

    _renderMenu: function( ul, items ) {
        var self = this,
            currentCategory = "",
            i = 0;

        $.each( items, function( index, item ) {
            if ( item.category != currentCategory ) {

                ul.append( "<div class='ui-autocomplete-category'>" + item.category + "</div>");
                currentCategory = item.category;

            }

            self._renderItem( ul, item );
        });

        /* This is how I thought it would work */

        ul.find('.ui-autocomplete-category').each(function() {
            $(this).nextUntil('div')
                    .andSelf()
                    .wrapAll('<div class="ui-block">')
                    .nextUntil('div')
                    .wrapAll('<div class="ui-list">');
        });

    },

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

$(function() {  
    $( "#ui-autocomplete-input" ).catcomplete({
        source: '<?php echo SITEURL?>/users/complete/',
        delay: 0,
        autoFocus: true,
        select: function(event, ui) {
            if(ui.item)
            {
                $('#ui-autocomplete-input').attr('value',ui.item.value);
            }
            $('#ui-autocomplete-form').submit();
        }
    });
});

基本上, select:function 部分根本不起作用。

有人可以帮我吗?

我确信有一种更简单的方法来修改默认标记并使其正常工作。

这就是我想要的样子:

Screenshot of drop-down list with multiple rows and header on left

2 个答案:

答案 0 :(得分:4)

我最终自己找到了解决方案,它涉及一些CSS技巧和一些简单的jQuery。

CSS:

.ui-autocomplete {
    width:424px;
    margin:0;
    padding:0 0 14px 0;
}

.ui-autocomplete-category {
    width:100px;
    position: absolute;
    padding:0 20px;
    margin:20px 0 0 0;
}

.ui-menu-item {
    padding-left:140px;
}

.ui-first {
    padding-top:20px;
}

jQuery的:

$( "#search" ).catcomplete({
    delay: 0,
    source: data,
    autoFocus: true,
    select: function(event, ui) {
        if(ui.item) { $('#search').attr('value',ui.item.value);}
        $('#form').submit();
        },

    /* This is the important part! */

    open: function() {
        $('.ui-autocomplete-category').next('.ui-menu-item').addClass('ui-first');
    }    
});

基本上,我使用绝对定位来将类别名称放在左侧,然后使用jQuery向第一个LI元素添加一个类,以便与PADDING创建一些间距。

它并不完美,但它完美无瑕地运行:)

答案 1 :(得分:1)

你可以解决这个问题,而无需用一点CSS技巧来改变HTML:

ul.ui-autocomplete {
    padding-left: 200px;
}

    ul.ui-autocomplete li.ui-autocomplete-category {
        width: 200px;
        height: 50px;
        margin-left: -200px;
        margin-bottom: -50px;
    }

它并不完美(类别li的高度可能超过结果的高度 - 或者它可能不适合li的内容)但是它有效。

Btw:ul中唯一有效的子元素是li。因此,跨度也无济于事。