2011-12-31 1 views
32

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

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

ответ

60

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

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

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

+1

Это сработало отлично! Благодаря! –

+21

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

+0

работает как шарм! Спасибо большое! – frabiacca

5

я помню, чтобы подобный вопрос с автозаполнения и ZIndex, и должен был зафиксировать его с помощью опции appendTo: $(selector).autocomplete({appendTo: "#copy_dialog"})

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

+0

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

2

С помощью этой проблемы я обнаружил, что 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") 

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

9

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

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

Пример

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-индекс после диалогового мыши

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

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

// initialize autocomplete 
input.autocomplete({ 
    source: ..., 
    open: function() { 
     autoComplete.zIndex(dlg.zIndex()+1); 
    } 
}); 
+0

Спасибо за обновление этого. Работает как шарм. Последующие проблемы выходят (http://stackoverflow.com/questions/17242943/jquery-autocomplete-with-dialog-updating-value), но это было именно то, что мне нужно. – Tom

+0

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

+0

Вы должны вызывать 'autoComplete.insertAfter (dlg.parent());' каждый раз, когда вы показываете диалог. – mhu

0

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

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

Am с помощью JQuery-UI-1.10.3.

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

24

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

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

+1

Старый поток. Запоздалый ответ. Работал отлично для меня ... Я благодарю вас. – TimSPQR

+0

Поздний отклик :-P .... добро пожаловать! –

+1

Это должен быть принятый ответ –

1

Изменение 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) 
    }); 
}); 

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

13

Опция '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); 
     } 
    } 
}); 
+0

Поскольку диалог всегда обновляет свой z-индекс, для меня это правильный ответ. –

0

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

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

user1357172-х solution работал для меня, но на мой взгляд, нуждается в двух imprevements.

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

BTW это решение работает, но это выглядит немного Hacky, так что это, вероятно, не самый лучший.

0

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

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

Знаете ли вы, почему вам нужно добавить опцию appendTo в теге закрытия? – catorda

0
open:function(event){ 

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

}, 
+0

Пожалуйста, обратитесь к дополнительной информации. Только код и «попробуйте» ответы не приветствуются, поскольку они не содержат содержимого, доступного для поиска, и не объясняют, почему кто-то должен «попробовать это». Мы прилагаем усилия, чтобы стать источником знаний. –

1
  1. Создать диалог
  2. Активировать автозаполнения

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

0

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

.ui-autocomplete { 
z-index: 2000; 
}