web-dev-qa-db-fra.com

La saisie semi-automatique jQueryUI ne fonctionne pas avec les boîtes de dialogue et zIndex

J'ai rencontré un problème intéressant avec la saisie semi-automatique de jQueryUI dans une boîte de dialogue.

Ma boîte de dialogue HTML ressemble à ceci:

<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>

Lorsque j'exécute la saisie semi-automatique jQueryUI sur le code HTML ci-dessus, cela fonctionne parfaitement.

Quand je l'ouvre en utilisant la boîte de dialogue

$('#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;
});

Ensuite, dans FireBug, je peux voir que la saisie semi-automatique fonctionne toujours. Il demande et reçoit des résultats, mais je ne vois plus de liste d'options sous le champ de saisie.

Ma pensée est que cela a quelque chose à voir avec le zIndex dans la boîte de dialogue étant beaucoup plus grand que ce que donne le menu de saisie semi-automatique, mais je ne sais pas avec certitude. Je recherche toujours les détails exacts de ce qui se passe, mais j'espère que quelqu'un ici aura une idée pour moi.

Edit J'ai essayé de supprimer le zIndex de la boîte de dialogue et ma saisie semi-automatique commence à apparaître. Malheureusement, j'ai besoin de cette valeur zIndex pour surmonter le zIndex terriblement élevé de la barre de menu, que je ne peux pas changer (je n'ai pas accès à cette zone du code). Donc, s'il existe un moyen d'ajouter un zIndex à la saisie semi-automatique, ce serait fantastique; jusque-là, je vais probablement supprimer le zIndex de la boîte de dialogue et m'assurer qu'il n'apparaît pas dans la zone de barre de menus.

37
Francis Lewis

Essayez de définir l'option appendTo sur "#copy_dialog":

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

Cette option spécifie à quel élément le menu de saisie semi-automatique est ajouté. En ajoutant le menu à la boîte de dialogue, le menu doit hériter du z-index correct.

67
Xavi

appendTo: À quel élément le menu doit être ajouté. Lorsque la valeur est nulle, les parents du champ de saisie seront vérifiés pour une classe de "ui-front". Si un élément avec la classe "ui-front" est trouvé, le menu sera ajouté à cet élément. Quelle que soit la valeur, si aucun élément n'est trouvé, le menu sera ajouté au corps.

Cela signifie que <div id="copy_dialog" class="ui-front"> fera l'affaire. Pas besoin d'utiliser l'option appendTo, cela ne fonctionnait pas pour moi.

26
arvic.rivera

L'option 'appendTo' ne fonctionne pas toujours.

Plus important encore, il ne s'affichera pas au-delà de la hauteur de la boîte de dialogue, mais aussi, si vous utilisez un utilitaire tiers (par exemple, l'éditeur de DataTables), vous n'avez pas toujours le contrôle sur la création d'une boîte de dialogue, d'une entrée, etc., lorsqu'ils sont attachés au DOM, quels ID ils ont, etc.

Cela semble toujours fonctionner:

$(selector).autocomplete({
    open: function(event, ui){
        var dialog = $(this).closest('.ui-dialog');
        if(dialog.length > 0){
            $('.ui-autocomplete.ui-front').zIndex(dialog.zIndex()+1);
        }
    }
});
15
user1357172

Lorsque vous utilisez jQuery UI 1.10, vous ne devriez pas jouer avec les z-index ( http://jqueryui.com/upgrade-guide/1.10/#removed-stack-option ). L'option appendTo fonctionne, mais limitera l'affichage à la hauteur de la boîte de dialogue.

Pour résoudre ce problème: assurez-vous que l'élément de saisie semi-automatique est dans l'ordre DOM correct avec: autocomplete. InsertAfter ( dialogue. Parent ())

Exemple

 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());

Mise à jour pour un problème d'index z après un clic sur la boîte de dialogue

L'index z de la saisie semi-automatique semble changer après un clic sur la boîte de dialogue (comme rapporté par MatteoC). La solution de contournement ci-dessous semble résoudre ce problème:

Voir violon: https://jsfiddle.net/sv9L7cnr/

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

Je me souviens avoir rencontré un problème similaire avec la saisie semi-automatique et zIndex, et j'ai dû le corriger en spécifiant l'option appendTo: $(selector).autocomplete({appendTo: "#copy_dialog"})

Ceci est également utile si vous avez une saisie semi-automatique à l'intérieur d'un élément positionné. Le problème spécifique que j'ai eu était une saisie semi-automatique à l'intérieur d'un élément de position fixe qui est resté en place pendant que le corps principal défilait. La saisie semi-automatique s'affichait correctement mais faisait ensuite défiler avec le corps plutôt que de rester fixe.

5
wrschneider

En poursuivant moi-même ce problème, j'ai découvert que appendTo doit être défini avant l'ouverture de la boîte de dialogue. Il en va de même pour définir (ou modifier) ​​la propriété 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")

Cela pourrait simplement être un sous-produit de ce que fait la boîte de dialogue ouverte, ou ne pas traiter correctement l'élément. Mais l'ordre dans lequel les choses se produisent semble avoir de l'importance.

2
dkelley
  1. Créer la boîte de dialogue
  2. Activer la saisie semi-automatique

Cela signale à jquery que la saisie semi-automatique se trouve dans une boîte de dialogue et contient les informations disponibles pour gérer les index z.

1
Timothy Gonzalez

Solution super simple. Augmentez le z-index pour la saisie semi-automatique. Quand il est actif, je suis sûr que vous le voulez en haut :)

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

solution de user1357172 a fonctionné pour moi mais à mon avis, il a besoin de deux améliorations.

Si appendTo est défini sur null, nous pouvons trouver l'élément .ui-front Le plus proche au lieu de .ui-dialog, Car notre autocomplete doit déjà être attaché à elle. Ensuite, nous devons changer le z-index Uniquement pour le widget associé (liste ul associée) au lieu de changer tous les éléments existants avec la classe .ui-autocomplete.ui-front. Nous pouvons trouver un widget associé en utilisant elem.autocomplete('widget')

Solution:

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 cette solution fonctionne mais elle a l'air un peu hacky, donc ce n'est probablement pas la meilleure.

1
akn

La modification du z-index ne fonctionne que la première fois que la liste déroulante est ouverte, une fois fermée, la fenêtre de dialogue se rend compte qu'il a été "piégé" et met à niveau son z-index.

Aussi pour moi, changer l'ordre de création de la boîte de dialogue et de la saisie automatique était vraiment un problème (pensez à un grand site Web, des tonnes de pages), mais par hasard, j'avais ma propre fonction openPopup qui enveloppait openDialog. J'ai donc trouvé le hack suivant

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

Chaque fois que la boîte de dialogue se concentre, c'est-à-dire sur la première ouverture et lorsque la saisie semi-automatique est fermée, l'index z de chaque liste de saisie semi-automatique est mis à jour.

1
Johann

J'ai essayé tout ce qui est mentionné ici (certains échouaient chaque fois que je survolais des articles et revenais), mais c'est le seule chose qui fonctionnait pour moi dans tous les cas:

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

Ce qui a fonctionné pour moi était une combinaison du poste ci-dessus. J'ai ajouté l'ID myModal au lieu de body et j'ai également ajouté l'événement close.

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

Ce lien a fonctionné pour moi.

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

Suis en utilisant jquery-ui-1.10.3.

J'ai configuré la zone de liste déroulante de saisie semi-automatique à l'intérieur de l'événement "open" de la boîte de dialogue jquery.

0
Suketu Bhuta