55

I have such problem - I need to autofocus some element inside twitter bootstrap modal (after it shows). The tricky part is here - content of this modal is loaded using 'data-remote' (jQuery.load method) from separate HTML file, so

$(document).on('shown', ".modal", function() {
    $('[autofocus]', this).focus();
});

works only if modal was loaded before.
The question is - how to make autofocus work at the first time modal loads?

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
eawer
  • 1,398
  • 3
  • 13
  • 25

6 Answers6

114

I'm using Bootstrap 3.0 (hopefully, this works with 3.1 as well).

We had to use tabindex="-1" because that allows the ESC key to close the modal.

So I was able to fix this issue using:

// Every time a modal is shown, if it has an autofocus element, focus on it.
$('.modal').on('shown.bs.modal', function() {
  $(this).find('[autofocus]').focus();
});
nc.
  • 7,179
  • 5
  • 28
  • 38
  • 3
    this is the answer for 3.0 and up – Dylan Hayes Oct 17 '14 at 13:06
  • Note if you load content remote through data-toggle link, then you should use event `loaded.bs.modal`, then it will also work then you close and reopen modal. – ksvendsen Feb 01 '16 at 14:38
  • 1
    See also [@paul-oliver's solution](http://stackoverflow.com/a/33323836/44637) if your modal does not exist at the time you create/assign this handler. – nc. Feb 10 '16 at 08:15
  • This answer is correct if the modal markup already exists by the time this JavaScript is executed. If you are working with dynamic markup, see the answer provided by @paul-oliver – Aaron Hudon Sep 05 '17 at 05:46
29

try removing tabindex="-1" and it works fine.

<div class="modal fade" id="modalID" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">

<div class="modal fade" id="modalID" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">

Hope this helps!

nooweel
  • 299
  • 4
  • 3
  • whoa - this was the only answer i found that solved this. in fact, you can just add the autofocus attribute and it will all just work. – drudru Sep 07 '13 at 09:56
  • 2
    When I remove `tabindex="-1"` it is possible to tab out and activate buttons outside of the modal. The solution provided by nc. worked for me. – aimfeld Aug 29 '14 at 10:21
  • 2
    Hi, just wanna double check about this solution, I try this one, it works but just once. Did you guys notice that one? Then I try @nc. answer and it work perfectly even with `tabindex="-1"` – ksugiarto Dec 09 '14 at 15:00
22

I couldn't get @nc's solution working on my app. It didn't see modals that were added later. This worked for me though

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

As Frank Fang points out, you should use this if you are using a newer version of Bootstrap that doesn't rely on the autofocus HTML attribute.

$('#myModal').on('shown.bs.modal', function () {
  // get the locator for an input in your modal. Here I'm focusing on
  // the element with the id of myInput
  $('#myInput').focus()
})
Paul Oliver
  • 7,531
  • 5
  • 31
  • 34
6

Above answers are somewhat outdated for latest Bootstrap versions.

Below is excerpted from: http://getbootstrap.com/javascript/#modals

Due to how HTML5 defines its semantics, the autofocus HTML attribute has no effect in Bootstrap modals. To achieve the same effect, use some custom JavaScript:

$('#myModal').on('shown.bs.modal', function () {
  $('#myInput').focus()
})
Frank Fang
  • 151
  • 2
  • 7
2

The accepted answers handle focusing on the autofocus button in the modal, but don't restore focus to the main page afterwards. This may be undesirable if you're showing the modal from a form that the user expects to submit afterwards by pressing enter.

So here's the complete code that handles both showing and hiding the modal:

// All modals will take enter to mean clicking the button with the autofocus property
$(document).ready(function () {
    $('.modal').on('shown.bs.modal', function() {
        $(this).find('[autofocus]').focus();
    });
    $('.modal').on('show.bs.modal', function(e) {
        var activeElement = document.activeElement;
        $(this).on('hidden.bs.modal', function () {
            activeElement.focus();
            $(this).off('hidden.bs.modal');    
        });
    });
});

Note: This code clears out all event listeners on the modal's hidden.bs.modal event. If you have other listeners for that event, then you'll need to turn the hidden function into a named function that you can reference and remove by reference from the event listeners.

carlin.scott
  • 6,214
  • 3
  • 30
  • 35
0

You have an input with the autofocus attribute you want focused when the bootstrap modal is shown.

Is your modal markup available when JavaScript is loaded?

Register an event handler on all .modal elements for the shown.bs.modal event

$('.modal').on('shown.bs.modal', function() {
  $(this).find('[autofocus]').focus();
});

Is your modal markup dynamically generated?

Register an event handler on the entire document for the shown.bs.modal event.

$(document).on('shown.bs.modal', '.modal', function () {
    $(this).find('[autofocus]').focus();
});
Aaron Hudon
  • 5,280
  • 4
  • 53
  • 60