Programmatically set focus of input box from ListView's ItemInvoked event [Windows 8 Metro HTML5]
Asked Answered
D

5

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?

Dottiedottle answered 21/5, 2012 at 18:52 Comment(8)
I guess "Windows 8" isn't the correct information we need here. What about the browser you're using? Also, consider the autofocus attribute.Bionomics
By 'Windows 8', do you mean IE 8?Dianthus
By "Windows 8," I mean Windows 8. Google it.Dottiedottle
Would it benefit us if you provided some markup? - just to double checkOrling
I doubt it. It's a standard <input> 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.Dottiedottle
@Dottiedottle 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?Upthrow
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.Incontestable
wrapping the focus in a timeout should do the trick.Adobe
H
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();
        }
Harim answered 25/5, 2012 at 6:58 Comment(6)
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.Dottiedottle
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.Harim
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.Dottiedottle
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.Harim
Click a list view item -> make it focus a text input boxDottiedottle
Updated my answer, hope this will fix your issue.Harim
S
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.

Schwejda answered 25/5, 2012 at 6:25 Comment(5)
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.Dottiedottle
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?Dottiedottle
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 focusSchwejda
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.Dottiedottle
I set up a simple listview example : 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.Schwejda
Y
0

Try using non-jquery regular javascript like

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

Yelenayelich answered 21/5, 2012 at 18:55 Comment(4)
I'm not using jquery. Please note that this is a Win8 metro app. Nothing changed when I tried your suggestion.Dottiedottle
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?Yelenayelich
yes. I'm positive. I've debugged through it the element is definitely there.Dottiedottle
I bet Steve thought querySelector() is a jquery syntax. Sad. Please go study.Upthrow
E
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);
}
Edd answered 23/5, 2012 at 13:59 Comment(3)
It's going into the first block and throws an error saying that 'DOMFocusIn' is an 'Invalid argument.'Dottiedottle
Try replacing DOMFocusIn with onfocus.Edd
same thing. it is very frustrating. This WinRT platform is so different from standard web dev.Dottiedottle
K
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();
Kahn answered 31/7, 2017 at 9:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.