Cómo establecer el foco para un campo en particular en un modo Bootstrap, una vez que aparece

182

He visto un par de preguntas con respecto a los modales de bootstrap, pero ninguna exactamente como esta, así que seguiré adelante.

Tengo un modal que llamo onclick así ...

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

Esto funciona bien, pero cuando muestro el modal quiero centrarme en el primer elemento de entrada ... En muchos casos, el primer elemento de entrada tiene una identificación de #photo_name.

Así que lo intenté

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

Pero esto fue en vano. Por último, traté de vincularme al evento 'show' pero aun así, la entrada no se enfocará. Por último, solo para probar, ya que sospechaba que se trataba del orden de carga de js, puse un setTimeout solo para ver si me demoraba un segundo, ¿funcionará el enfoque, y sí, funciona! Pero este método es obviamente una porquería. ¿Hay alguna manera de tener el mismo efecto que a continuación sin usar un setTimeout?

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

Respuestas:

371

Prueba esto

Aquí está la vieja DEMO :

EDITAR: (Aquí hay una DEMO que funciona con Bootstrap 3 y jQuery 1.8.3)

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

El arranque de bootstrap 3 debe usar el evento shown.bs.modal:

$('#modal-content').on('shown.bs.modal', function() {
    $("#txtname").focus();
})
gaurang171
fuente
3
Gracias. No había visto el evento "mostrado". Exactamente lo que estaba buscando.
jdkealy
¡Gracias! la demostración ya no funciona pero el fragmento sí.
Kreker
@keyur en codebins.com Este evento comienza después de que se muestra modal, ¿y si tengo que iniciar el evento antes de que se muestre modal
Thomas Shelby
okej, debería usar 'show.bs.modal' en lugar de 'shown.bs.modal'
Thomas Shelby
sobre el controlador de foco, requiere un poco de retraso, por lo que debe hacerlo en un conjunto de elementos como este: setInterval (function () {$ ("# your-input"). focus ();}, 50);
Nguyen Minh Hien
76

Solo quería decir que Bootstrap 3 maneja esto un poco diferente. El nombre del evento es "shown.bs.modal".

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

o poner el foco en la primera entrada visible como esta:

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

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

David Beck
fuente
Me funcionó si usaba .on ('show.bs.modal') no mostrado
Peter Graham
Me llevó mucho tiempo ver que debería ser "shown.bs ..." en lugar de "show.bs ...". Show no funcionó para mí. En realidad, ambos funcionan y son eventos diferentes. Lo siento, ignora mi primera oración.
Vladyn
@PeterGraham, ¿tal vez estás usando Bootstrap 2?
FindOutIslamNow
10

Estoy usando esto en mi diseño para capturar todos los modales y enfocarme en la primera entrada

  $('.modal').on('shown', function() {
     $(this).find('input').focus();
  });
Joe Beams
fuente
Dulce. Sin embargo, mi primer elemento de entrada está oculto, así que creo que tendría que hacer: $ (this) .find ('input: not ([type = hidden])'). Focus ();
jdkealy
2
O bien$(this).find('input:visible').focus();
Stephan Muller el
2
debe ser $ (this) .find ('input'). first (). focus () si no desea enfocar todas las entradas
Jacek Pietal
9

Tuve el mismo problema con bootstrap 3, enfóqueme cuando hago clic en el enlace, pero no cuando desencadenar el evento con javascript. La solución:

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

¡Probablemente sea algo sobre la animación!

Alejandro Fiore
fuente
Definitivamente está pasando algo con la animación modal. Incluso si apago el desvanecimiento modal en las opciones, no se representará si hay una tarea intensiva de CPU justo después de la ventana emergente modal. Usar este tiempo de espera es la única forma en que puedo hacer que funcione.
krx
8

Tuve problemas para detectar el evento "shown.bs.modal" ... Y esta es mi solución que funciona perfectamente ...

En cambio simple en ():

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

Usar en () con elemento delegado:

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

Parece que es porque la animación modal está habilitada ( fadeen la clase del cuadro de diálogo), después de llamar .modal('show'), el cuadro de diálogo no es visible de inmediato, por lo que no puede enfocarse en este momento.

Se me ocurren dos formas de resolver este problema:

  1. Eliminar fadede la clase, de modo que el diálogo sea visible inmediatamente después de llamar .modal('show'). Puede ver http://codebins.com/bin/4ldqp7x/4 para la demostración. (Lo siento @keyur, edité y guardé por error como nueva versión de tu ejemplo)
  2. Llame focus()en showncaso de lo que escribió @keyur.
SAPikachu
fuente
Gracias. Desearía poder etiquetar dos respuestas como corrent: p. Sí, ni siquiera quería el efecto de "desvanecimiento", por lo que eliminar eso funciona. Eliminé el desvanecimiento y agregué el evento mostrado.
jdkealy
4

He creado una forma dinámica de llamar a cada evento automáticamente. Es perfecto para enfocar un campo, porque llama al evento solo una vez, eliminándolo después de su 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');
            }
        });
    });
}

Solo necesita llamar modalEvents()al documento listo.

Utilizar:

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

Por lo tanto, puede usar el mismo modal para cargar lo que desee sin preocuparse por eliminar eventos cada vez.

Danilo Colasso
fuente
¡Eso es lo que necesito! ¡Gracias hermano!
Desarrollador
3

Tuve el mismo problema con el bootstrap 3 y lo resolví así:

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

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

Evento de espectáculo modal Bootstrap

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

})

AdminDev826
fuente
-1

Una solución un poco más limpia y más modular podría ser:

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

O usando su ID como ejemplo en su lugar:

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

Espero que ayude..

reanimar
fuente
No existe tal función de éxito.
Avinash