Пользовательский интерфейс jQuery Autocomplete - PullRequest
4 голосов
/ 20 декабря 2011

Я использую jQuery UI Autocomplete с результатами поиска по категориям, и я хочу оживить его с помощью CSS.

К сожалению, пользовательский интерфейс jQuery не облегчает работу, и с разметкой по умолчанию действительно трудно работать:

<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 part вообще не работает.

Может ли кто-нибудь помочь мне с этим?

Я уверен, что есть более простой способ изменить разметку по умолчанию и заставить ее работать просто отлично.

Я хочу, чтобы это выглядело так:

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

Ответы [ 2 ]

4 голосов
/ 23 декабря 2011

В конце концов я нашел решение самостоятельно, и оно включает в себя некоторые хитрости 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');
    }    
});

В основномЯ играю с абсолютным позиционированием для размещения названия категории слева и добавляю класс к первому элементу LI с помощью jQuery, чтобы создать некоторый интервал с PADDING.

Это не идеально, но работает безупречно :)

1 голос
/ 21 декабря 2011

Вы можете решить эту проблему, не изменяя HTML с небольшим хитростью CSS:

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), но это работает.

Кстати: единственный допустимый дочерний элемент ul - это li. Так что span тоже не поможет.

...