Автозаполнение jQueryUI не работает с диалогом и zIndex - PullRequest
37 голосов
/ 31 декабря 2011

Я столкнулся с интересной проблемой с автозаполнением jQueryUI в диалоговом окне.

Мой диалог HTML выглядит так:

<div id="copy_dialog">
    <table>
        <tbody>
            <tr>
                <th>Title:</th>
                <td><input type="text" class="title" name="title"></td>
            </tr>
            <tr>
                <th>Number:</th>
                <td><input type="text" name="number"></td>
            </tr>
        </tbody>
    </table>
</div>

Когда я запускаю автозаполнение jQueryUI в приведенном выше HTML, оно отлично работает.

Когда я открываю его с помощью диалога

$('#copy').click(function()
{
    $('#copy_dialog').dialog({
        autoOpen: true,
        width: 500,
        modal: false,
        zIndex: 10000000,
        title: 'Duplicate',
        buttons: {
            'Cancel': function()
            {
                $(this).dialog('close');
            },
            'Save': function()
            {
                $(this).dialog('close');
            }
        }
    });

    return false;
});

Тогда в FireBug я вижу, что автозаполнение все еще работает. Он запрашивает и получает результаты, но я больше не вижу список опций под полем ввода.

Я думаю, что это как-то связано с тем, что zIndex в диалоговом окне намного больше, чем дает меню автозаполнения, но я точно не знаю. Я все еще исследую точные детали того, что происходит, но я надеюсь, что кто-то здесь будет иметь некоторую идею для меня.

Редактировать Я попытался удалить zIndex из диалогового окна, и мое автозаполнение начинает появляться. К сожалению, мне нужно это значение zIndex, чтобы преодолеть ужасно высокое значение zIndex в строке меню, которое я не могу изменить (у меня нет доступа к этой области кода). Так что, если есть способ добавить zIndex к автозаполнению, это было бы замечательно; до тех пор я, вероятно, просто удаляю zIndex из диалогового окна и проверяю, не отображается ли он вокруг области меню.

Ответы [ 14 ]

67 голосов
/ 31 декабря 2011

Попробуйте установить для параметра appendTo значение "#copy_dialog":

$(/** autocomplete-selector **/)
    .autocomplete("option", "appendTo", "#copy_dialog");

Этот параметр указывает, к какому элементу добавляется меню автозаполнения.Добавляя меню в диалог, меню должно наследовать правильный z-индекс.

26 голосов
/ 05 сентября 2013

appendTo: К какому элементу следует добавить меню.Когда значение равно нулю, родители поля ввода будут проверены на наличие класса «ui-front».Если найден элемент с классом «ui-front», к этому элементу будет добавлено меню.Независимо от значения, если элемент не найден, меню будет добавлено к телу.

Это означает, что <div id="copy_dialog" class="ui-front"> сделает свое дело.Нет необходимости использовать опцию appendTo, которая не работает для меня.

15 голосов
/ 31 декабря 2014

Опция 'appendTo' не всегда работает.

Наиболее вопиюще, он не будет отображаться выше высоты диалога, но также, если вы используете стороннюю утилиту (например, редактор DataTables), вы не всегда можете контролировать, когда диалог, вход,и т. д. создаются, когда они присоединены к DOM, какие у них идентификаторы и т. д.

Кажется, что всегда работа:

$(selector).autocomplete({
    open: function(event, ui){
        var dialog = $(this).closest('.ui-dialog');
        if(dialog.length > 0){
            $('.ui-autocomplete.ui-front').zIndex(dialog.zIndex()+1);
        }
    }
});
10 голосов
/ 19 июня 2013

При использовании jQuery UI 1.10 не следует возиться с z-индексами (http://jqueryui.com/upgrade-guide/1.10/#removed-stack-option). Опция appendTo работает, но ограничивает отображение до высоты диалога.

Чтобы исправить это: убедитесь, что элемент автозаполнения находится в правильном порядке DOM с помощью: автозаполнение .insertAfter ( диалог .parent ())

Пример

 var autoComplete,
     dlg = $("#copy_dialog"),
     input = $(".title", dlg);

 // initialize autocomplete
 input.autocomplete({
     ...
 });

 // get reference to autocomplete element
 autoComplete = input.autocomplete("widget");

 // init the dialog containing the input field
 dlg.dialog({
      ...
 });

 // move the autocomplete element after the dialog in the DOM
 autoComplete.insertAfter(dlg.parent());

Обновление для проблемы z-index после щелчка в диалоге

Z-индекс автозаполнения, кажется, изменяется после щелчка по диалоговому окну (какMatteoC). Обходное решение, описанное ниже, похоже, исправляет это:

См. скрипту: https://jsfiddle.net/sv9L7cnr/

// initialize autocomplete
input.autocomplete({
    source: ...,
    open: function () {
        autoComplete.zIndex(dlg.zIndex()+1);
    }
});
5 голосов
/ 31 декабря 2011

Я помню, что у меня была похожая проблема с автозаполнением и zIndex, и мне пришлось ее исправить, указав опцию appendTo: $(selector).autocomplete({appendTo: "#copy_dialog"})

Это также полезно, если у вас есть автозаполнение внутри позиционированного элемента.Конкретная проблема, с которой я столкнулся, заключалась в автозаполнении внутри элемента с фиксированным положением, который оставался на месте во время прокрутки основного корпуса.Автозаполнение отображалось правильно, но затем прокручивалось вместе с телом, а не оставалось фиксированным.

2 голосов
/ 14 декабря 2012

Изучив эту проблему самостоятельно, я обнаружил, что appendTo должен быть установлен до открытия диалога. То же самое относится и к установке (или изменению) свойства источника.

$("#mycontrol").autocomplete({appendTo:"#myDialog",source:[..some values]})
$("#mycontrol").autocomplete("option","source",[...some different values]) // works

// doesn't work if the lines above come after
$("#myDialog").dialog("open")

Это может быть просто побочным продуктом того, что делает открытое диалоговое окно, или неправильной адресацией элемента. Но порядок вещей, кажется, имеет значение.

1 голос
/ 09 марта 2018

Супер простое решение.Увеличьте z-индекс для автозаполнения.Когда он активен, я уверен, что вы хотите, чтобы он был сверху :)

.ui-autocomplete {
 z-index: 2000;
}
1 голос
/ 12 июля 2016
  1. Создать диалог
  2. Активировать автозаполнение

Этот сигнал указывает на запрос об автозаполнении в диалоговом окне, и он имеет информацию, доступную для обработки z-индексов.

1 голос
/ 09 июня 2015

user1357172's решение сработало для меня, но, по моему мнению, оно требует двух улучшений.

Если appendTo установлено на null, мы можем найти ближайший .ui-front элемент вместоиз .ui-dialog, потому что наш autocomplete должен быть уже прикреплен к нему.Затем мы должны изменить z-index только для связанного виджета (связанного списка ul) вместо изменения всех существующих элементов с классом .ui-autocomplete.ui-front.Мы можем найти связанный виджет, используя elem.autocomplete('widget')

Решение:

elem.autocomplete({
    open: function(event, ui){
        var onTopElem = elem.closest('.ui-front');
        if(onTopElem.length > 0){
            var widget = elem.autocomplete('widget');
            widget.zIndex(onTopElem.zIndex() + 1);
        }
    }
});

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

1 голос
/ 25 июля 2014

Изменение z-индекса работает только при первом открытии раскрывающегося списка, после закрытия диалоговое окно обнаруживает, что оно «обмануто», и обновляет свой z-индекс.

Также для меня изменение порядка создания диалогового окна и автозаполнения действительно было проблемой (например, большой веб-сайт, тонны страниц), но случайно у меня была своя собственная функция openPopup, которая обернула открытое диалоговое окно. Итак, я придумал следующий взломать

$("#dialog").dialog({ focus: function () {
    var dialogIndex = parseInt($(this).parent().css("z-index"), 10);
    $(this).find(".ui-autocomplete-input").each(function (i, obj) {
        $(obj).autocomplete("widget").css("z-index", dialogIndex + 1)
    });
});

Каждый раз, когда диалог имеет фокус, т. Е. При первом открытии и когда автозаполнение закрывается, обновляется z-индекс каждого автозаполнения.

...