70

Just starting to play around with bootstrap and it's amazing.

I'm trying to figure this out. I have a textarea for feedback inside a modal window. It works great. But I want the focus to go on the textarea when you click on the button to activate the modal. And I can't seem to get it working.

Here is a fiddle: http://jsfiddle.net/denislexic/5JN9A/4/

Here is the code:

<a class="btn testBtn" data-toggle="modal" href="#myModal" >Launch Modal</a>

<div class="modal hide" id="myModal">
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal">×</button>
    <h3>Modal header</h3>
  </div>
  <div class="modal-body">
      <textarea id="textareaID"></textarea>
  </div>
  <div class="modal-footer">
    <a href="#" class="btn" data-dismiss="modal">Close</a>
    <a href="#" class="btn btn-primary">Save changes</a>
  </div>
</div>​

Here is the JS

$('.testBtn').on('click',function(){
    $('#textareaID').focus();
});​

To resume When I click on "Launch modal" I want the modal to show up and the focus to go on the textarea.

Thanks for any help.

user2771704
  • 5,994
  • 6
  • 37
  • 38
denislexic
  • 10,786
  • 23
  • 84
  • 128
  • Possible duplicate of [Twitter bootstrap modal input field focus](http://stackoverflow.com/questions/15474862/twitter-bootstrap-modal-input-field-focus) – Muhammad Rehan Saeed Oct 13 '15 at 13:48

13 Answers13

209

It doesn't work because when you click the button the modal is not loaded yet. You need to hook the focus to an event, and going to the bootstrap's modals page we see the event shown, that is fired when the modal has been made visible to the user (will wait for css transitions to complete). And that's exactly what we want.

Try this:

$('#myModal').on('shown', function () {
    $('#textareaID').focus();
})
​

Here's your fiddle updated: http://jsfiddle.net/5JN9A/5/


Update:

As @MrDBA notes, in Bootstrap 3 the event name is changed to shown.bs.modal. So, for Bootstrap 3 use:

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

New fiddle for Bootstrap 3: http://jsfiddle.net/WV5e7/

Community
  • 1
  • 1
scumah
  • 6,273
  • 2
  • 29
  • 44
  • 11
    Heads-up: If your modal has a 'fade' property, this approach may not work, depending on what seem to be some pretty obscure timing conditions (i.e., where the modal doesn't exist enough to accept the focus request until it's completely faded in). I was only able to set focus on a modal item by dropping the fade property, at which point I could just do a $('#textareaID').focus() call right after the .show() call. YMMV, I suppose... – Jim Miller Oct 22 '12 at 19:48
  • 1
    Thanks Jim, it was really annoying me why the focus wasn't being set but it was because I had a fade in. Would be great if there were a work around. – chrisb Jan 30 '13 at 10:47
  • @chrisb you mean adding a `fade` class to your modal? It's working for me: http://jsfiddle.net/5JN9A/16/ If I could see a failing example I could try to find a workaround :P – scumah Jan 30 '13 at 15:53
  • 6
    FYI Bootstrap v3 has changed the event name to shown.bs.modal – MrDBA Aug 21 '13 at 01:15
  • StackOverflow is so awesome that I got here and @MrDBA commented 2 hours ago about Bootstrap change for v3. Thanks buddy! :) Almost realtime coding FTW! – Leniel Maccaferri Aug 21 '13 at 04:07
  • For some reason the $('#passwordModal').focus(); isn't setting focus to my . Even running in console after the modal is way done with transitions. – Stephen Smith Nov 08 '13 at 14:42
  • If I have content loaded remotely to the modal, and in that content I have `$('document').ready(function(){` isn't that supposed to work? – mgPePe Mar 04 '14 at 18:19
  • 6
    Pay attention to event name. It must be 'shown.bs.modal', not 'show.bs.modal'. And btw setting focus from console in Chrome doesn't work because page window is not active. To work around it you can use setTimeout – S3RK Jun 30 '15 at 17:02
23

I wanted to have a declarative version of this, so I went with the following :

$(document).ready(function() {
    $(".modal").on('shown.bs.modal', function () {
        $("[data-modalfocus]", this).focus();
    });
});

You can then simply add a data-modalfocus property to your field, like so :

<input type="text" data-modalfocus />

And when the modal pops-up, your field will get focus.

Legionar
  • 7,472
  • 2
  • 41
  • 70
Alexandre Roger
  • 971
  • 7
  • 8
11

Bootstrap3

$(window.document).on('shown.bs.modal', '.modal', function() {
    window.setTimeout(function() {
        $('[autofocus]', this).focus();
    }.bind(this), 100);
});

Bootstrap 2

$(window.document).on('shown', '.modal', function() {
    window.setTimeout(function() {
        $('[autofocus]', this).focus();
    }.bind(this), 100);
});
4

You can use the autofocus html element to set the autofocus.

<textarea id="textareaID" autofocus="" ></textarea>

Fiddle here (Click)

Chancho
  • 1,930
  • 2
  • 15
  • 20
  • 9
    This works only for the first time. When dialog is closed (hidden) and shown again, field doesn't receive focus. – nevermind Oct 16 '14 at 16:37
1

If your modal has the 'fade' property:

This will work but you might have to adjust the duration of the timeout and obviously the IDs where needed:

$("#ID-of-modal").on('show', function(event){
                window.setTimeout(function(){
                  $(event.currentTarget).find('input#ID-of-input').first().focus()
                }, 0175);
              });
Semaj Nekeerv
  • 141
  • 2
  • 7
1

I was having major issues in chrome... I hope this helps someone.

//When user clicks link
$('#login-modal-link').on('click',function() {
        setTimeout(function(){
                //If modal has class
            if ($('#login-modal').hasClass('modal')) {
                //Whatever input you want to focus in
                $('#user_login_modal').focus();
            }
        },100);

    });
Davis
  • 2,937
  • 3
  • 18
  • 28
1

As mentioned in one of the comments you need to remove fade from your modal. So this works for me:

 <div id="myModal" class="modal">
    ...
    <textarea class="form-control" rows="5" id="note"></textarea>
  </div>

  <script>
    $('#myModal').on('shown.bs.modal', function () {
        $('#note').focus();
    })
  </script>
tokhi
  • 21,044
  • 23
  • 95
  • 105
1

I wanted something a bit more generic

    $(window.document).on('shown.bs.modal', '.modal', function () {
        var timer = window.setTimeout(function () {
            $('.firstInput', this).focus();
            typeof timer !== 'undefined' && window.clearTimeout(timer);
        }.bind(this), 100);
    });

With this, I give whatever control I want the CSS class firstInput. There is a slight delay in setting focus that gives it a certain flair.

John Grabauskas
  • 310
  • 2
  • 5
0

I don't know why, but the choosed solution doesn't work for me.. I use the following code snippet instead:

$('#annul-modal').on('show', function() {
    setTimeout(function() {$('textarea:first', '#annul-form').focus();}, 400);
});

I know it isn't so pretty but at least it works.. Bootstrap v2.3.0

nKognito
  • 6,297
  • 17
  • 77
  • 138
0

If you are using bootstrap v3 and you are using both modal dialog and wysihtml5 text editor the following works (assuming #basic is the ID of your modal form):

    $('#basic').on('shown.bs.modal', function () {
    editor.composer.element.focus()
})
Ryan
  • 804
  • 1
  • 11
  • 24
0

Attaching the event directly to the modal screen didn't work for me. I'm using this code instead:

$('body').on('shown.bs.modal', '.modal', function () {
  $('[id$=myField]').focus();
})

With this code I only need to change myField for the id of the control I want to have the focus, it also allows me to define the focus for multiple modal screens, I have something like:

      $('body').on('shown.bs.modal', '.modal', function () {
        $('[id$=YesCancel]').focus();
        $('[id$=YesInverted]').focus();
        $('[id$=cancelAddCustomer]').focus();
        $('[id$=closeHistoryModal]').focus();
      });

Source http://xcellerant.net/2014/08/06/set-focus-on-a-field-when-showing-a-bootstrap-3-modal/

J.J
  • 881
  • 16
  • 29
  • 1
    Why not use direct $('#myField').focus ? – Yves Martin Jan 20 '16 at 07:44
  • @YvesMartin You are right, There should only be one id with the same name, and there for it should be selected as you point out – J.J Jan 21 '16 at 07:48
  • Yes! That works. I was trying the `"shown.bs.modal"` directly on the modal (i.e. `"#modalName"`) and the event was not being triggered. Moving it to the body works. Unfortunate since that means you do not really know which modal gets triggered without testing that... or as you do, set the focus of the first item of any modal you have. – Alexis Wilke May 10 '17 at 18:25
0

Found doing:

$(document).on('shown.bs.modal', function () {
  $(this).find('.form-control:visible:first').focus();
});

Worked well as it just finds the first form-control rather than needing a specific id etc. Be just what is needed most of the time.

SimonKiteley
  • 359
  • 3
  • 8
-1
<a href="" id="btnmoverCategoriaRaiz">Mover para a raiz...</a> 
      <script>
         $(function(){
            $("#btnmoverCategoriaRaiz").click(function(){
                $("#novoPlaylist").modal();
                return false;
            });
         });

       </script>    
 <div id="novoPlaylist" class= "modal  hide">
          <div class="modal-header">
            <h3>Novo Playlist</h3>
          </div>
          <div class="modal-body">
            <form class="form-horizontal">
              <?echo $form->input("Playlist.nome", array("label"=>"Nome:")) ?>
            </form>
          </div>
              <div class="modal-footer">
                 <a href="javascript:;" class="btn" data-dismiss="modal">Cancelar</a>
                 <a href="javascript:;" class="btn btn-primary" id="SalvarNomePlaylist" data-loading-text="Aplicando..."> Savar</a>
              </div>
      </div>
Smern
  • 18,746
  • 21
  • 72
  • 90
  • 3
    you should include some comments on exactly what you did rather than force people to try and hunt down the changes – Smern Oct 11 '13 at 12:24