16

I am developing webapp using jQuery. I have functionality that adds new row of 3 input fields. After creating these DOM elements I want to focus one of input fields. I am doing it with calling jQuery focus() function on necessary input field.

Problem is that calling focus() works fine in IE6 and FF3.5, but not working in IE8.

I was trying to make simple working example of this problem for showing it here, but with stripped version of code focus() is working fine. So my guess was that DOM is not ready yet when I call focus() in IE8. For this I tried calling setTimeout('myFocus()',400). I had success and in some of cases focus was really working but still not always. Randomly it does not focus my input field.

Question is: Has anybody faced similar problems and does anybody have any idea how to workaround it? Using setTimeout feels like very ugly workaround.

Tnx in advance

Edited : 26.08.2009

Succeeded to reproduce on simple example. Here is HTML+JS code that reproduces this bug on IE8.

<html>
<head>
    <script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
    <script type="text/javascript">
        function performChanged() {
          formChanged = true;
        }

        function handleChange() {
          var parentDiv = $('#container');
          newValue = $(html).html();

          parentDiv.html(newValue);
          $(".sel1",parentDiv).bind('change',handleChange);
          //alert('Uncomment this and after alert focus will be on input');
          $("input.cv_values",parentDiv).focus();
        }

        $(document).ready(function() {
          $('.trackChange').bind('change', handleChange);
        });
        var html = '<div class=\"div1\">\n<select class=\"sel1\" id=\"sel1\" name=\"sel1\"><option value=\"\"><\/option>\n<option value=\"11\">Select me to see problem<\/option>\n<\/select>\n\n\n<input class=\"cv_values\" id=\"sel3\" name=\"sel3\" size=\"30\" type=\"text\" value=\"\" /><br/>Focus should in input field. With alert it is but without alert focus is not there</div>';
    </script>
</head>
<body>
    <select class="trackChange" onchange='performChanged();'>
      <option value=""></option>
      <option value="1" >Select me to generate new inputs</option>
    </select>

    <div id="container"></div>
</body>

To reproduce: 1) select value from first dropdown. You will see that first time input is working 2) select value from second dropdown. You will see that bug is reproduced.

Then in code you can comment out line where it shows JS alert(). Strange thing is that if there is this alert() then after it focus is working fine.

Hope this helps to understand where my problem is.

P.S. I need my app to work this way - it is regenerating those inputs after selecting value from dropdown. This is simplified example of my app ;).

oskarae
  • 520
  • 2
  • 5
  • 16

7 Answers7

30

I had a similar problem with my app, but I can't reproduce the focus problem with your code. My problem was slightly different in that my page had a link hash that made IE not give my element focus.

Anyway, to get around the problem I added a timeout:

setTimeout(function () {
  $('.my-thing').focus();
}, 100);

Not noticeable by a user but it gives IE a moment to breathe.

Ponny
  • 703
  • 9
  • 17
  • Do you know why this solution works? (Oh, thanks. It definitely works.) – jjnguy Sep 15 '11 at 14:43
  • 1
    From some [ancient documentation](http://javascript.gakaa.com/div-focus-4-0-5-.aspx): To give a text box focus and pre-select all the text in the box, use the sequence of focus() and select() methods on the element. If this sequence is to occur after windows change (such as after an alert dialog box closes), place the methods in a separate function, and invoke this function through the setTimeout() method following the alert() method for the dialog. This allows IE/Windows to sequence statement execution correctly. – davidchambers Nov 18 '11 at 00:45
  • Thanks for the workaround. Ugly fix, but I can't find any more elegant solutions.. Would love an explanation if anyone finds one! In my case, it seems to work even with only a 1 msec timeout, not that either 1 or 100 msec is noticeable to the user :) – thetoolman May 20 '12 at 18:30
8

In conjunction with Kazys's solution, I found this to fix all my problems (using IE8 & .HTA files):

$("elem").blur();
$("elem").focus().focus();

I have no idea why, but somehow calling focus twice helps IE along.

EDIT: I have found that calling .show() and .select() can also help.

Max Mayhem
  • 165
  • 2
  • 10
6

Strangely i had the same problem and resolved it using plain old javascript like so:

document.getElementById('friend_name').focus();

Using jQuery equivalent $('#friend_name').focus(); didn't work in IE8 :-/

lmmendes
  • 1,480
  • 15
  • 14
4

Had similar problem with IE8. I wanted to focus input in dialog when it is opened. Used autoOpen = false. Noticed that focus doesn't work only for first focusable element in dialog. Tried setTimeout but it worked only sometimes. Blurring element before focusing helped me.

$('#dialog').find('#name').blur();
$('#dialog').find('#name').focus();
Kazys
  • 377
  • 2
  • 12
1

Since you have not posted any code are you using:

$(document).ready(function(){
    //code here
});

This will make javascript run after the html is loaded.

And you should use live events also. When your adding inputs to the dom the will automatically have focus binded to them.

$("p").live("focus", function(){
   alert( $(this).text() );
});

This means that every p that is created will have a focus binded to it.

MrHus
  • 32,888
  • 6
  • 31
  • 31
  • I want to focus some input but I do not need to be aware of that focus event. P.S. jQuery current stable version does not support live for "focus" event. – oskarae Aug 26 '09 at 16:57
1

This is the best solution for the moment to set focus:

$('.elt').fadeIn(200, function() {$('.elt').focus();});

elhadi dp ıpɐɥןǝ
  • 4,763
  • 2
  • 30
  • 34
0

This is an old question, but it is top in search, so wanted to update.

I don't know if there was ever a time that it was fixed, but I ran into this issue again today in IE11, using jquery-2.1.3. I found that wrapping the focus call in a setTimeout, as set out by Ponny above, worked best for me.

I did need to increase the timeout in some cases, to get it to work.

devRyan
  • 373
  • 4
  • 12