PDA

View Full Version : Buttons, click handlers, and the iOS keyboard



AlexKorn
25 May 2011, 12:29 PM
Short version: How do you control the iOS Safari virtual keyboard with JavaScript?

Long version: In my app, I would like to have a home page where you can tap on a button that will bring you to the contact page, put the cursor in a text box, and pop up the virtual keyboard.

This is more difficult to accomplish than I'd expected.

It appears that the basic issue is that iOS Safari will only accept field.focus() and show the keyboard if it's directly tied to a user action (i.e. a click/tap event). However, if there is a setTimeout() between the DOM event and the call to field.focus(), the focus isn't necessarily changed and the keyboard will not pop up.

You can see that on this page: http://www.alexkorn.com/other/testFocus.html

In Sencha Touch, there are a couple layers of setTimeout()s that occur between a button tap event and actually calling the handler. Thus, it appears impossible to get the keyboard to appear from a button handler.

Exhibit B: http://jsfiddle.net/bAsv8/4/
* Pull this up on your iPhone to try it: http://jsfiddle.net/bAsv8/4/embedded/result/

The weird thing about this page is that I occasionally see the keyboard pop up when I click the button.

Does anybody have any insight into this? How do people control the iOS keyboard?

nwe44
28 Jul 2011, 4:05 PM
Did you ever resolve it?

AlexKorn
29 Jul 2011, 5:21 AM
Yes!

First off, this is a known issue (or at least expected behavior) for Sencha Touch:
http://twitter.com/#!/edspencer/status/74678136985493504

The way I solved this was by using the beforetap event, not the handler config (implicitly the tap event). beforetap fires without any delays, so iOS will allow you to change focus, scroll the window, change the history, etc. And, as far as I can tell, there are no user-noticeable differences between the two events.

An example:


var button = new Ext.Button({
//handler: don't use this
listeners: {
beforetap: function() {
window.scrollTo(0, 0);
}
}
});