Comment définir le focus pour un champ particulier dans un modal Bootstrap, une fois qu'il apparaît

182

J'ai vu quelques questions concernant les modaux bootstrap, mais aucune ne ressemble exactement à celle-ci, alors je vais continuer.

J'ai un modal que j'appelle en cliquant comme ça ...

$(".modal-link").click(function(event){
  $("#modal-content").modal('show');
});

Cela fonctionne bien, mais lorsque j'affiche le modal, je veux me concentrer sur le premier élément d'entrée ... Dans certains cas, le premier élément d'entrée a un identifiant de #photo_name.

Alors j'ai essayé

   $(".modal-link").click(function(event){
     $("#modal-content").modal('show');
     $("input#photo_name").focus();
   });

Mais ce fut en vain. Enfin, j'ai essayé de lier à l'événement 'show', mais même ainsi, l'entrée ne se concentrera pas. Enfin juste pour les tests, comme je soupçonnais qu'il s'agissait de l'ordre de chargement de js, j'ai mis un setTimeout juste pour voir si je retarde une seconde, la mise au point fonctionnera, et oui, ça marche! Mais cette méthode est évidemment de la merde. Existe-t-il un moyen d'avoir le même effet que ci-dessous sans utiliser un setTimeout?

  $("#modal-content").on('show', function(event){
    window.setTimeout(function(){
      $(event.currentTarget).find('input#photo_name').first().focus()
    }, 0500);
  });
jdkealy
la source

Réponses:

371

Essaye ça

Voici l'ancienne DEMO :

EDIT: (Voici une DEMO fonctionnelle avec Bootstrap 3 et jQuery 1.8.3)

$(document).ready(function() {
    $('#modal-content').modal('show');
    $('#modal-content').on('shown', function() {
        $("#txtname").focus();
    })
});

Le démarrage de bootstrap 3 doit utiliser l'événement shown.bs.modal:

$('#modal-content').on('shown.bs.modal', function() {
    $("#txtname").focus();
})
gaurang171
la source
3
Merci. Je n'avais pas vu l'événement "montré". Exactement ce que je cherchais.
jdkealy
Merci! la démo ne fonctionne plus mais l'extrait de code fonctionne.
Kreker
@keyur at codebins.com Cet événement commence après l'affichage du modal, que faire si je dois démarrer l'événement avant que le modal ne soit affiché
Thomas Shelby
okej, je devrais utiliser 'show.bs.modal' au lieu de 'shown.bs.modal'
Thomas Shelby
à propos du gestionnaire de focus, il nécessite un peu de retard donc vous devez le faire dans un setInterval comme ceci: setInterval (function () {$ ("# your-input"). focus ();}, 50);
Nguyen Minh Hien
76

Je voulais juste dire que Bootstrap 3 gère cela un peu différemment. Le nom de l'événement est "shown.bs.modal".

$('#themodal').on('shown.bs.modal', function () {
   $("#txtname").focus();
});

ou mettez le focus sur la première entrée visible comme ceci:

.modal('show').on('shown.bs.modal', function ()
{
    $('input:visible:first').focus();
})

http://getbootstrap.com/javascript/#modals

David Beck
la source
Cela a fonctionné pour moi si j'utilisais .on ('show.bs.modal') non montré
Peter Graham
Cela a pris beaucoup de temps pendant que je voyais que ça devait être "montré.bs ..." au lieu de "show.bs ...". Le spectacle n'a pas fonctionné pour moi. En fait, les deux fonctionnent et ce sont des événements différents. Désolé ignorer ma première phrase.
Vladyn
@PeterGraham vous utilisez peut-être bootstrap 2?
FindOutIslamNow
10

J'utilise ceci dans ma mise en page pour capturer tous les modaux et me concentrer sur la première entrée

  $('.modal').on('shown', function() {
     $(this).find('input').focus();
  });
Joe Beams
la source
Sucré. Mon premier élément d'entrée est masqué, donc je pense que je devrais faire: $ (this) .find ('input: not ([type = hidden])'). Focus ();
jdkealy
2
Ou$(this).find('input:visible').focus();
Stephan Muller
2
devrait être $ (this) .find ('input'). first (). focus () si vous ne voulez pas concentrer toutes les entrées
Jacek Pietal
9

J'ai eu le même problème avec bootstrap 3, focus quand je clique sur le lien, mais pas quand déclenche l'événement avec javascript. La solution:

$('#myModal').on('shown.bs.modal', function () {
    setTimeout(function(){
        $('#inputId').focus();
    }, 100);
});

C'est probablement quelque chose à propos de l'animation!

Alejandro Fiore
la source
Il se passe définitivement quelque chose avec l'animation modale. Même si je désactive le fondu modal dans les options, il ne sera pas rendu s'il y a une tâche intensive en processeur juste après la fenêtre contextuelle modale. L'utilisation de ce délai est le seul moyen de le faire fonctionner.
krx
8

J'ai eu du mal à attraper l'événement "shown.bs.modal" .. Et c'est ma solution qui fonctionne parfaitement ..

Au lieu de cela simple sur ():

$('#modal').on 'shown.bs.modal', ->

Utilisez sur () avec l'élément délégué:

$('body').on 'shown.bs.modal', '#modal', ->
Michal Macejko
la source
6

Il semble que c'est parce que l'animation modale est activée ( fadedans la classe de la boîte de dialogue), après l'appel .modal('show'), la boîte de dialogue n'est pas immédiatement visible, elle ne peut donc pas obtenir le focus pour le moment.

Je peux penser à deux façons de résoudre ce problème:

  1. Supprimer fadede la classe, de sorte que la boîte de dialogue soit immédiatement visible après l'appel .modal('show'). Vous pouvez voir http://codebins.com/bin/4ldqp7x/4 pour une démonstration. (Désolé @keyur, j'ai modifié et enregistré par erreur en tant que nouvelle version de votre exemple)
  2. Appel focus()à l' shownévénement comme ce @keyur écrit.
SAPikachu
la source
Merci. J'aimerais pouvoir marquer deux réponses comme correntes: p. Oui, je ne voulais même pas que le "fondu" soit appliqué, donc supprimer cela fonctionne. J'ai supprimé le fondu et ajouté l'événement affiché.
jdkealy
4

J'ai créé une manière dynamique d'appeler automatiquement chaque événement. C'est parfait pour focaliser un champ, car il n'appelle l'événement qu'une seule fois, le supprimant après utilisation.

function modalEvents() {
    var modal = $('#modal');
    var events = ['show', 'shown', 'hide', 'hidden'];

    $(events).each(function (index, event) {
        modal.on(event + '.bs.modal', function (e) {
            var callback = modal.data(event + '-callback');
            if (typeof callback != 'undefined') {
                callback.call();
                modal.removeData(event + '-callback');
            }
        });
    });
}

Il vous suffit d'appeler modalEvents()le document prêt.

Utilisation:

$('#modal').data('show-callback', function() {
    $("input#photo_name").focus();
});

Ainsi, vous pouvez utiliser le même modal pour charger ce que vous voulez sans vous soucier de supprimer des événements à chaque fois.

Danilo Colasso
la source
C'est ce dont j'ai besoin! Merci mec!
DmitryBoyko
3

J'ai eu le même problème avec le bootstrap 3 et je l'ai résolu comme ceci:

$('#myModal').on('shown.bs.modal', function (e) {
    $(this).find('input[type=text]:visible:first').focus();
})

$('#myModal').modal('show').trigger('shown');
edercortes
la source
0

Événement show modal Bootstrap

$('#modal-content').on('show.bs.modal', function() {
$("#txtname").focus();

})

AdminDev826
la source
-1

Une solution un peu plus propre et plus modulaire pourrait être:

$(document).ready(function(){
    $('.modal').success(function() { 
        $('input:text:visible:first').focus();
    });  
});

Ou en utilisant votre identifiant comme exemple à la place:

$(document).ready(function(){
    $('#modal-content').modal('show').success(function() {
        $('input:text:visible:first').focus();
    });  
});

J'espère que ça t'as aidé..

relancer
la source
Pas de succès de cette fonction.
Avinash