Handling Form Fields in Flex 4.5 / AIR Mobile

While doing mobile development, one of the most frustrating things has been form input.
If you’ve looked at any Playbook development, you’ll see QNX has something called ReturnKeyType specifically for this reason.
Being as stubborn as I am, I wanted a plain Flex approach at accomplishing what I wanted, and not to use the QNX library.

The Problem

When a series of form inputs are displayed on a mobile device, consideration for the on screen keyboard must be taken. In most scenarios, the operating system will shift your application up for you, but getting to the next field below it can be troublesome.

Take a look at this example in my current mobile app, Crash:

Inputs Covered Inputs Uncovered
Inputs Covered Inputs Uncovered

As you can see, when the user has the keyboard in position, the next TextInput is barely in view, and extremely difficult to tap. What’s more, is if you ARE able to tap it, it seemingly lines it up perfect so you can’t tap the one just below it.

I set out to find a solution that was easy to understand, and really easy to implement.

The Solution

It turns out, in Flex 4.5, the TextInput class now dispatches FlexEvent.ENTER when the enter key is pressed. From the ASDocs directly, the statement appears:

This control dispatches a FlexEvent.ENTER event when the user pressed the Enter key rather than inserting a line break, because this control does not support entering multiple lines of text.

AHA! It’s obvious now! I just listen for this event… and… then… do… something?

Yep! That’s exactly right! I’ll skip the banter and get right to the code:

override protected function partAdded(partName:String, instance:Object):void
{
    switch (instance) {
        case this.txtInpName:
        case this.txtInpPhone:
        case this.txtInpAddress1:
        case this.txtInpAddress2:
        case this.txtInpLicense:
            TextInput(instance).addEventListener(FlexEvent.ENTER, this._onPressEnter, false, 0, true);
        break;
    }
}

Simply put, whenever a part from the skin is added, and I can identify it as one of my TextInputs, I simply listen for the FlexEvent.ENTER event, and handle it as such:

private function _onPressEnter(event:FlexEvent):void
{
    var nextFocusObj:IFocusManagerComponent = null;

    var focusMap:Dictionary                 = new Dictionary(true);

    focusMap[this.txtInpName]               = this.txtInpPhone;
    focusMap[this.txtInpPhone]              = this.txtInpAddress1;
    focusMap[this.txtInpAddress1]           = this.txtInpAddress2;
    focusMap[this.txtInpAddress2]           = this.txtInpLicense;
    focusMap[this.txtInpLicense]            = null;

    nextFocusObj = focusMap[event.target];

    if (null !== nextFocusObj) {
        this.focusManager.setFocus(nextFocusObj);
    } else {
        FlexGlobals.topLevelApplication.setFocus();
    }
}

Here I’ve simply created a mapping from one input to the next. this.txtInpName will map to this.txtInpPhone as it’s the next in order, this.txtInpPhone to this.txtInpAddress1 and so on.
The special case is the last TextInput item, and I’m assigning null to the mapping. Furthermore, when the nextFocusObj is null, it merely calls setFocus() on the Application itself.

This isn’t the CLEANEST approach in my mind, because there is some setup you have to do first, but it does work.

For those that are going to say, “Why not just use FocusManager::getNextFocusManagerComponent() method to get the next item.” Well, honestly, it wasn’t working as I expected. It was selecting some arbitrary button on the screen; certainly not what I had hoped/expected to see. Thus, I have to be a bit more explicit.

I’ve tested this on the Playbook, and it works great! When the last text input is reached and the user hits Enter/Return, the Application gets focus and the keyboard automatically hides.
Win!

Advertisements

About killerspaz

I'm a developer that loves to tinker with cutting edge technology. I have recently been playing with the Flash Platform (AS3/Flex), Android (custom roms, replacement apps, scripting), and looking at opportunities in the mobile markets.

Posted on 05.07.2011, in Flex and tagged , , , , , , , , , , , , , , . Bookmark the permalink. 4 Comments.

  1. Andres Rojas

    Have you tried this with a long form? the fields are focused but the keyboard is on top so they are not visible until user types something.

    • What exactly do you mean a “long form?” I done TextInput and TextArea area just fine, and don’t actually use form syntax or forms/ layouts.

  2. You can use
    pan
    in den App.xml file 😉

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: