The Spark Form, Spark FormHeading, and Spark FormItem containers

The Spark Form is a highly customizable container that supports multiple form designs and helps you create richer form experiences. When designing forms, you sometimes have limited space to display all the form elements. Spark forms help you solve this problem by providing horizontal and stacked layouts, as well as multiple customized columns.

Spark Forms let you customize the appearance of your form through skinning.

Creating a Spark Form

You use the <s:Form> tag to define a Spark Form. Specify an id value if you intend to refer to the entire form elsewhere in your MXML, either in another tag or in an ActionScript block.

To create a Spark Form, you typically use three different components: the Form container, FormHeading controls, and FormItem containers, as the following example shows:

Spark Form example
A.
Form container

B.
FormHeading control

C.
FormItem containers

For complete reference information, see Form, FormHeading, and FormItem in the ActionScript 3.0 Reference for the Adobe Flash Platform.

For a video on creating a Spark Form, see www.adobe.com/go/learn_flexsparkformvideo_en

Creating a Spark FormHeading control

A Spark FormHeading control specifies an optional label for a group of FormItem containers. The label is aligned with the start of the FormItem label controls in the form. You can have multiple FormHeading controls in your form to designate multiple content areas. You can also use FormHeading controls with a blank label property to create vertical space in your form.

You use the <s:FormHeading> tag to define a FormHeading container. Specify an id value if you intend to refer to the heading elsewhere in your MXML, either in another tag or in an ActionScript block.

The following code example defines the FormHeading control for the Spark Form:

<?xml version="1.0" encoding="utf-8"?> 
<!-- containers\layouts\spark\SparkFormHeadingSimple.mxml --> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:s="library://ns.adobe.com/flex/spark">
    
    <s:Form id="myForm" width="400" height="100">
        <s:FormHeading label="Spark Form Heading" />
        <!--Define FormItem containers here. -->
    </s:Form>
</s:Application>

The executing SWF file for the previous example is shown below:

For complete reference information, see the ActionScript 3.0 Reference for the Adobe Flash Platform.

Creating a Spark FormItem container

A Spark FormItem consists of the following parts:

  • A single label

  • A sequence label

  • One or more child controls or containers, such as text input or button control

  • Help content that provides a description of the form item or instructions for filling it out

  • Required indicator to indicate if a form item has to be filled

By default, all the FormItem elements are arranged in a horizontal layout with the label placed on the left and the Help content on the right.

The following code example defines the Spark FormItem container for the Spark Form:

<?xml version="1.0" encoding="utf-8"?> 
<!-- containers\layouts\spark\SparkFormItemSimple.mxml --> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:s="library://ns.adobe.com/flex/spark">
    
    <s:Form id="myForm" width="450" height="125">
        <s:FormHeading label="Spark Form Heading" />
        <s:FormItem label="Username:">
            <s:TextInput id="username" />
            <s:helpContent>
                <s:Label text="Enter your LDAP username" />
            </s:helpContent>
        </s:FormItem>
    </s:Form>
</s:Application>

The executing SWF file for the previous example is shown below:

For complete reference information, see Spark FormItem in the ActionScript 3.0 Reference for the Adobe Flash Platform.

Using sequence labels in a Spark FormItem control

You sometimes need to fill the form in a sequential order. Sequential labels help you design forms that define a visual order to the form items. When laying out form items in a Spark Form, you can define sequence labels using the sequenceLabel property.

The following code example uses sequence labels, incrementing the sequence number by one for each label:
<?xml version="1.0" encoding="utf-8"?> 
<!-- containers\layouts\spark\SparkFormItemSequenceLabels.mxml --> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:s="library://ns.adobe.com/flex/spark">
    
    <s:Form id="myForm" width="350" height="325">
        <!-- Reduce gap between form items. -->
        <s:layout>
            <s:FormLayout gap="-14"/>
        </s:layout>         
        <s:Label fontSize="16" text="My Spark Form"/>
        <s:FormItem label="Address" sequenceLabel="1.">
            <s:TextInput width="100%"/>
            <s:TextInput width="100%"/>
            <s:TextInput width="100%"/>
        </s:FormItem>
        <s:FormItem label="City" sequenceLabel="2.">
            <s:TextInput width="100%"/>
        </s:FormItem>
        <s:FormItem label="State" sequenceLabel="3.">
            <s:TextInput width="100%"/>
        </s:FormItem>
        <s:FormItem label="ZipCode" sequenceLabel="4.">
            <s:TextInput width="100%"/>
        </s:FormItem>
    </s:Form> 
</s:Application>

The executing SWF file for the previous example is shown below:

You can customize the appearance of sequence labels by styling the FormItem container’s sequenceLabelDisplay skin part. Properties like label color and fontWeight are explicitly set in the default FormItemSkin. To change these properties, you can create a custom skin using MXML or ActionScript and override the default styles.

Defining Help content in a Spark FormItem control

Help content provides a description for the form item or instructions for filling out the form item. When you create a FormItem, you use the helpContent property to define the Help content for the FormItem.

In a BasicLayout Group container, the Help content is placed next to the FormItem input control, by default. If you have multiple items in your helpContent group, you can place the Help content in an HGroup container or a VGroup container. The HGroup container lays out Help content horizontally and the VGroup container lays out Help content vertically.

The following code example defines Help content for FormItems in a Spark Form:

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\layouts\spark\SparkFormItemHelpContent.mxml --> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:s="library://ns.adobe.com/flex/spark"
    width="600">
    
    <s:Form id="form1" x="164" y="38">
        <!-- Reduce space between form items. -->
        <s:layout>
            <s:FormLayout gap="-14"/>
        </s:layout>         
        <s:FormHeading label="Mailing Information"/>
        <s:FormItem label="Address">
            <s:helpContent>
                <s:Label text="(eg. 123 Main Street)"/>      
            </s:helpContent>
            <s:TextInput/>
            <s:TextInput/>
        </s:FormItem>
        <s:FormItem label="City/State">
            <s:TextInput/>
        </s:FormItem>
        <s:FormItem label="Phone" fontFamily="Verdana" required="true">
            <s:helpContent>
                <s:VGroup>
                    <s:Label text="(xxx)-xxx-xxxx"/>
                    <s:Label text="Will appear in your profile"/>
                </s:VGroup>
            </s:helpContent>
            <s:TextInput/>
        </s:FormItem>
    </s:Form>
</s:Application>

The executing SWF file for the previous example is shown below:

You can customize the appearance of the Help content by styling the FormItem container’s helpContentGroup skin part. Properties like fontStyle and color are explicitly set in the default FormItem skin. To change these properties, you can create a custom skin using MXML or ActionScript and override the default styles.

Spark Form and Spark FormItem skin classes

The Flex framework provides two sets of skin classes for the Spark Form and Spark FormItem controls:

The default skin classes define a horizontal layout of form items. The default skin classes include the following:

  • FormHeadingSkin: A horizontal layout for a FormHeading.

  • FormItemSkin: A horizontal layout for a FormItem with four columns and five skin parts. For more information, see Using the required indicator for form items.

  • FormSkin: A four-column skin for the Form, where the columns are arranged horizontally in a single row.

The stacked skin classes define each form item with the label above the form control to use less horizontal space. The stacked skin classes include the following:

  • StackedFormHeadingSkin: A stacked layout for a FormHeading

  • StackedFormItemSkin: A stacked layout for a FormItem with four columns and five skin parts.

  • StackedFormSkin: A three-column skin with two rows per item, and the label placed in the top row.

The following code example defines a Spark Form control using a StackedFormHeadingSkin, StackedFormItemSkin, and StackedFormSkin class:
<?xml version="1.0" encoding="utf-8"?> 
<!-- containers\spark\SparkFormStackedSkinClasses.mxml --> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:s="library://ns.adobe.com/flex/spark"
    width="300">
    
    <fx:Style>
       @namespace s "library://ns.adobe.com/flex/spark";
        
       s|Form
           {
               skinClass: ClassReference("spark.skins.spark.StackedFormSkin");
           }
       s|FormHeading
           {
               skinClass: ClassReference("spark.skins.spark.StackedFormHeadingSkin");
           }        
       s|FormItem
           {
               skinClass: ClassReference("spark.skins.spark.StackedFormItemSkin");
           }
    </fx:Style>
    
    <s:Form id="frm" width="300">
        <!-- Reduce gap between form items. -->
        <s:layout>
            <s:FormLayout gap="-14"/>
        </s:layout>         
        <s:FormHeading label="STACKED SPARK FORM" backgroundColor="Gray" color="#FFFFFF" width="300"/>
        <s:FormItem sequenceLabel="1." label="First name" required="true">
            <s:TextInput id="fName" maxChars="64" />
        </s:FormItem>
        <s:FormItem sequenceLabel="2." label="Last name">
            <s:TextInput id="lName" maxChars="64" />
        </s:FormItem>
        <s:FormItem sequenceLabel="3." label="Address">
            <s:TextInput id="AddressLine1" maxChars="32"/>
            <s:TextInput id="AddressLine2" maxChars="32"/>
            <s:TextInput id="AddressLine3" maxChars="32"/>
        </s:FormItem>
        <s:FormItem sequenceLabel="4." label="City">
            <s:TextInput id="City" maxChars="64" />
        </s:FormItem>
        <s:FormItem sequenceLabel="5." label="State">
            <s:TextInput id="State" maxChars="64" />
        </s:FormItem>
        <s:FormItem sequenceLabel="6." label="ZipCode" required="true">
            <s:TextInput id="ZipCode" maxChars="64" />
        </s:FormItem>
    </s:Form>     
</s:Application>

The executing SWF file for the previous example is shown below:

Using the required indicator for form items

The required state indicates that you must enter the FormItem's content before submitting the form. The required state occurs when you set the FormItem's required property to true as follows:

<s:FormItem label="Username:" required="true"> 
    <s:TextInput id="username" /> 
</s:FormItem>

When you set the required property to true, an asterisk (*) is used to denote the field. A Spark FormItem lets you customize the appearance of the required fields through skinning. For example, a required field can have a light green background, a bold label, or a "(required)" text.

An error state highlights the input error in the form item. The error state occurs when the FormItem's content fails validation. For example, you can define a red border or a light red background to indicate an error state. For more information on including form validation in your Spark Form, see Validating data in a Spark Form.

Validating data in a Spark Form

You can include form validation in your Spark Form. You can add custom logic to validate the input controls to ensure that the required data is entered in a proper format. To do so, you create the proper validator or formatter controls, and associate them with their Form Item controls. When a user enters incorrect data in the Form Item, the Form Item skin uses a different state to represent the erroneous state of the Form Item.

The following code example shows a Spark Form where the phone entry TextInput control is bound to a PhoneFormatter. The TextInput control is bound to the PhoneFormatter such that the data entered is formatted to display, as required. The ZIP code text input is bound to a ZipCodeValidator for data validation, such that, on entering incorrect data, an appropriate error message appears.

<?xml version="1.0" encoding="utf-8"?> 
<!-- containers\spark\SparkFormValidation.mxml --> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx">
    
    <fx:Declarations>
        <mx:PhoneFormatter
            id="pnf"
            areaCode="-1"
            areaCodeFormat="(###)"
            formatString="(###) ###-####"
            validPatternChars="+()#-. "/>
        <mx:ZipCodeValidator
            id="zcv"
            source="{ti_zip}"
            property="text"/>
    </fx:Declarations>
    
    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            [Bindable]
            public var statesDP:ArrayCollection = new ArrayCollection
                    (["Arizona","California","Kansas","New Mexico","Texas","Wyoming"]);
           
            import mx.events.ValidationResultEvent;
            private var vResult:ValidationResultEvent;
            // Event handler to validate and format input.
            private function format():void {
                ti_phone.text = pnf.format(ti_phone.text);
            }
        ]]>
    </fx:Script>
    
    <s:Form width="500" height="600" backgroundColor="0xeeeeee">
        <s:Label fontSize="16" text="My Spark Form"/>
        <s:FormItem label="Address" sequenceLabel="1.">
            <s:TextInput width="100%"/>
            <s:TextInput width="100%"/>
            <s:TextInput width="100%"/>
            <s:helpContent>
                <s:Label text="(ex. 123 Main Street)" baseline="24" />
                <s:Button label="?" width="30" baseline="24" x="120"/>
            </s:helpContent>
        </s:FormItem>
        <s:FormItem label="City" sequenceLabel="2.">
            <s:TextInput width="100%"/>
        </s:FormItem>
        <s:FormItem label="State" sequenceLabel="3.">
            <s:ComboBox dataProvider="{statesDP}" width="100%"/>
        </s:FormItem>
        <s:FormItem label="ZipCode" sequenceLabel="4." required="true">
            <s:TextInput widthInChars="4" restrict="0123456789"/>
            <s:helpContent>
                <s:Label text="Will appear in your profile" left="0" right="0" baseline="24" />
            </s:helpContent>
        </s:FormItem>
        <s:FormItem id="phoneZipItem" label="Phone and Zip" sequenceLabel="5.">
            <s:TextInput id="ti_phone" width="100%" focusOut="format()"/>
            <s:TextInput id="ti_zip" widthInChars="4" restrict="0123456789"/>
            <s:helpContent>
                <s:Label text="(xxx)-xxx-xxxx" left="0" right="0" baseline="24" />
            </s:helpContent>
        </s:FormItem>
        <s:Label text="PhoneZip ErrorString : {phoneZipItem.elementErrorStrings}"/>
    </s:Form>
</s:Application>

The executing SWF file for the previous example is shown below:

Scrolling a Spark Form

The simplest way to add scrolling to a Spark Form is to wrap the Form in a Group container. Then wrap the Group container in a Scroller, as the following example shows:

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\layouts\spark\SparkFormScroll.mxml --> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx">
    
    <s:Scroller width="300" height="200">
        <s:Group>
            <s:Form>
                <s:FormItem label="Label 1:" textAlign="right">
                    <s:layout>
                        <s:HorizontalLayout/>
                    </s:layout>
                    <s:TextInput width="30"/>
                    <s:TextInput width="30"/>
                    <s:TextInput width="30"/>
                    <s:TextInput width="30"/>
                </s:FormItem>
                
                <s:FormItem label="Longer Label 2:" textAlign="right">
                    <s:layout>
                        <s:HorizontalLayout/>
                    </s:layout>
                    <s:TextInput width="30"/>
                    <s:TextInput width="30"/>
                    <s:TextInput width="30"/>
                    <s:TextInput width="30"/>
                </s:FormItem>
                
                <s:FormItem label="Label 3:" textAlign="right">
                    <s:TextInput width="200"/>
                </s:FormItem> 

                <s:FormItem label="Label 4:" textAlign="right">
                    <s:TextInput width="200"/>
                </s:FormItem>
            </s:Form>
        </s:Group>
    </s:Scroller>
</s:Application>

The executing SWF file for the previous example is shown below:

Use a Group container because the Form container does not implements the spark.core.IViewport interface that is required by all children of Scroller.

Changing the layout of FormItems in a Spark Form

FormLayout is the layout class for the FormSkin class and StackedFormSkin class. FormLayout provides a vertical layout for its child FormItem containers in the Form. Elements using FormItemLayout within a FormLayout are aligned along columns.

Note: Only use the FormLayout class with the Form container. Do not use it to lay out the contents of any other container.
You can change the layout of a Spark Form by setting properties such as gap and padding properties on the FormLayout tag. The following example reduces the vertical space between the FormItems and indents the form by 25 pixels:
<?xml version="1.0" encoding="utf-8"?>
<!-- containers\layouts\spark\SparkFormLayout.mxml --> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:s="library://ns.adobe.com/flex/spark"
    width="600">
    <s:layout>
        <s:VerticalLayout/>
    </s:layout>         
    
    <s:Form id="form1" x="164" y="38">
        <!-- Reduce space between form items and indent form 25 pixels. -->
        <s:layout>
            <s:FormLayout gap="-14" paddingLeft="25"/>
        </s:layout>         
        <s:FormHeading label="Mailing Information (Custom spacing)"/>
        <s:FormItem label="Address">
            <s:TextInput prompt="Enter your address"/>
        </s:FormItem>
        <s:FormItem label="City/State">
            <s:TextInput prompt="Enter your city and state"/>
        </s:FormItem>
        <s:FormItem label="Phone" fontFamily="Verdana" required="true">
            <s:TextInput prompt="Enter your phone number"/>
        </s:FormItem>
    </s:Form>

    <s:Form id="form2" x="164" y="38">
        <!-- Reduce space between form items. -->
        <s:layout>
            <s:FormLayout gap="0" paddingLeft="0"/>
        </s:layout>         
        <s:FormHeading label="Mailing Information (Default properties)"/>
        <s:FormItem label="Address">
            <s:TextInput prompt="Enter your address"/>
        </s:FormItem>
        <s:FormItem label="City/State">
            <s:TextInput prompt="Enter your city and state"/>
        </s:FormItem>
        <s:FormItem label="Phone" fontFamily="Verdana" required="true">
            <s:TextInput prompt="Enter your phone number"/>
        </s:FormItem>
    </s:Form>

</s:Application>

The executing SWF file for the previous example is shown below:

Using the FormItemLayout layout class

FormItemLayout is a grid layout for the FormItemSkin and StackedFormItemSkin classes. The FormItemLayout has a set of columns and rows, where each layout element can position its edges relative to each column and row.

The FormItemLayout class is necessary for the Form container to align the columns. Layout elements align to the specified columns and rows using constraints. For more information, see Using constraint rows and columns with MX containers and the Spark FormLayout class.