Como definir o foco para um campo específico em um modal de Bootstrap, uma vez que ele apareça

182

Eu já vi algumas perguntas em relação aos modais de autoinicialização, mas nenhuma exatamente como essa, então vou adiante.

Eu tenho um modal que eu chamo de onclick assim ...

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

Isso funciona bem, mas quando eu mostro o modal, quero focar no primeiro elemento de entrada ... Nesse caso, o primeiro elemento de entrada tem um ID de #photo_name.

Então eu tentei

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

Mas isso não adiantou. Por fim, tentei vincular o evento 'show', mas, mesmo assim, a entrada não será focada. Por fim, apenas para teste, como eu suspeitava que fosse sobre a ordem de carregamento do js, ​​coloquei um setTimeout apenas para ver se eu atraso um segundo, o foco funcionará e, sim, funciona! Mas esse método é obviamente uma porcaria. Existe alguma maneira de ter o mesmo efeito que abaixo sem usar um setTimeout?

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

Respostas:

371

Tente isto

Aqui está a antiga DEMO :

EDIT: (Aqui está uma demonstração de trabalho com Bootstrap 3 e jQuery 1.8.3)

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

Para iniciar o bootstrap 3, é necessário usar o evento named.bs.modal:

$('#modal-content').on('shown.bs.modal', function() {
    $("#txtname").focus();
})
gaurang171
fonte
3
Obrigado. Eu não tinha visto o evento "mostrado". Exatamente o que eu estava procurando.
Jdkealy 31/08/2012
obrigado! a demonstração não funciona mais, mas o snippet funciona.
Kreker
@keyur em codebins.com Este evento começa após modal está exibindo, o que se eu tiver que evento começa antes modal é exibido
Thomas Shelby
okej, eu deveria usar 'show.bs.modal' em vez de 'shown.bs.modal'
Thomas Shelby
sobre o manipulador de foco, ele requer um pouco de atraso; portanto, você deve inseri-lo em um conjunto de informações sobre SetInterval como este: setInterval (function () {$ ("# your-input"). focus ();}, 50);
Nguyen Minh Hien
76

Só queria dizer que o Bootstrap 3 lida com isso de maneira um pouco diferente. O nome do evento é "mostrado.bs.modal".

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

ou concentre-se na primeira entrada visível como esta:

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

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

David Beck
fonte
Ela trabalhou para mim se eu usasse .no ( 'show.bs.modal') não mostrado
Peter Graham
Demorou muito tempo enquanto eu vi que deveria ser "mostrado.bs ..." em vez de "show.bs ...". Mostrar não funcionou para mim. Na verdade, ambos estão trabalhando e são eventos diferentes. Desculpe ignorar minha primeira frase.
Vladyn
@PeterGraham talvez você esteja usando o bootstrap 2?
FindOutIslamNow
10

Estou usando isso no meu layout para capturar todos os modais e focar na primeira entrada

  $('.modal').on('shown', function() {
     $(this).find('input').focus();
  });
Joe Beams
fonte
Doce. Meu primeiro elemento de entrada está oculto, portanto, acho que teria que fazer: $ (this) .find ('input: not ([type = hidden])'). Focus ();
Jdkealy 31/08/2012
2
Ou$(this).find('input:visible').focus();
Stephan Muller
2
deve ser $ (this) .find ( 'input') primeiro () foco () Se você não quer se concentrar todas as entradas..
Jacek Pietal
9

Eu tive o mesmo problema com o bootstrap 3, foco quando clico no link, mas não quando acionar o evento com javascript. A solução:

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

Provavelmente é algo sobre a animação!

Alejandro Fiore
fonte
Definitivamente, há algo acontecendo com a animação modal. Mesmo se eu desativar o desbotamento modal nas opções, ele não será renderizado se houver uma tarefa intensiva da CPU logo após o pop-up modal. Usar esse tempo limite é a única maneira de fazê-lo funcionar.
KRX
8

Eu tive problema para pegar o evento "shows.bs.modal" .. E esta é a minha solução que funciona perfeita ..

Em vez simples, em ():

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

Use on () com elemento delegado:

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

Parece que a animação modal está ativada ( fadena classe da caixa de diálogo), após chamar.modal('show') , a caixa de diálogo não fica imediatamente visível e, portanto, não é possível obter o foco no momento.

Posso pensar em duas maneiras de resolver esse problema:

  1. Remover fadeda classe, para que a caixa de diálogo fique imediatamente visível após a chamada .modal('show'). Você pode ver http://codebins.com/bin/4ldqp7x/4 para obter uma demonstração. (Desculpe, @keyur, editei e salvei por engano como nova versão do seu exemplo)
  2. Ligue focus()para showneventos como o que o @keyur escreveu.
SAPikachu
fonte
Obrigado. Gostaria de poder marcar duas respostas como corretas: p. Sim, eu nem queria o "fade" em efeito, então remover isso funciona. Eu removi o fade e adicionei o evento mostrado.
Jdkealy
4

Criei uma maneira dinâmica de chamar cada evento automaticamente. É perfeito para focar um campo, porque ele chama o evento apenas uma vez, removendo-o após o uso.

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

Você só precisa chamar o modalEvents()documento pronto.

Usar:

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

Portanto, você pode usar o mesmo modal para carregar o que deseja, sem se preocupar em remover eventos sempre.

Danilo Colasso
fonte
Isso é o que eu preciso! Obrigado mano!
Desenvolvedor
3

Eu tive o mesmo problema com o bootstrap 3 e resolvi assim:

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

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

Evento de apresentação modal de inicialização

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

})

AdminDev826
fonte
-1

Uma solução um pouco mais limpa e mais modular pode ser:

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

Ou use seu ID como exemplo:

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

Espero que ajude..

reviver
fonte
Não existe tal função de sucesso.
Avinash 07/07