Изменение ширины виджетов автозаполнения jquery-ui по отдельности

Я работаю с несколькими виджетами автозаполнения jquery-ui на одной странице и хочу иметь возможность устанавливать ширину каждого из них по отдельности. В настоящее время я делаю это так:

$($('.ui-autocomplete')[0]).width(150);
$($('.ui-autocomplete')[1]).width(105);
$($('.ui-autocomplete')[2]).width(80);

Что на самом деле не является решением, поскольку пользователь может запускать различные автозаполнения в разном порядке, а этот код просто стилизует их в зависимости от порядка добавления в DOM.

Когда запускается автозаполнение, кажется, что создается <ul>, а затем помещается под поле ввода, которое его запустило. К сожалению, я не могу найти какие-либо уникальные идентификаторы в этом сгенерированном <ul>, чтобы зафиксировать и применить некоторые CSS.

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

Кроме того, копание в автозаполнении <ul> и сопоставление различной ширины поля автозаполнения со значениями внутри списка также не работает, поскольку значения генерируются динамически.

Есть идеи?


person CamelBlues    schedule 05.01.2011    source источник


Ответы (11)


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

$('#input').autocomplete({  
    source: mysource,  
    appendTo: '#div',  
    open: function() { $('#div .ui-menu').width(300) }  
});
person rkever    schedule 19.04.2011
comment
Вау, это просто отличное решение. - person CamelBlues; 20.04.2011
comment
Регистрация в 2014 году – это по-прежнему потрясающее решение. - person notaceo; 17.01.2014
comment
Обратите внимание, #div — это элемент на странице: appendTo: '#div' - person Dan; 22.05.2014
comment
это не сработало для меня; неясно, что такое #div по отношению к исходному #input - ответ @Martin Lögdberg сработал для меня - person wal; 13.06.2014
comment
@wal, что #div - это еще один элемент (желательно пустой и рядом с этим #input), внутри которого будет размещено пользовательское меню. Это также не сработало для меня, поэтому я нашел другой способ исключительно с CSS . - person Armfoot; 07.12.2015
comment
Мне также нужно было установить ширину динамически (просто добавив несколько пикселей), и тогда .width() у меня не получилось, но .outerWidth() сделал именно то, что нужно. Может быть, я неправильно понимаю разницу между этими двумя методами, а может быть, я не один такой. ;) - person Kout; 24.04.2016

Мне нравится ответ Луки. Но если вы находитесь в ситуации, когда вы не можете использовать функцию appendTo (может быть из-за скрытого переполнения и т. д.), вы можете использовать приведенный ниже код, чтобы убедиться, что вы вносите изменения в правильный список.

$('#input').autocomplete({  
    source: mysource,  
    open: function() { 
        $('#input').autocomplete("widget").width(300) 
    }  
});

Ссылка: http://docs.jquery.com/UI/Autocomplete#method-widget

person Martin Lögdberg    schedule 22.05.2011

Если у вас есть несколько элементов управления, использующих автозаполнение, достаточно элегантным решением будет получить widget. прикрепить к элементу управления в последний момент и изменить его CSS:

$(document).ready(function() {
    $("input#Foo").autocomplete({
        source: source
    });
    $("input#Bar").autocomplete({
        source: source,
        open: function(event, ui) {
            $(this).autocomplete("widget").css({
                "width": 400
            });
        }
    });
});

Просмотрите демонстрацию.

Как упоминалось выше, ширина списка автозаполнения рассчитывается в самый последний момент, поэтому вы должны изменить его в open событие.

person Salman A    schedule 25.05.2011
comment
$(this).autocomplete('widget').width(300); на открытом методе у меня работает нормально =), большое спасибо. - person overallduka; 28.10.2014

Вы можете получить виджет «UI-меню», прикрепленный к <input> с автозаполнением в отношении $('#myinput').data("autocomplete").menu. Итак, чтобы изменить ширину, вы можете использовать

$('#myinput').autocomplete({
    source: yourUrlOrOtherSource,
    open: function () {
        $(this).data("autocomplete").menu.element.width(80);
    }
});
person Oleg    schedule 07.08.2011

Вы можете обернуть поле ввода, которое запускает автозаполнение, в div, дать div определенный идентификатор, а затем добавить автозаполнение ul к этому div, а не к телу документа. Таким образом, вы можете нацелить его с помощью css на основе div.

<!- this is how i would set up the div -->
<div class='autoSuggestWrapper' id='wrapper1'>
     <input class='autocomplete'>
</div>
<script>/* this is a way to config the autocomplete*/
   $( ".autocomplete" ).autocomplete({ appendTo: ".autoSuggestWrapper" });
</script> 
person scrappedcola    schedule 05.01.2011
comment
Это, кажется, не имеет большого эффекта. Автозаполнение по-прежнему отображается за пределами родительского элемента. - person CamelBlues; 06.01.2011
comment
Как у вас настроен html вокруг ввода и как вы инициализируете автозаполнение? - person scrappedcola; 06.01.2011
comment
‹span class=wrapper›‹input class=autocomplete1/›‹/span› И я инициализирую автозаполнение через функцию-оболочку. Функция не вызывается при загрузке страницы, но я не уверен, что это как-то повлияет на стиль. - person CamelBlues; 07.01.2011
comment
Попробуйте обернуть его в div, а не в ‹span›. Затем попробуйте appendTo в конфигурации выше. Я почти уверен, что вы не можете добавить ul внутри диапазона, и, вероятно, поэтому код appendTo не работает. Кроме того, вы захотите добавить идентификатор к каждой из оболочек, чтобы вы могли указать, какая из них получает какую ширину. - person scrappedcola; 08.01.2011

Без использования дополнительного кода Javascript вы можете использовать 1 простую строку CSS:

<style type="text/css">
    .ui-menu,.ui-menu>.ui-menu-item,.ui-menu-item>a {min-width:800px !important}
</style>

Так почему же это работает с min-width?

Просто потому, что width перезаписывается JS, иногда даже с решениями, использующими open: function(event, ui) { ... } (например, ответ rkever, который не работал в мое дело). Однако min-width не перезаписывается, так что это удобно.

Кроме того, если вы не хотите использовать !important, вы можете уточнить правило с остальными классами:

.ui-autocomplete.ui-menu.ui-widget.ui-widget-content.ui-corner-all,.ui-menu>.ui-menu-item,.ui-menu-item>a
 {min-width:800px}

Это избавило меня от дальнейших взломов JS, надеюсь, это поможет!

person Armfoot    schedule 07.12.2015
comment
идеальный ответ ... тесто, чтобы использовать это вместо кода JS - person Sumit Kumar; 13.04.2016

Мне нравится ответ @Martin Lögdberg, но если вы используете ширину фиксированного размера, а не выполняете какие-то причудливые вычисления с возвращаемыми результатами, чтобы установить ширину, вы также можете просто установить ширину в CSS

ul .ui-autocomplete {
  width: 50%;
}
person ants    schedule 22.08.2012

Улучшение ответа Мартина Лёгдберга. Это сработало лучше для меня, потому что у меня было много текстовых полей на странице.

$('.some-class').each(function(){
   var txt = $(this);
   txt.autocomplete({  
      source: mysource,  
      open: function() { 
          txt.autocomplete("widget").width(txt.outerWidth());
      }
   });  
});
person Ben Anderson    schedule 01.05.2014

Читая API, я только что добавил класс ui-front в родительский div моего ввода, и это работает нормально.

<div class="ui-front">
    <label for="autosample" class="required">example</label>
    <input name="autosample" class="default-autocomplete" type="text">
</div>

См. здесь:

[...] родители поля ввода будут проверены на наличие класса ui-front. Если элемент с классом ui-front найден, меню будет добавлено к этому элементу. Независимо от значения, если элемент не найден, меню будет добавлено к телу.

Добавленный элемент определяет позицию и ширину меню.

person Le Moineau    schedule 10.01.2015

Начиная с jQuery UI 1.10, виджет автозаполнения был переписан с использованием фабрики виджетов. В рамках этого автозаполнение теперь содержит точку расширения _resizeMenu, которая вызывается при масштабирование меню перед отображением.

$('#input').autocomplete({  
    source: mysource,  
    appendTo: '#div',  
    _resizeMenu: function() {
        this.menu.element.outerWidth( 500 );
    }
});
person saluce    schedule 05.11.2015

Мне удалось решить эту проблему с помощью CSS, добавив float в меню автозаполнения.

.ui-autocomplete { float: left; }

Поскольку меню автозаполнения расположено absolute и является прямым дочерним элементом <body>. Я предполагаю, что он получает максимальную ширину от тела, и, поскольку его позиция абсолютна, он не может отображаться как встроенный блок, чтобы не занимать все доступное пространство.

Также .ui-autocomplete { width: 1%; }, кажется, работает.

person Trevald    schedule 08.11.2016