kudos-dude
kudos-dude

Reputation: 61

Bootstrap Modal inputs lose focus on click

I am working on 2 bootstrap modals that both lie on the same page. Bootstrap 2.3.2

The issue I'm experiencing is that whenever the modal appears, the first time you click on any of the inputs in the modal, it will immediately lose focus. After that, focus functions fine, it's just the first time.

I've found some similar issues out there, but none of their solutions have worked for me so far. Here's what I've tried:

1.)

$('#Modal').focus(function (e) {
        e.preventDefault();
});

2.) Something about removing an "in" class on the modal, which mine doesn't have

3.) Trying to comment out a part of the bootstrap code, which isn't an ideal solution anyways, couldn't find the exact piece of code but something similar, but that didn't work.

4.) Both setting focus on an input (which works until something is clicked), and preventing default again.

$('#Modal').on('shown', function (e) {
        e.preventDefault();
        $('#textArea').focus();
});

I've pretty much exhausted google at this point, and I can't think of a way to even debug why this is happening. Either an answer or a suggested route to try would be greatly appreciated.

Upvotes: 2

Views: 5252

Answers (2)

Dylan
Dylan

Reputation: 13859

I encountered this exact issue, and I think I've got it figured out.

What went wrong

I'm guessing that your modal was set up with the "fade" class so that it will transition in and out, but the very first transition in was not doing the nice "slide" effect. That's what was happening for me, at least.

It all boiled down to this code in bootstrap.js's Modal class (in the show function):

var transition = $.support.transition && that.$element.hasClass('fade')
...
transition ?
  that.$element.one($.support.transition.end, function () {
    that.$element.focus().trigger('shown') 
  }) :
  that.$element.focus().trigger('shown')

What this means is that if you want transitions on your modal, it will wait for the "transition end" event before forcing focus on the modal and triggering its "shown" event.

Since the very first intro transition was not actually transitioning, it never fired a transition end event, so that callback just sat around waiting for the next one, which ended up coming from the blue glow effect on the text box as it gained focus.

The text box's glow transitioned in, firing a transition end event, which got caught by the bootstrap transition end handler, which at that point forced focus on the modal's element, and triggered the "shown" event.

Remediation

For me, fixing the issue boiled down to removing the "in" class on my modal element, but you mentioned in point #2 that you didn't have that.

A more general-purpose fix that might work for you is to stop the transition end event from bubbling up to the point where the modal's listener will hear it. Something along the lines of this:

$textField.on($.support.transition.end, function(e){
  e.stopPropagation()
})

This way, the modal will hopefully get some other transition end event (e.g. when it transitions out, you might see it firing the "shown" event at that point), at which point it gets back in sync with itself (which explains why it only ever happened the very first time you opened the modal).

I hope this works for you too! I know the question is over a year old, but maybe it will scratch that year-old curiosity itch ;)

Upvotes: 2

ewitkows
ewitkows

Reputation: 3618

Ran into the same problem, it seems related to Bootstraps "blue highlight on focus" functionality. Personally I didn't care about losing it, but admittedly couldn't find a way to "disable" the style using "!important", applying none styles, etc. So in the end, it's a workaround, but it did resolve this particular issue...

To work around, I commented out the CSS in my bootstrap.css file that applied to the focus pseudoclass for input elements:

/*
textarea:focus,
input[type="text"]:focus,
input[type="password"]:focus,
input[type="datetime"]:focus,
input[type="datetime-local"]:focus,
input[type="date"]:focus,
input[type="month"]:focus,
input[type="time"]:focus,
input[type="week"]:focus,
input[type="number"]:focus,
input[type="email"]:focus,
input[type="url"]:focus,
input[type="search"]:focus,
input[type="tel"]:focus,
input[type="color"]:focus,
.uneditable-input:focus {
  border-color: rgba(82, 168, 236, 0.8);
  outline: 0;
  outline: thin dotted \9;

  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
} */

Upvotes: 0

Related Questions