Подтвердить что ты не робот

JQueryUI autocomplete не работает с диалогом и zIndex

Я столкнулся с интересной проблемой с автозаполнением 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 в диалоговом окне намного больше, чем дает меню автозаполнения, но я точно не знаю. Я все еще изучаю точные детали того, что происходит, но я надеюсь, что у кого-то здесь будет какая-то идея для меня.

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

Ответ 3

Параметр "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);
        }
    }
});

Ответ 4

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

Чтобы исправить это: убедитесь, что элемент автозаполнения находится в правильном порядке DOM: autocomplete.insertAfter(dialog.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

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

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

Ответ 6

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

$("#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")

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

Ответ 7

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

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

$("#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-index списка автозаполнения.

Ответ 8

  • Создайте диалог
  • Активировать автозаполнение

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

Ответ 9

Эта ссылка работала для меня.

https://github.com/taitems/Aristo-jQuery-UI-Theme/issues/39

Используем jquery-ui-1.10.3.

Я сконфигурировал поле со списком автозаполнения внутри "открытого" события в диалоговом окне jquery.

Ответ 10

Пробовал все, что упоминалось здесь (некоторые проваливались всякий раз, когда я наводил курсор на элементы и возвращался снова), но это единственная вещь, которая работала для меня во всех случаях:

$("selector").autocomplete({
    ...
    appendTo: "body",    // <-- do this
    close: function (event, ui){
        $(this).autocomplete("option","appendTo","body");  // <-- and do this  
    }
});    

Ответ 11

user1357172 решение работало для меня, но, на мой взгляд, ему нужны два недостатка.

Если 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);
        }
    }
});

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

Ответ 12

То, что сработало для меня, было комбинацией поста выше. Я добавил идентификатор myModal вместо тела и добавил событие закрытия.

$("selector").autocomplete({
    ...
    appendTo: "#myModalId",    // <-- do this
    close: function (event, ui){
        $(this).autocomplete("option","appendTo","#myModalId");  // <-- and do this  
    }
}); 

Ответ 13

open:function(event){

        var target = $(event.target); 
        var widget = target.autocomplete("widget");
        widget.zIndex(target.zIndex() + 1); 

},