102

When ever I do onchange event, its going inside that function its validating, But focus is not comming I am using document.getElementById('controlid').focus();

I am using Mozilla Firefox and Google Chrome, in both its not working. I don't want any IE. Can any one tell me what could me the reason.

Here's the code:

var mnumber = document.getElementById('mobileno').value; 
if(mnumber.length >=10) {
    alert("Mobile Number Should be in 10 digits only"); 
    document.getElementById('mobileno').value = ""; 
    document.getElementById('mobileno').focus(); 
    return false; 
}
starball
  • 20,030
  • 7
  • 43
  • 238
SKSK
  • 1,203
  • 2
  • 11
  • 12
  • 1
    Please post some code so we can see what's going on. Also, try and clean up your question a little. – Andy E Jul 08 '09 at 07:09
  • Are you doing this in the onload handler? – Maurice Perry Jul 08 '09 at 07:17
  • Ok.. I am doing mobile no. validation, in that onchange event I written like this var mnumber= document.getElementById('mobileno').value; if(mnumber.length >=10){ alert("Mobile Number Should be in 10 digits only"); document.getElementById('mobileno').value=""; document.getElementById('mobileno').focus(); return false; } here if any one enters digits less than 10 it will show alert and clear the text field after that the focus is going next field, I am trying to give in same field its not comming for Mozilla and crome. – SKSK Jul 08 '09 at 07:17
  • did u add 'index' attribute to ur html? – Alberto Acuña Nov 19 '18 at 12:00

19 Answers19

142

Try using a timer:

const id = "mobileno";
const element = document.getElementById(id);
if (element.value.length >= 10) {
    alert("Mobile Number Should be in 10 digits only");
    element.value = "";
    window.setTimeout(() => element.focus(), 0);
    return false;
}

A timer with a count of 0 will run when the thread becomes idle. If that doesn't help, try the code (with the timer) in the onblur event instead.

Ninjakannon
  • 3,751
  • 7
  • 53
  • 76
Andy E
  • 338,112
  • 86
  • 474
  • 445
  • 1
    I don't like not to understand because I forget everything but when I understand something I JUST UNDERSTAND IT and I don't need to remember it. So I have a question for @AndyE, where did you learn that? I would loooove to read about javascript specifications I know that implementations will not necessarily follow but when you say "_will run when the thread becomes idle_" I immediately understood why it wasn't working. So I would like to learn about internals. – Iharob Al Asimi Aug 08 '15 at 19:49
  • 1
    Wanting to dig this up but yeah as some concerns above, why does this work? – Gerry Mar 14 '18 at 11:16
  • 2
    An explanation can be found here https://stackoverflow.com/questions/33955650/what-is-settimeout-doing-when-set-to-0-milliseconds/33955673 and here https://stackoverflow.com/questions/779379/why-is-settimeoutfn-0-sometimes-useful – Ted Whitehead May 06 '18 at 02:30
  • This is also a really good visual representation of the JS event loop https://blog.sessionstack.com/how-javascript-works-event-loop-and-the-rise-of-async-programming-5-ways-to-better-coding-with-2f077c4438b5 – Ted Whitehead May 06 '18 at 02:42
  • @AndyE Soooper curious to know exactly how it works any refer please??? – ezio4df Jun 21 '20 at 16:37
  • +1. For me, using AngularJS, my problem seemed to be that an `md-tab` transition was preventing `focus()` from working unless I used `window.setTimeout` with 200 ms. – Ryan Aug 14 '20 at 21:27
77

2 things to mention if focus() not working:

  • use this function after appending to parent
  • if console is selected, after refreshing page, element will not gain focus, so select (click on) the webpage while testing

This way works in both Firefox and Chrome without any setTimeOut().

40

My case was a bit different. I was trying to focus() an input from within a browser developer console. Turns out it was interfering with the input somehow, and once I minimized the console everything worked as expected. I understand this isn't a programmatical solution, but in case someone found this on a search engine jist like I did, there's a chance this information might help.

ᴍᴇʜᴏᴠ
  • 4,804
  • 4
  • 44
  • 57
38
window.setTimeout(function () { 
    document.getElementById('mobileno').focus(); 
}, 0); 

This worked for me also. Firefox would set the value of my element, but not give focus to it.

Mihai Iorga
  • 39,330
  • 16
  • 106
  • 107
Robin B
  • 571
  • 6
  • 10
  • The easy solution for me was this, though with a 500ms delay. I guess something tries to steal the focus and its probably possible to dig further and determine who/what it is. – Chau Jan 19 '22 at 11:57
27

Not all elements are focusable but default, there is a tabindex attribute to fix that.

When you assign tabindex= to an element:

It becomes focusable. A user can use the tab key to move from the element with lesser positive tabindex to the next one. The exception is a special value tabindex="0" means that the element will always be last. The tabindex=-1 means that an element becomes focusable, but the tab key will always skip it. Only the focus() method will work

  • 1
    Great explanation.fixed all my tabIndex issues – Guy Sopher Jun 18 '17 at 12:04
  • This fixed it. Using window.setTimeout or closing the console might fix the issue temporarily, but should still use tabindex for safety. – Akaisteph7 Apr 12 '21 at 20:55
  • 'tabindex="0" means that the element should be focusable in sequential keyboard navigation, after any positive tabindex values and its order is defined by the document's source order.' https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex – Alex Dec 06 '22 at 12:46
12

One more thing to add to this list to check:

Make sure the element you are trying to focus is not itself nor is contained in an element with "display: none" at the time you are trying to focus it.

justFatLard
  • 482
  • 5
  • 9
4

For getting back focus to retype password text box in javascript:

window.setTimeout(function() { document.forms["reg"]["retypepwd"].focus(); },0);

Here, reg is the registration form name.

Code Maverick
  • 20,171
  • 12
  • 62
  • 114
veena
  • 41
  • 1
4

I suspect the reason this works is the browser rendering runs on the same thread as javascript, and setTimeout(function(){},0); queues the javascript function inside setTimeout to execute when the browser becomes idle. If anyone has a more in-depth explanation please share it.

setTimeout(function(){ 
 if(document.getElementById('mobileno')){
  document.getElementById('mobileno').focus();
 } 
},0);
3

The timeout suggested above worked around the issue on Chrome. No issue exists on IE8 or FF3.

My code that to set focus that worked is:

window.setTimeout(function() {
  document.form1.password.focus();
}, 0);
JMP
  • 4,417
  • 17
  • 30
  • 41
Don
  • 69
  • 2
  • 6
  • Thanks for keeping me from banging my head against anything solid and big. This did the trick for me. – LongHike Feb 09 '22 at 16:42
2

I know this may be an esoteric use-case but I struggled with getting an input to take focus when using Angular 2 framework. Calling focus() simply did not work not matter what I did.

Ultimately I realized angular was suppressing it because I had not set an [(ngModel)] on the input. Setting one solved it. Hope it helps someone.

parliament
  • 21,544
  • 38
  • 148
  • 238
2

I also faced this type of problem in vue js.

I fixed this problem using vue $nextTick method Vue 2

this.$nextTick(() => {                      
    this.$refs['ref-name'].focus(); 
});

you can use it inside of vue js mounted lifecycle hooks.

Hasibur Rahman
  • 641
  • 2
  • 7
  • 18
  • 2
    The question is not tagged with vue js. as such it's unlikely that people will find this answer (useful) – phuzi Aug 31 '21 at 13:55
  • 1
    This does not really answer the question. If you have a different question, you can ask it by clicking [Ask Question](https://stackoverflow.com/questions/ask). To get notified when this question gets new answers, you can [follow this question](https://meta.stackexchange.com/q/345661). Once you have enough [reputation](https://stackoverflow.com/help/whats-reputation), you can also [add a bounty](https://stackoverflow.com/help/privileges/set-bounties) to draw more attention to this question. – StevenSiebert Sep 01 '21 at 16:56
  • well, I did find it useful. Most frameworks have a `tick` situation and due to that element not focusing. – anakha Oct 27 '21 at 04:15
  • This topic was the first thing i found when looking for a solution, i also use Vue (3) so this answered my question. +1 – eXXecutor Jul 20 '22 at 10:53
1

Are you trying to reference the element before the DOM has finished loading?

Your code should go in body load (or another function that should execute when the DOM has loaded, such as $(document).ready() in jQuery)

body.onload = function() { 
    // your onchange event handler should be in here too   
    var mnumber = document.getElementById('mobileno').value; 
    if(mnumber.length >=10) {
        alert("Mobile Number Should be in 10 digits only"); 
        document.getElementById('mobileno').value = ""; 
        document.getElementById('mobileno').focus(); 
        return false; 
    }    
}
Russ Cam
  • 124,184
  • 33
  • 204
  • 266
1

Make sure you use "id" and "getElementById" as shown here:

<FORM id="my_form" name="my_form" action="">
<INPUT TYPE="text" NAME="somefield" ID="somefield" onChange="document.getElementById('my_form').submit();">
</FORM>
Westchaser
  • 11
  • 1
1

One thing to check that I just found is that it won't work if there are multiple elements with the same ID. It doesn't error if you try to do this, it just fails silently

joejknowles
  • 350
  • 2
  • 12
1

Add a control, where you want to set focus then change its property like below

<asp:TextBox ID="txtDummy" runat="server" Text="" Width="2" ReadOnly="true" BorderStyle="None" BackColor="Transparent"></asp:TextBox>

In the codebehind, just call like below txtDummy.Focus()

this method is working in all browser.

Leo
  • 37,640
  • 8
  • 75
  • 100
Tamilvanan
  • 19
  • 1
0

Your focus is working before return false; ,After that is not working. You try this solution. Control after return false;

Put code in function:

function  validateNumber(){
    var mnumber = document.getElementById('mobileno').value; 
    if(mnumber.length >=10) {
        alert("Mobile Number Should be in 10 digits only"); 
        document.getElementById('mobileno').value = ""; 
        return false; 
    }else{
        return true;
    }
}

Caller function:

function submitButton(){
        if(!validateNumber()){
            document.getElementById('mobileno').focus();
            return false;
        }
}

HTML:

Input:<input type="text" id="mobileno">
<button onclick="submitButton();" >Submit</button>
0

Place this source above your modal :

<script>
$('body').on('shown.bs.modal', '#IdYourModal', function () {
    document.getElementById('mobileno').focus();
})
</script>
neTurmeric
  • 31
  • 2
0

I was trying to use .focus() to move my scroll position so the target element was visible.

Turns out that .focus() isn't designed to do this - it's for "focusing" on a form element, or at least something that's focusable (such as an <a>).

The correct function to call was .scrollIntoView().

document.getElementById('mobileno').scrollIntoView(); 
harvzor
  • 2,832
  • 1
  • 22
  • 40
-1

Try location.href='#yourId'

Like this:

<button onclick="javascript:location.href='#yourId'">Show</button>
Ananth
  • 1,798
  • 2
  • 11
  • 8