Empêcher jQuery UI dialog de définir focus à la première textbox

j'ai mis en place un dialogue modal jQuery UI à afficher quand un utilisateur clique sur un lien. Il y a deux boîtes de texte (Je ne montre le code que pour 1 par souci de brièveté) dans cette balise dialog div et elle est changée pour être une boîte de texte jQuery UI DatePicker qui réagit sur focus.

le problème est que la boîte de dialogue jQuery UI('open') déclenche d'une manière ou d'une autre la première boîte de texte à avoir le focus, ce qui déclenche alors le calendrier datepicker à ouvrir immédiatement.

donc je cherche un façon de prévenir l'accent de passe automatiquement.

<div><a id="lnkAddReservation" href="#">Add reservation</a></div>

<div id="divNewReservation" style="display:none" title="Add reservation">
    <table>
        <tr>
            <th><asp:Label AssociatedControlID="txtStartDate" runat="server" Text="Start date" /></th>
            <td>
                <asp:TextBox ID="txtStartDate" runat="server" CssClass="datepicker" />
            </td>
        </tr>
    </table>

    <div>
        <asp:Button ID="btnAddReservation" runat="server" OnClick="btnAddReservation_Click" Text="Add reservation" />
    </div>
</div>

<script type="text/javascript">
    $(document).ready(function() {
        var dlg = $('#divNewReservation');
        $('.datepicker').datepicker({ duration: '' });
        dlg.dialog({ autoOpen:false, modal: true, width:400 });
        $('#lnkAddReservation').click(function() { dlg.dialog('open'); return false; });
        dlg.parent().appendTo(jQuery("form:first"));
    });
</script>
145
demandé sur kay 2009-07-29 22:15:32

30 réponses

jQuery UI 1.10.0 Changelog listes ticket 4731 as being fixed.

ressemble à focusSelector n'a pas été mis en œuvre, mais une recherche en cascade pour divers éléments a été utilisée à la place. Du billet:

Étendre l'autofocus, en commençant par [autofocus], alors :tabbable contenu, puis buttonpane, puis fermer le bouton, puis la boîte de dialogue

donc, marque un élément avec l'attribut autofocus et c'est l'élément qui devrait recevoir la mise au point:

<input autofocus>

Dans la documentation , le focus logique est expliqué (juste en dessous de la table des matières, sous le titre de "Focus"):

Lors de l'ouverture d'un dialogue, l'accent est automatiquement déplacé vers le premier élément qui correspond à ce qui suit:

  1. le premier élément à l'intérieur du dialogue avec l'attribut autofocus 1519280920"
  2. La première :tabbable élément à l'intérieur de la boîte de dialogue contenu
  3. La première :tabbable élément à l'intérieur de la boîte de dialogue buttonpane
  4. le bouton de fermeture du dialogue
  5. le dialogue lui-même
75
répondu slolife 2014-09-06 07:49:20

ajoutez une portée cachée au-dessus, utilisez ui-helper-hidden-accessible pour la rendre cachée par positionnement absolu. Je sais que vous avez cette classe parce que vous utilisez dialog à partir de jquery-ui et c'est dans jquery-ui.

<span class="ui-helper-hidden-accessible"><input type="text"/></span>
70
répondu Patrick Scott 2012-05-04 20:16:32

En jQuery UI >= 1.10.2, vous pouvez remplacer le _focusTabbable le prototype de la méthode par un placebo de la fonction:

$.ui.dialog.prototype._focusTabbable = $.noop;

Violon

cela affectera tous les dialog dans la page sans avoir besoin de les éditer manuellement.

la fonction originale ne fait rien d'autre que mettre l'accent sur le premier élément avec l'attribut autofocus / tabbable élément / ou de revenir à la boîte de dialogue elle-même. Comme son utilisation ne fait que mettre l'accent sur un élément, il ne devrait y avoir aucun problème à le remplacer par un noop .

55
répondu Fabrício Matté 2014-03-24 06:54:50

j'ai trouvé le code suivant la fonction de dialogue jQuery UI pour ouvrir.

c([]).add(d.find(".ui-dialog-content :tabbable:first")).add(d.find(".ui-dialog-buttonpane :tabbable:first")).add(d).filter(":first").focus();

vous pouvez soit contourner le comportement jQuery ou changer le comportement.

tabindex -1 fonctionne comme une solution.

28
répondu 2009-07-29 19:28:02

à partir de jQuery UI 1.10.0, vous pouvez choisir sur quel élément d'entrée vous concentrer en utilisant l'attribut HTML5 autofocus .

tout ce que vous avez à faire est de créer un élément fictif comme première entrée dans la boîte de dialogue. Il absorbera la concentration pour vous.

<input type="hidden" autofocus="autofocus" />

cela a été testé dans Chrome, Firefox et Internet Explorer (toutes les dernières versions) le 7 février 2013.

http://jqueryui.com/upgrade-guide/1.10/#added-ability-to-specify-which-element-to-focus-on-open

27
répondu silkfire 2014-01-27 14:44:40

vient de le découvrir en jouant.

j'ai trouvé avec ces solutions pour supprimer la mise au point, a causé la touche ESC pour arrêter de travailler (c'est-à-dire fermer le dialogue) lors de la première entrée dans le dialogue.

si la boîte de dialogue s'ouvre et que vous appuyez immédiatement sur ESC , elle ne fermera pas la boîte de dialogue( si vous avez activé cette option), parce que l'accent est mis sur un champ caché ou quelque chose, et il ne reçoit pas de pression sur le clavier événement.

la façon dont je l'ai fixé était d'ajouter ceci à l'événement ouvert pour enlever le focus du premier champ à la place:

$('#myDialog').dialog({
    open: function(event,ui) {
        $(this).parent().focus();
    }
});

cela met l'accent sur la boîte de dialogue, qui n'est pas visible, et puis le ESC travaux de clés.

13
répondu Rob Donovan 2014-07-18 14:11:10

définit le tabindex de l'entrée à -1, puis définit dialog.ouvert pour restaurer tabindex si vous en avez besoin plus tard:

$(function() {
    $( "#dialog-message" ).dialog({
        modal: true,
        width: 500,
        autoOpen: false,
        resizable: false,
        open: function()
        {
            $( "#datepicker1" ).attr("tabindex","1");
            $( "#datepicker2" ).attr("tabindex","2");
        }
    });
});
10
répondu redsquare 2011-03-11 07:53:30

ma solution:

open: function(){
  jQuery('input:first').blur();
  jQuery('#ui-datepicker-div').hide();
},  
10
répondu Thomas 2011-03-22 20:41:44

solution simple:

il suffit de créer un élément invisible avec tabindex=1 ... Cela ne focalisera pas le curseur de données ...

par exemple.:

<a href="" tabindex="1"></a>
...
Here comes the input element
8
répondu Andy 2011-07-07 22:22:25

j'avais un contenu qui était plus long que le dialogue. Une fois ouvert, le dialogue s'écroulerait sur le premier :tabbable qui se trouve en bas. Voici mon fix.

$("#myDialog").dialog({
   ...
   open: function(event, ui) { $(this).scrollTop(0); }
});
7
répondu thetoolman 2010-08-10 03:47:24

Voici la solution que j'ai implémentée après avoir lu jQuery UI ticket #4731 , Initialement posté par slolife en réponse à une autre réponse. (Le billet a aussi été créé par lui.)

tout D'abord, quelle que soit la méthode que vous utilisez pour appliquer les autocomplètes à la page, Ajouter la ligne de code suivante:

$.ui.dialog.prototype._focusTabbable = function(){};

qui désactive le comportement "auto-focus" de jQuery. Pour vous assurer que votre site continue à être largement accessible, enveloppez vos méthodes de création de dialogue de sorte que le code supplémentaire peut être ajouté, et Ajouter un appel pour focaliser le premier élément d'entrée:

function openDialog(context) {

    // Open your dialog here

    // Usability for screen readers.  Focus on an element so that screen readers report it.
    $("input:first", $(context)).focus();

}

pour traiter plus en détail de l'accessibilité lorsque les options autocomplete sont sélectionnées via le clavier, nous outrepassons la fonction de rappel autocomplete de jQuery UI et ajoutons du code supplémentaire pour nous assurer que le textElement ne perd pas sa mise au point dans IE 8 après avoir effectué une sélection.

voici le code que nous utilisons pour appliquer les autocomplètes aux éléments:

$.fn.applyAutocomplete = function () {

    // Prevents jQuery dialog from auto-focusing on the first tabbable element.
    // Make sure to wrap your dialog opens and focus on the first input element
    // for screen readers.
    $.ui.dialog.prototype._focusTabbable = function () { };

    $(".autocomplete", this)
        .each(function (index) {

            var textElement = this;

            var onSelect = $(this).autocomplete("option", "select");
            $(this).autocomplete("option", {
                select: function (event, ui) {
                    // Call the original functionality first
                    onSelect(event, ui);

                    // We replace a lot of content via AJAX in our project.
                    // This ensures proper copying of values if the original element which jQuery UI pointed to
                    // is replaced.
                    var $hiddenValueElement = $("#" + $(textElement).attr('data-jqui-acomp-hiddenvalue'));
                    if ($hiddenValueElement.attr("value") != ui.item.value) {
                        $hiddenValueElement.attr("value", ui.item.value);
                    }

                    // Replace text element value with that indicated by "display" if any
                    if (ui.item.display)
                        textElement.value = ui.item.display;

                    // For usability purposes.  When using the keyboard to select from an autocomplete, this returns focus to the textElement.
                    $(textElement).focus();

                    if (ui.item.display)
                        return false;

                }
            });
        })
        // Set/clear data flag that can be checked, if necessary, to determine whether list is currently dropped down
        .on("autocompleteopen", function (event, ui) {
            $(event.target).data().autocompleteIsDroppedDown = true;
        })
        .on("autocompleteclose", function (event, ui) {
            $(event.target).data().autocompleteIsDroppedDown = false;
        });

    return this;
}
3
répondu Alexander Pritchard 2013-06-05 18:09:57

vous pouvez fournir cette option, pour focaliser le bouton Fermer à la place.

.dialog({
      open: function () {
              $(".ui-dialog-titlebar-close").focus();
            }
   });
2
répondu Jay Dubal 2017-02-23 08:10:34

cela peut être un comportement de navigateur pas question de plugin jQuery. Avez-vous essayé de supprimer le focus programmatiquement après avoir ouvert le popup.

$('#lnkAddReservation').click(function () {
    dlg.dialog('open');

    // you may want to change the selector below
    $('input,textarea,select').blur();

    return false;
});

N'a pas testé cela mais devrait fonctionner correctement.

1
répondu RaYell 2009-07-29 18:30:52

j'ai résolu le même problème en insérant une entrée vide avant le curseur de données, qui vole le focus chaque fois que la boîte de dialogue est ouverte. Cette entrée est cachée à chaque ouverture du dialogue et affichée à nouveau à la fermeture.

1
répondu Manuel Leuenberger 2011-03-12 19:15:11

eh Bien, c'est cool que personne n'a trouvé la solution pour l'instant, mais il semble que j'ai quelque chose pour vous. La mauvaise nouvelle est que le dialogue saisit le focus dans tous les cas, même si aucune entrée et aucun lien ne sont à l'intérieur. J'utilise le dialogue comme une infobulle et j'ai vraiment besoin de rester concentré dans l'élément d'origine. Voici ma solution:

utiliser l'option [autoOpen: false]

$toolTip.dialog("widget").css("visibility", "hidden"); 
$toolTip.dialog("open");
$toolTip.dialog("widget").css("visibility", "visible");

tandis que le dialogue invisible, le focus n'est pas défini n'importe où et reste dans le place d'origine. Il fonctionne pour les tooltips avec juste un texte simple, mais pas testé pour les dialogues plus fonctionnels où il peut être important d'avoir le dialogue visible sur le moment d'ouverture. Ça marchera probablement très bien dans tous les cas.

je comprends que le post original était juste pour éviter d'obtenir la mise au point sur le premier élément, mais vous pouvez facilement décider où la mise au point devrait être après le dialogue est ouvert (après mon code).

testé en IE, FF et Chrome.

espérons que cela aidera quelqu'un.

1
répondu Roc 2012-02-24 09:40:59

à mon avis Cette solution est très agréable:

$("#dialog").dialog({
    open: function(event, ui) {
        $("input").blur();
    }
});

Trouvés ici: impossible à supprimer-autofocus-en-ui-dialog

1
répondu emolah 2017-05-23 11:55:15

je cherchais un autre problème, mais la même cause. Le problème est que le dialogue défini focus à la première <a href="">.</a> qu'il trouve. Donc, si vous avez beaucoup de texte dans votre boîte de dialogue et que des barres de défilement apparaissent, vous pourriez avoir la situation où la barre de défilement sera défilée vers le bas. Je crois que cela résout également la question des personnes de première instance. Bien que les autres le sont également.

la solution simple et facile à comprendre. <a id="someid" href="#">.</a> comme première ligne de votre dialogue div.

exemple:

 <div id="dialogdiv" title="some title">
    <a id="someid" href="#">.</a>
    <p>
        //the rest of your stuff
    </p>
</div>

où votre dialogue est initié

$(somediv).dialog({
        modal: true,
        open: function () { $("#someid").hide(); otherstuff or function },
        close: function () { $("#someid").show(); otherstuff or function }
    });

le ci-dessus n'aura rien de focalisé et les barres de défilement resteront au sommet où il appartient. Le <a> se focalise mais est ensuite caché. Donc, l'effet global est l'effet désiré.

je sais c'est un vieux fil, mais comme pour L'UI docs il n'y a pas de solution à cela. Cela ne nécessite pas de flou ni de concentration pour fonctionner. Pas sûr si c'est la plus élégante. Mais c'est logique et facile à expliquer à quiconque.

1
répondu MikeF 2012-09-14 00:58:57

si vous n'avez qu'un champ sous la forme de dialogue Jquery et que C'est celui qui a besoin D'un cliqueur de données, vous pouvez aussi simplement mettre l'accent sur le dialogue fermer le bouton dans la barre de titre de dialog:

$('.ui-dialog-titlebar-close').focus();

appelez ceci après que le dialogue a été initialisé, par exemple:

$('#yourDialogId').dialog();
$('.ui-dialog-titlebar-close').focus();

parce que le bouton Fermer est rendu après le .dialog() est appelé.

1
répondu mik-t 2013-06-25 19:58:28

si vous utilisez des boutons de dialogue, il vous suffit de définir l'attribut autofocus sur l'un des boutons:

$('#dialog').dialog({
  buttons: [
    {
      text: 'OK',
      autofocus: 'autofocus'
    },
    {
      text: 'Cancel'
    }
  ]
});
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
<link href="https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet"/>

<div id="dialog" title="Basic dialog">
  This is some text.
  <br/>
  <a href="www.google.com">This is a link.</a>
  <br/>
  <input value="This is a textbox.">
</div>
1
répondu Sam 2016-06-16 07:50:25

j'ai eu le même problème.

le contournement que j'ai fait est d'ajouter la boîte de texte factice au haut du conteneur de dialogue.

<input type="text" style="width: 1px; height: 1px; border: 0px;" />
0
répondu TTCG 2011-03-22 13:20:59

comme mentionné, il s'agit d'un bug connu avec jQuery UI et devrait être corrigé assez rapidement. Jusqu'à ce moment...

Voici une autre option, donc vous n'avez pas à jouer avec tabindex:

désactiver temporairement le curseur jusqu'à ce que la boîte de dialogue s'ouvre:

dialog.find(".datepicker").datepicker("disable");
dialog.dialog({
    "open": function() {$(this).find(".datepicker").datepicker("enable");},
});

ça me va.

Double question: Comment le flou de la première forme d'entrée dans la boîte de dialogue d'ouverture

0
répondu BMiner 2017-05-23 10:30:49

pour développer certaines des réponses précédentes (et ignorer l'aspect du pick-données auxiliaire), si vous voulez empêcher l'événement focus() de focaliser le premier champ d'entrée lorsque votre dialogue s'ouvre, essayez ceci:

$('#myDialog').dialog(
    { 'open': function() { $('input:first-child', $(this)).blur(); }
});
0
répondu nickb 2011-12-29 00:12:02

j'ai eu un problème similaire et je l'ai résolu en me concentrant sur le dialogue après l'ouverture:

var $dialog = $("#pnlFiltros")
    .dialog({
        autoOpen: false,
        hide: "puff",                   
        width: dWidth,
        height: 'auto',
        draggable: true,
        resizable: true,
        closeOnScape : true,
        position: [x,y]                    
    });
$dialog.dialog('open');
$("#pnlFiltros").focus(); //focus on the div being dialogued (is that a word?)

mais dans mon cas le premier élément est une ancre, donc je ne sais pas si dans votre cas cela laissera le curseur ouvert.

EDIT: ne fonctionne que sur IE

0
répondu daniloquio 2012-03-16 16:19:08

trouver dans jquery.interface.js

d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus(); 

et remplacer par

d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(-1).focus();
0
répondu user1443069 2012-06-07 19:28:11

jQuery 1.9 est libéré et il ne semble pas y avoir de correction. Tenter d'empêcher la focalisation de la première zone de texte par certaines des méthodes suggérées ne fonctionne pas en 1.9. Je pense que parce que les méthodes tentent de flouter la mise au point ou de déplacer la mise au point se produisent après que la zone de texte dans le dialogue a déjà gagné la mise au point et a fait son sale travail.

Je ne vois rien dans la documentation de L'API qui me fasse penser que quelque chose a changé en termes de fonctionnalité attendue. Hors de ajouter un ouvreur de bouton...

0
répondu pixelda 2012-10-09 13:07:15

j'ai eu le même problème. Sur ma page première entrée est la zone de texte avec jQuery UI calendrier. Deuxième élément est le bouton. Comme la date a déjà de la valeur, je mets l'accent sur le bouton, mais d'abord ajouter le déclencheur pour la zone de texte flou. Ce problème résoudre dans tous les navigateurs et probablement dans toutes les versions de jQuery. Testé dans la version 1.8.2.

<div style="padding-bottom: 30px; height: 40px; width: 100%;">
@using (Html.BeginForm("Statistics", "Admin", FormMethod.Post, new { id = "FormStatistics" }))
{
    <label style="float: left;">@Translation.StatisticsChooseDate</label>
    @Html.TextBoxFor(m => m.SelectDate, new { @class = "js-date-time",  @tabindex=1 })
    <input class="button gray-button button-large button-left-margin text-bold" style="position:relative; top:-5px;" type="submit" id="ButtonStatisticsSearchTrips" value="@Translation.StatisticsSearchTrips"  tabindex="2"/>
}

<script type="text/javascript">
$(document).ready(function () {        
    $("#SelectDate").blur(function () {
        $("#SelectDate").datepicker("hide");
    });
    $("#ButtonStatisticsSearchTrips").focus();

});   

0
répondu user1698635 2013-11-20 14:48:48

c'est vraiment important pour les smartphones et les tablettes parce que le clavier apparaît quand une entrée a l'accent. C'est ce que j'ai fait, ajoutez cette entrée au début de la div:

<input type="image" width="1px" height="1px"/>

ne fonctionne pas avec la taille 0px . Je suppose que c'est encore mieux avec une vraie image transparente, soit .png ou .gif mais je n'ai pas essayé.

fonctionne très bien sur iPad.

0
répondu Ángel Arbeteta 2014-12-13 01:02:25

vous pouvez ajouter ceci:

...

dlg.dialog({ autoOpen:false,
modal: true, 
width: 400,
open: function(){                  // There is new line
  $("#txtStartDate").focus();
  }
});

...

-1
répondu F1dz 2010-08-21 03:45:02

comme première entrée: <input type="text" style="position:absolute;top:-200px" />

-2
répondu user2816796 2013-10-01 08:11:56