web-dev-qa-db-fra.com

Focus de champ de saisie modale sur Twitter

J'ai la forme modale suivante de l'exemple:

<!-- Button to trigger modal -->
<a href="#myModal" role="button" class="btn" data-toggle="modal">Launch demo modal</a>

<!-- Modal -->
<div id="myModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
    <h3 id="myModalLabel">Modal header</h3>
  </div>
  <div class="modal-body">
    Enter something: <input type="text" id="myInput">
  </div>
  <div class="modal-footer">
    <button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
    <button class="btn btn-primary">Save changes</button>
  </div>
</div>

Je veux que mon champ de saisie soit concentré après l'affichage de modal.
J'ai essayé à la fois l'autofocus et la définition de la focalisation par champ sur l'événement $('modal').shown(). Il se concentre un peu sur le champ (j'ai un autre événement qui affiche l'étiquette lorsque le champ est ciblé) mais en fait, le champ n'est pas ciblé et je dois appuyer sur TAB pour le recentrer. J'ai aussi essayé quelque chose comme ça:

$(".modal").on('shown', function() {
    $(this).find("[autofocus]:first").focus();
});

et la définition de l'attribut autofocus:"autofocus" pour mon champ . Cela a eu le même effet.
Tout ce que j’ai essayé fonctionne lorsque modal n’est qu’un div habituel, il se concentre sur le chargement des pages. Mais quand modal est déclenché par un bouton - rien ne fonctionne (bien sûr, je change de logique également, quand modal est juste un div habituel, je peux le concentrer sur la charge, quand je le déclenche par un bouton, je le prends en compte et essaie de le résoudre en conséquence). 

Ce que je veux, c'est simplement que le champ soit ciblé une fois le modal chargé, de sorte que le curseur clignote et que l'utilisateur puisse commencer à taper. 

La seule chose qui a fonctionné est de changer bootstrap.js lui-même, j'ai mis $("#myInput").focus() quelque part dans la section modale de bootstrap.js mais bon, j'ai oublié où il se trouvait, et deuxièmement - je pense que ce n'est pas bon de changer l'API bootstrap.js, il doit y avoir plus simple et solution plus élégante. Me conseiller s'il vous plaît, merci xD

METTRE À JOUR:
Tout d’abord, merci pour votre aide! Grâce à vous, j’ai compris que mon problème était celui de Rails. 

Voici ce que j'ai fait:
1). Rails generate controller home index
2). app/views/home/index.html et app/assets/javascript/quelque chose.js sont comme dans ce jsFiddle fourni par robertklep: http://jsfiddle.net/ JCaFp/
4). jquery-1.9.1.js et bootstrap.js sont dans app/assets/javascript/ (les deux sont récents du site Web, rien n'a changé)
5). app/views/layouts/application.html.erb - Je suppose que ce fichier est la clé de notre solution: 

<!DOCTYPE html>
<html>
<head>
  <title>Udc</title>
  <%= stylesheet_link_tag    "application", :media => "all" %>
  <%= javascript_include_tag "application" %>
  <%= csrf_meta_tags %>
</head>
<body>

<%= yield %>

</body>
</html>

Ça ne marche toujours pas. Tous les fichiers js sont inclus, mais lorsque j'ouvre mon modal dans un navigateur, les entrées sont activées un instant, puis à nouveau floues. 

J'ai aussi essayé ceci:

  <%= javascript_include_tag "jquery" %>
  <%= javascript_include_tag "bootstrap" %>
  <%= javascript_include_tag "somehow" %>

Toujours les mêmes choses.
Suggestions? :) 

METTRE À JOUR: 

Résolu!

Après avoir changé mon somehow.js en 

$(document).ready(function() {
    $(".modal").on('shown', function() {
        $(this).find("[autofocus]:first").focus();
    });
});

et application.html.erb feuille de style à: 

  <%= javascript_include_tag "jquery" %>
  <%= javascript_include_tag "bootstrap" %>
  <%= javascript_include_tag "somehow" %>

cela fonctionne comme prévu. Merci encore!

53
konnigun

Je pense que le nom de l'événement affiché a été modifié dans Bootstrap 3, comme expliqué dans this post.

Comme @MrDBA note, dans Bootstrap 3 le nom de l'événement est changé en shown.bs.modal.

Donc, pour Bootstrap 3 utiliser:

$('#myModal').on('shown.bs.modal', function () {
    $('#myInput').focus();
})
81
David Kirkland

Pour une solution générale ne nécessitant pas de code spécifique pour chaque boîte de dialogue, vous pouvez utiliser ceci:

$('.modal').on('shown.bs.modal', function () {
  $(this).find('input:text:visible:first').focus();
})
39
pschwamb

Essayez de supprimer tabindex="-1" et cela fonctionne bien.

Alors changez ceci:

<div class="modal fade" id="modalID" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">

Pour ça:

<div class="modal fade" id="modalID" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
11
Sunil Shivalkar

Le simple fait de changer $(this).find("[autofocus]:first").focus(); en $(this).find("#myInput").focus(); le rend efficace pour moi. Si vous avez modifié l'API Bootstrap et souhaitez annuler cette modification, vous pouvez simplement télécharger à nouveau et remplacer le fichier.

7
Austin Cummings

J'ai enlevé tabindex = "- 1" et ça marche tellement bien.

Mon code HTML avant les modifications:

<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">

Mon code HTML après les modifications:

<div class="modal fade" id="myModal" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">

Mon code d'entrée:

<input id="tblModalNombreConductor" type="text" maxlength="50" placeholder="Ej: Armando Casas" autofocus/>

Et je n'ai pas de configuration dans mon code Javascript.

6
Richard Rebeco

Si vous rencontrez des problèmes avec "shown.bs.modal", définissez un délai d'expiration.

setTimeout(function() {
$('#myInput').focus();
}, 500);
6
hacklover

Je pense que la réponse mise à jour est assez intelligente. Voici une autre façon de le résoudre.

Le fichier js de Bootstrap 3.2 comprend un script permettant de gérer le focus pendant et après la transition en fondu du modal. Cela interfère avec tout jQuery, javascript ou Rails + HTML5 se concentrant sur un champ de formulaire dans modal - bootstrap supprime votre focus après le chargement modal. 

Pour supprimer la capacité de bootstrap de surcharger votre focus, commentez cette ligne dans la zone de script Modal:

transition ?
    that.$element.find('.modal-dialog') // wait for modal to slide in
      .one($.support.transition.end, function () {
        // that.$element.focus().trigger(e)
        // the line above is stealing your focus after modal loads!
      })
      .emulateTransitionEnd(300) :
    that.$element.focus().trigger(e) 

Votre champ devrait maintenant pouvoir se focaliser sous n'importe quelle forme modale. 

3
Deborah

Vous pouvez faire: 

<%= f.text_field :first_name, class: "form-control", placeholder: "Enter first name", autofocus: true%>

il suffit d'ajouter ceci: autofocus: true

1
Raz

Vous pouvez aussi essayer

$('#the-modal').on('shown.bs.modal', function(e) {
    $('#the-input').focus();
});
0
ctf0