18

Edit: If you have not developed on Windows 8, do not try to answer this question. Do not vote on it. Do not even read it. This is not a web app or website and does not run in a browser. Please stop down-voting content you do not understand. This is a Windows 8 METRO HTML5/js application that runs in the Windows Runtime environment.

Original Question:

I want the cursor to be "blinking" in the input box, ready to receive input. I'm using javascript to set the focus. This isn't working:

document.querySelector("#input-box").focus();

Anyone know why? Is the focus method not the correct one to use for this?

Thank you.

Edit #2: So it definitely has something to do with the fact that I am trying to set focus to the input from a ListView's "itemInvoked" event. The event is firing properly, the element is accessible from the event handler, and the line has no errors on execution. I can set focus to my input tag from a standard button click event, but not from an ItemInvoked event. So the question is, why can't I set focus from within this event handler?

JT703
  • 1,311
  • 4
  • 17
  • 41
  • 1
    I guess "Windows 8" isn't the correct information we need here. What about the browser you're using? Also, consider the `autofocus` attribute. – MaxArt May 21 '12 at 18:54
  • 1
    By 'Windows 8', do you mean IE 8? – honyovk May 21 '12 at 19:00
  • 4
    By "Windows 8," I mean Windows 8. Google it. – JT703 May 21 '12 at 19:14
  • Would it benefit us if you provided some markup? - just to double check – Greg May 24 '12 at 12:26
  • I doubt it. It's a standard tag with a type='text'. That is why this is so frustrating. In standard HTML5/js, this is so easy. But under WinRT, it's not working. – JT703 May 24 '12 at 12:29
  • 2
    @JT703 Since WinRT JS core is based on Chakra for IE9, could you test the following? #1: Try call `document.querySelector("#input-box").focus();` twice. #2: If #1 fails, try call `document.querySelector("#input-box").select();document.querySelector("#input-box").focus();`. #3: If #2 fails, put the focus inside a timeout `setTimeout(function(){ document.querySelector("#input-box").focus(); }, 100);`. I KNOW is WinRT but i just covered some focus() bugs that happened on IE9. Testing does not hurts, right? – RaphaelDDL May 24 '12 at 17:07
  • 4 years later, I'm having the same issue. Using Visual Studio 2013 to make a Javascript / HTML windows store app. Oddly, when I use focus() on an input, I can put an event listener for 'keyup' events and it will fire the event listener, but it won't actually type characters into the input field. Luckily that's good enough for me, I've used the keyup event as a workaround as I don't need the visual display, but it's still frustrating, unexpected and weird. Probably inconsistent as well, depending on where the app is installed. – TKoL Dec 01 '16 at 14:11
  • wrapping the focus in a timeout should do the trick. – mintedsky Jun 29 '18 at 21:51

5 Answers5

10

I have created this little test project with only a textbox and in the onload set the focus in exactly the same way as you do. I tried it both on the emulator and on my local machine and both methods seem to work.

Could you try if this project is working for you on your machine? And can you give us some more insight on when you are trying to set the focus? Right now in your question there is not that much information about when it's happening.

You can download the sample over here http://www.playingwith.net/Temp/TestFocusApplication.zip

Update

Okay, seem to found it, if you call the msSetImmediate function with the function that sets focus to the textbox it seems to work. I don't have an option to upload the test example, so below you find the code where I attach the ItemInvoked handler and call the setFocus function.

 var listView = document.getElementById("basicListView");

                listView.winControl.addEventListener("iteminvoked", function (evt) {
                    if (listView.winControl.selection.count() > 0) {                        
                        msSetImmediate(setFocus);
                    }
                });

function setFocus() {
            //Set focus on input textbox;
            var input = document.querySelector("#input-box")
            input.focus();
        }
ChristiaanV
  • 5,401
  • 3
  • 32
  • 42
  • Could you update your example to use a listview item being invoked as the trigger for the focus event? I believe this is the core issue. – JT703 May 29 '12 at 13:52
  • I think it would be better if you give us an working sample app with your problem instead of us updating our examples based on your input. I really would like to look into your issue if you send a sample. – ChristiaanV May 29 '12 at 14:02
  • I'm sorry, but I can't do that. It's definitely a listview issue. If someone can figure that out, that will be the solution. – JT703 May 29 '12 at 14:28
  • You can't abstract the problem in a separate solution and give that to us? If you can't do that, how am i supposed to do it for you. – ChristiaanV May 29 '12 at 14:35
  • Click a list view item -> make it focus a text input box – JT703 May 29 '12 at 15:04
  • Updated my answer, hope this will fix your issue. – ChristiaanV May 30 '12 at 08:34
1

Which build are you on ? consumer preview or other dev previews ? I'm on DP6 (available to MS partners) and the JS standard stuff works.

In my default.html I have:

<input id="input1" type="text" value="one"/>
<input id="input2" type="text" value="two"/>
<input id="focus_btn" type="button" value="Set focus 1"/>
<input id="focus_btn2" type="button" value="Set focus 2"/>

And then in my default.js, in the app-launched-loaded boilerplate function I have:

document.querySelector('#focus_btn').addEventListener('click', function () {
    var input1 = document.querySelector('#input1').focus();            
});

document.querySelector('#focus_btn2').addEventListener('click', function () {
    var input1 = document.querySelector('#input2').focus();            
});

The only reason I can think of it not working is that the element is accessed before it is ready. That or earlier build bugs. I have the solution rar'd in : http://www.mediafire.com/?ghz49gtfxlgr7en if you want to see.

Orry S
  • 36
  • 3
  • so, this example is almost exactly what I'm trying to do [set focus on a click event]. I copied/pasted your elements/event handlers into my project and they worked fine. It's exactly what I'm doing, but my case still is not working. The only difference I can think of is that my click is coming from a list view item. The event is firing correctly, the input element definitely exists, and the line is getting executed, but nothing is happening. Also, the input tag is inside a form tag. I don't know if that matters. – JT703 May 25 '12 at 13:29
  • So it definitely has something to do with the ListView and the fact that the event is a "itemInvoked" event. I've confirmed that the form has nothing to do with it. I can set focus to my input tag from a standard button click event, but not from this ItemInvoked event. So the question is, why can't I set focus from within this event handler? – JT703 May 25 '12 at 13:37
  • 1
    It would be great if you can give more information on the flow of things (which gets clicked, which element gets modified where, etc.). Guessing from what you say there though, what I'd do is : -Make sure the input element is actually selected by making it style.visibility='collapse' and see if dom manipulation works at all -If so, it could be a focus race condition problem. The list view does a lot of things behind the scenes including setting focus to the items (ex. if you click an item, item is now focused). To test if this is the problem, do a setTimeOut to delay the input set focus – Orry S May 25 '12 at 18:07
  • the setTimeout didn't help. Could you update your example to use a listview item being invoked instead of buttons? I believe this is the core issue. – JT703 May 29 '12 at 13:52
  • I set up a simple listview example : http://www.mediafire.com/download.php?3k7prujw8od62od The setTimeout actually worked, and needed in this scenario. So what happened was when you click on a listview, you are setting focus to that item. Hence why you can't focus on anything else. I tried a 1ms delay and worked but to be safe I put it at 10ms. – Orry S May 31 '12 at 17:53
0

Try using non-jquery regular javascript like

document.getElementById( 'myElementsID' ).focus()

Steve Binder
  • 2,270
  • 1
  • 14
  • 6
  • I'm not using jquery. Please note that this is a Win8 metro app. Nothing changed when I tried your suggestion. – JT703 May 21 '12 at 19:20
  • are you sure the id exists for your element? Also, are you sure that the element exists at the time you are calling this javascript? – Steve Binder May 21 '12 at 19:25
  • yes. I'm positive. I've debugged through it the element is definitely there. – JT703 May 21 '12 at 19:26
  • I bet Steve thought querySelector() is a jquery syntax. Sad. [Please go study.](https://developer.mozilla.org/En/DOM/Document.querySelector) – RaphaelDDL May 24 '12 at 19:20
0

Try this to see if it helps:

if(document.createEvent) 
{
    document.getElementById('input-box').dispatchEvent('DOMFocusIn');
} 
else 
{
    document.getElementById('input-box').fireEvent('DOMFocusIn', event);
}
BenM
  • 52,573
  • 26
  • 113
  • 168
0

Although the question is very old. But I struggled to find the solution for this.

First thing .focus() does not return any value it just set focus and undefined is returned.

Also, when we set focus on some element make sure that element has the tabindex present, otherwise it would not focus (mainly in chrome).

The following query may be used:

element.querySelector('#label').setAttribute('tabindex','0');
element.querySelector('#label').focus();
Firdous Ahmad
  • 49
  • 1
  • 8