41

What is the proper method to set the focus to a specific field within a dynamically loaded DIV?

$("#display").load("?control=msgs"); // loads the HTML into the DIV
$('#display').fadeIn("fast"); // display it
$("tex#header").focus();          // ?? neither that
$("input#header").focus();        // ?? nor that
$('#display', '#header').focus()  // ?? nor that
$("#header").focus();             // ?? nor that works

The following HTML is fetched into the display DIV:

<div id="display">
<form id="newHeaderForm" class="dataform" action="/" method="post">
    <input id="to" type="hidden" value="22" name="to"/>
    <dl>
        <dt>Header</dt>
        <dd>
            <input id="header" class="large" type="text" name="header" value="" maxlength="128"/>
        </dd>
 </form>
 </div>

Many, many thanks!

Jan Willem B
  • 3,747
  • 1
  • 22
  • 38
MrG
  • 5,097
  • 17
  • 46
  • 66

10 Answers10

57

The load() function is an asynchronous function. You should set the focus after the load() call finishes, that is in the callback function of load(), because otherwise the element you are referring to by #header, does not yet exist. For example:

$("#display").load("?control=msgs", {}, function() { 
  $('#header').focus();
}); 

I had issues myself even with this solution, so i did a setTimeout in the callback and set the focus in the timeout to make /really/ sure the element exists.

Jan Willem B
  • 3,747
  • 1
  • 22
  • 38
  • 1
    I keep seeing solutions like this in regards to tricky scenarios involving the DOM and being "ready". Is there simply no alternative to calling `setTimeout` for an arbitrary amount of time and hoping that it's enough? It seems to me that such an approach is bound to fail intermittently. This issue was raised recently in a question of mine: http://stackoverflow.com/questions/21191336/getting-chrome-to-prompt-to-save-password-when-dynamically-generating-the-form-a – EleventyOne Jan 20 '14 at 04:45
  • Timeout function also present in Angular. Other syntax, but same solution. Thanks for setting me on the right track with the timeout.`$timeout(function () { $window.document.getElementById('name').focus(); });` – Michel Feb 12 '16 at 08:06
  • The proper amount of time in the Timeout is 0; the purpose is to schedule the 'focus()' code to run immediately after the
    creation code completes. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
    – Stephen Leake May 16 '18 at 08:24
12

Have you tried simply selecting by Id?

$("#header").focus();

Seeing as Ids should be unique, there's no need to have a more specific selector.

Paul Suart
  • 6,003
  • 6
  • 38
  • 60
9

Yes, this happens when manipulating an element which doesn't exist yet (a few contributors here also made a good point with the unique ID). I ran into a similar issue. I also need to pass an argument to the function manipulating the element soon to be rendered.

The solution checked off here didn't help me. Finally I found one that worked right out of the box. And it's very pretty, too - a callback.

Instead of:

$( '#header' ).focus();
or the tempting:
setTimeout( $( '#header' ).focus(), 500 );

Try this:

setTimeout( function() { $( '#header' ).focus() }, 500 );

In my code, testing passing the argument, this didn't work, the timeout was ignored:

setTimeout( alert( 'Hello, '+name ), 1000 );

This works, the timeout ticks:

setTimeout( function() { alert( 'Hello, '+name ) }, 1000 );

It sucks that w3schools doesn't mention it.

Credits go to: makemineatriple.com.

Hopefully, this helps somebody who comes here.

Arta
  • 4,727
  • 5
  • 22
  • 23
  • The setTimeout seemingly helps even when the element well and truly exists before the invocation of `.focus()`. The value of 500 is probably overblown, though. Works fine for me with 10 :) – Nick Aug 17 '13 at 05:01
3

If

$("#header").focus();

is not working then is there another element on your page with the id of header?

Use firebug to run $("#header") and see what it returns.

Daniel
  • 22,521
  • 12
  • 107
  • 150
Bela
  • 3,338
  • 1
  • 18
  • 12
3
$("#display").load("?control=msgs", {}, function() { 
  $('#header').focus();
});

i tried it but it doesn't work, please give me more advice to resolve this problem. thanks for your help

xman
  • 31
  • 1
  • Did you set the ID of the field like ? Test your code in Firefox and enable the Error Console or in Chrome with a breakpoint at the right place, this might help. – MrG Jun 29 '10 at 10:24
2

As Omu pointed out, you must set the focus in a document ready function. jQuery provides it for you. And do select on an id. For example, if you have a login page:

$(function() { $("#login-user-name").focus(); }); // jQuery rocks!
Christian Specht
  • 33,837
  • 14
  • 123
  • 176
1

This runs on page load.

<script type="text/javascript">
    $(function () {
        $("#header").focus();
    });
</script>
bluish
  • 23,093
  • 23
  • 110
  • 171
IAmGroot
  • 13,301
  • 18
  • 72
  • 146
1

Dynamically added items have to be added to the DOM... clone().append() adds it to the DOM... which allows it to be selected via jquery.

Daniel
  • 22,521
  • 12
  • 107
  • 150
BCnuckles
  • 11
  • 1
0
$("#header").attr('tabindex', -1).focus();
Rob Hruska
  • 111,282
  • 28
  • 160
  • 186
ashu
  • 9
  • 1
0
$(function (){
    $('body').on('keypress','.sobitie_snses input',function(e){
        if(e.keyCode==13){
            $(this).blur();
            var new_fild =  $(this).clone().val('');
            $(this).parent().append(new_fild);
            $(new_fild).focus();
        }
    });
});

most of error are because U use wrong object to set the prorepty or function. Use console.log(new_fild); to see to what object U try to set the prorepty or function.

Andrew Barber
  • 37,547
  • 20
  • 91
  • 118
skinny
  • 1
  • 1