Recipe 11.21 Customizing the Tab Order

11.21.1 Problem

You want to specify the order in which form elements are chosen when the Tab key is pressed.

11.21.2 Solution

Use the tabIndex properties of the form elements to specify their sequence.

11.21.3 Discussion

Flash provides an automatic sequence through which items on the Stage are accessed when the Tab key is pressed. This automatic sequence includes all movie clips, buttons, and text fields, and is not necessarily in an order that makes sense for your application. This poses two challenges. First of all, only certain elements in the movie (such as form elements) should be selectable via the Tab key. Second, you want form elements to be accessed in a specific order. It can be frustrating for your application's users if pressing the Tab key after the first form element takes them to the last element instead of the next one.

Fortunately, you can specify a custom tab order for Flash to use and can include only those elements that you want to be selectable via the Tab key.

The Tab key cannot be detected reliably in Test Movie mode unless you select the Control Disable Keyboard Shortcuts option. Select Control Test Movie, wait for the .swf file to appear, and then disable keyboard shortcuts from the Control menu.

To specify a custom tab order, assign an order (integer) value to each of the element's tabIndex properties. When a text field is selected and the user presses the Tab key, Flash looks at the text field's tabIndex value; it then looks for the element with the next highest value and switches to it. There is one caveat, however: although the user can switch out of text fields using the Tab key, other form elements can be switched to, but not out of, using the Tab key.

#include "Form.as"

/* Create the form elements. They appear on the Stage in this order:
   myTextField0_txt
   myComboBox0_cb
   myTextField1_txt
   myComboBox1_cb
   myTextField2_txt
   myCheckBox_ch
   myListBox_lb
   myRadioButton0_rb
   myRadioButton1_rb
   myRadioButton2_rb
*/    
_root.createTextField("myTextField0_txt", 1, 0, 0, 100, 20);
myTextField0_txt.border = true;
myTextField0_txt.type = "input";
_root.attachMovie("FComboBoxSymbol", "myComboBox0_cb", 2, {_y: 30});
_root.createTextField("myTextField1_txt", 3, 0, 60, 100, 20);
myTextField1_txt.border = true;
myTextField1_txt.type = "input";
_root.attachMovie("FComboBoxSymbol", "myComboBox1_cb", 4, {_y: 90});
_root.createTextField("myTextField2_txt", 5, 0, 120, 100, 20);
myTextField2_txt.border = true;
myTextField2_txt.type = "input";
_root.attachMovie("FCheckBoxSymbol", "myCheckBox_ch", 6);
myCheckBox_ch.setGroupName("myCheckBoxGroup");
myCheckBoxGroup.setPositions(0, 150);
_root.attachMovie("FListBoxSymbol", "myListBox_lb", 7, {_y: 180});
_root.attachMovie("FRadioButtonSymbol", "myRadioButton0_rb", 8);
_root.attachMovie("FRadioButtonSymbol", "myRadioButton1_rb", 9);
_root.attachMovie("FRadioButtonSymbol", "myRadioButton2_rb", 10);
myRadioButton0_rb.setGroupName("myRadioButtonGroup");
myRadioButton1_rb.setGroupName("myRadioButtonGroup");
myRadioButton2_rb.setGroupName("myRadioButtonGroup");
myRadioButtonGroup.setPositions(0, (myListBox_lb._y + myListBox_lb._height + 10));

// Specify the desired tab order by assigning each element's tabIndex property.
myTextField0_txt.tabIndex = 1;
myComboBox0_cb.tabIndex   = 2;
myTextField1_txt.tabIndex = 3;
myComboBox1_cb.tabIndex   = 4;
myTextField2_txt.tabIndex = 5;
myCheckBox_ch.tabIndex    = 6;

// There is no real reason to include these last two because they can never be tabbed
// to or out of (it would require a text field to precede them to switch to them).
// However, as you can see by this example, it does no harm to also add them in the
// sequence.
myListBox_lb.tabIndex      = 7;
myRadioButton0_rb.tabIndex = 8;


    Part I: Local Recipes
    Part II: Remote Recipes