183

I've seen a couple of questions in regards to bootstrap modals, but none exactly like this, so I'll go ahead.

I have a modal that I call onclick like so...

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

This works fine, but when I show the modal I want to focus on the first input element... In may case the first input element has an id of #photo_name.

So I tried

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

But this was to no avail. Lastly, I tried binding to the 'show' event but even so, the input won't focus. Lastly just for testing, as I had a suspiscion this is about the js loading order, I put in a setTimeout just to see if I delay a second, will the focus work, and yes, it works! But this method is obviously crap. Is there some way to have the same effect as below without using a setTimeout?

  $("#modal-content").on('show', function(event){
    window.setTimeout(function(){
      $(event.currentTarget).find('input#photo_name').first().focus()
    }, 0500);
  });
ryanpcmcquen
  • 6,285
  • 3
  • 24
  • 37
jdkealy
  • 4,807
  • 6
  • 34
  • 56

11 Answers11

372

Try this

Here is the old DEMO:

EDIT: (Here is a working DEMO with Bootstrap 3 and jQuery 1.8.3)

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

Starting bootstrap 3 need to use shown.bs.modal event:

$('#modal-content').on('shown.bs.modal', function() {
    $("#txtname").focus();
})
Jonathan
  • 1,126
  • 10
  • 19
gaurang171
  • 9,032
  • 4
  • 28
  • 30
  • 4
    Thank you. I had not seen the "shown" event. Exactly what I was looking for. – jdkealy Aug 31 '12 at 16:58
  • thanks! the demo doesn't working anymore but the snippet does. – Kreker Mar 05 '14 at 10:42
  • @keyur at codebins.com This event starts after modal is displaying, what if I have to starts event before modal is displayed – Thomas Shelby Sep 04 '15 at 12:51
  • okej, I should use 'show.bs.modal' instead of 'shown.bs.modal' – Thomas Shelby Sep 04 '15 at 12:54
  • about the focus handler, it requires a bit delay so you must but it in a setInterval stuff like this: setInterval(function() { $("#your-input").focus(); }, 50); – Nguyen Minh Hien Jul 08 '17 at 06:05
  • I too had to call `focus` after a small delay -- but you'll wont to use *`setTimeout`*, not `setInterval` (as the latter will call your code -- `focus` -- over and over, and your user will not be able to remove focus from that field). – Chris W. Aug 16 '17 at 18:40
  • How to achieve this if there are 5-6 bootstrap modal, I am using this code for first input field(not disabled-hidden-readonly) but its not working... `$(document).on('shown.bs.modal', function () { var firstInput = $(this).find('form:first *:input[type!=hidden]:not(:disabled):not([readonly]):first'); firstInput.focus(); });` – Abhinav Gupta Jul 02 '18 at 11:04
  • @gaurang171: This shown method gets called in numerous time when I try to show any tool tip on modal. – Vandita Apr 03 '19 at 08:53
75

Just wanted to say that Bootstrap 3 handles this a bit differently. The event name is "shown.bs.modal".

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

or put the focus on the first visible input like this:

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

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

Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
David Beck
  • 975
  • 8
  • 12
10

I am using this in my layout to capture all modals and focus on the first input

  $('.modal').on('shown', function() {
     $(this).find('input').focus();
  });
Joe Beams
  • 185
  • 1
  • 1
  • 8
9

I had the same problem with bootstrap 3, focus when i click the link, but not when trigger the event with javascript. The solution:

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

Probably it´s something about the animation!

Alejandro Fiore
  • 1,117
  • 14
  • 18
  • There is definitely something going on with the modal animation. Even if I turn the modal fade off in the options, it will not render if there is a CPU intensive task right after the modal popup. Using this timeout is the only way I can get it to work. – krx Jun 09 '15 at 18:02
8

I had problem to catch "shown.bs.modal" event.. And this is my solution which works perfect..

Instead simple on():

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

Use on() with delegated element:

$('body').on 'shown.bs.modal', '#modal', ->
Michal Macejko
  • 370
  • 4
  • 8
6

Seems it is because modal animation is enabled (fade in class of the dialog), after calling .modal('show'), the dialog is not immediately visible, so it can't get focus at this time.

I can think of two ways to solve this problem:

  1. Remove fade from class, so the dialog is immediately visible after calling .modal('show'). You can see http://codebins.com/bin/4ldqp7x/4 for demo. (Sorry @keyur, I mistakenly edited and saved as new version of your example)
  2. Call focus() in shown event like what @keyur wrote.
SAPikachu
  • 579
  • 1
  • 3
  • 17
  • Thank you. I wish I could tag two answers as corrent :p. Yes, I didn't even want the "fade" in effect, so removing that works. I removed fade and added the shown event. – jdkealy Aug 31 '12 at 17:00
4

I've created a dynamic way to call each event automatically. It perfect to focus a field, because it call the event just once, removing it after use.

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

You just need to call modalEvents() on document ready.

Use:

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

So, you can use the same modal to load what you want without worry about remove events every time.

Danilo Colasso
  • 2,360
  • 17
  • 11
3

I had the same problem with the bootstrap 3 and solved like this:

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

$('#myModal').modal('show').trigger('shown');
edercortes
  • 379
  • 4
  • 6
0

Bootstrap has added a loaded event.

https://getbootstrap.com/docs/3.3/javascript/#modals

capture the 'loaded.bs.modal' event on the modal

$('#mymodal').on('loaded.bs.modal', function(e) {
  // do cool stuff here all day… no need to change bootstrap
})
bharat
  • 1,762
  • 1
  • 24
  • 32
0

Bootstrap modal show event

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

})

AdminDev826
  • 330
  • 4
  • 15
-1

A little cleaner and more modular solution might be:

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

Or using your ID as an example instead:

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

Hope that helps..

revive
  • 831
  • 2
  • 15
  • 31