Пользовательский интерфейс jQuery — автоматическое завершение — динамически устанавливается на основе содержимого

#jquery #jquery-ui #jquery-ui-autocomplete

#jquery #jquery-пользовательский интерфейс #jquery-пользовательский интерфейс-автозаполнение

Вопрос:

Есть ли способ динамически устанавливать ширину объекта автозаполнения на основе длины возвращаемого ему текста?

Спасибо

Ответ №1:

Это потребовало немного усилий, но я считаю, что у меня есть разумное решение. В первую очередь для этого требуется привязка к событию «открыть» виджета автозаполнения, чтобы изменить поведение меню по умолчанию при его отображении, а также изменить несколько атрибутов CSS, чтобы помочь нам.

Метод поставляется с одним предостережением: это приведет к тому, что фоновые полосы будут занимать только длину текста, а не все меню в IE7. Он будет нормально функционировать в IE8 , а также во всех других основных браузерах. Я бы посоветовал вам не рассматривать это как проблему, поскольку вы бы адаптировали свое решение к визуальному несоответствию менее чем для 3% рынка и, вероятно, даже для меньшей части вашей реальной аудитории.

CSS

 .ui-autocomplete {
    max-height: 200px;
    overflow-y: auto;
    overflow-x: hidden;
}

.ui-autocomplete .ui-menu-item a {
    padding-right: 20px;
}
  

Добавьте эти стили в свой проект, чтобы помочь с визуальным отображением. Стили .ui-autocomplete довольно стандартны для создания прокручиваемого списка пунктов меню, и вы, вероятно, уже используете его. Правильное заполнение, применяемое к привязке, должно обеспечивать надлежащее пространство для полосы прокрутки в браузерах Firefox и Webkit. Это работает лучше, чем применять его непосредственно к контейнеру UL.

jQuery

 $(".myAutoComplete").autocomplete({
    ...
    open: function(e, ui) {
        $("ul.ui-autocomplete:visible").css("width", "").find("a").html(function(i, html) {
            return html.replace(/s/g, "amp;nbsp;");
        });
    }
    ...
});
  

Обработчик, привязанный к событию open, в основном очевиден в том, что он делает. Во-первых, используемый им селектор ищет единственное видимое меню автозаполнения. К счастью, событие open вызывается только после отображения меню автозаполнения. Это поможет вашему обработчику направить свое внимание в случае, если у вас на странице более одного виджета автозаполнения. Оттуда он удаляет атрибут «width», который применяется непосредственно к CSS неупорядоченного списка. Затем он находит всех потомков привязки в списке и выполняет глобальную замену всех пробелов в своем HTML на неразрывные пробелы. nbsp заставляет привязку реагировать увеличением ее ширины, а не переносом текста на новую строку, тем самым увеличивая ширину всего меню.

Вы можете посмотреть рабочую демонстрацию здесь. Я бы предложил ввести «ab», за которым следует «deep», чтобы увидеть различия в изменении размера по мере их возникновения. Извините за длинный список цветов (сорс) в коде, но я хотел дать вам возможность получить хороший набор возможных предложений для просмотра различий в изменении размера.

Редактировать

Не знаю, о чем я тогда думал, но гораздо более простым подходом было бы предоставить следующий дополнительный стиль и отключить обработчик событий open:

 .ui-autocomplete .ui-menu-item a {
    white-space: nowrap;
}
  

Комментарии:

1. Хитрый план, но в итоге я просто установил ширину на $(e.target).outerWidth() вместо метода amp;nbsp.

2. Оглядываясь назад, переопределение стиля CSS с помощью white-space set to nowrap , вероятно, сделало бы это.

Ответ №2:

В CSS убедитесь, что ширина установлена на auto :

 .ui-autocomplete {
    height: 250px;
    max-height: 250px;
    overflow-y: auto;
    /* prevent horizontal scrollbar */
    width:auto;
}
  

Там, где виджет автозаполнения создает элементы списка, установите стиль пробела li на nowrap :

 input.data( "autocomplete" )._renderItem = function( ul, item ) {
    return $( "<li style='white-space:nowrap;'></li>" )
        .data( "item.autocomplete", item )
        .append( "<a>"   item.label   "</a>" )
        .appendTo( ul );
};