One of the most common tasks you perform when writing an application is code related to validating user input and collecting user input. This is also the case for applications written in Flex and having a simple way of doing this would save both time and money. In my new job working for Open AdExchange I looking at possible solutions to this very common task. Adobe has an article by Aral Balkan called Handling Data which covers basic validation of a form in Flex. This example serves as a good sample of simple validation, but it is not perfect and it does not cover collection of the form data.
The Goal
The goal of this article is to improve upon the code from Aral’s article with generic form handling and automatic collection of form data. This is one way of going about this problem and there are many other ways to do it which probably just as good for your use.
A secondary goal is to make the solution as simple as possible and make it really simple to use in most kinds of applications. Just having two or three lines of code to make it all work perfectly.
The Design
The design consists mainly of two interfaces called FormHelper , FormHelpEnabled and an implementation class FormHelperImpl.

The FormHelper interface extends the IEventDispatcher interface because the implementation classes needs to dispatch events notifying about changes in validation status and sending. The implementation class dispatches a FormEvent, which extends flash.events.Event, when a form is validated and all the data is collected. Listening for a FormEvent.SEND event you can retrieve a typed object containing the form data.
In order to make data collection easy the FormHelper uses a convetion in the way you name your input controls inside your Form. By having a naming convention the implementation class uses the field names in the targetClass property and looks first for a FormItem with the ID on the form <Field name in class>Field and a an input control called <Field name in class>Input. You can of course change this convention to just rely on the input control if you like.
Using this convention the implemention class of FormHelper is capable of returning a typed object with the form data. Have a look at the source code (see the link below) to learn more about the details of the implementation.
UPDATE (25.07.2008): My friend Børre Wessel pointed out something which makes a lot of sense and that was the tight coupling between the view component and the validators. This was beyond my simple scope which was simple validation and data collection. However his point makes perfect sense and I have update the sample code with a new class VOFormHelper which extends the FormHelperImpl class by adding a mapping array which uses the field names of the configured target class as key to store a validator class.
This is all configured in the main application and removes the tight coupling between the form component and the validation logic. The same approach can be performed to format data.
Have a look at the sample source code to see how this is done.
The Sample
Here is a simple demonstration application which shows how to make use of these classes to provide your application with form validation and processing. The sample consists of two input forms and they are there to collect information about a user and some address data. Both input components implement the FormHelpEnabled interface:
public interface FormHelpEnabled {
function set formHelper(f:FormHelper):void;
function get formControl():Form;
}
This enables the main application to compose the input components with a FormHelper to do validation and data collection.
Using the two SASO’s (Simple ActionScript Objects) Address and User the sample just needs to setup two FormHelperImpl instances and add an event listener to retrieve the form data.
formhelper = new FormHelperImpl(FormHelpEnabled(regForm), User);
formhelper.addEventListener(FormEvent.SEND, function(fe:FormEvent):void {
if (fe.resultObject is User) {
var u:User = User(fe.resultObject);
Alert.show("Form data:\n" + ObjectUtil.toString(u));
}
});
regForm.formHelper = formhelper;
.....
<mx:TabNavigator height="350" width="600">
<local:RegistrationForm2 id="regForm"
label="User information"/>
<local:RegistrationForm id="regForm2"
label="Address information"
creationComplete="initAddress()"/>
</mx:TabNavigator>
View the sample in new window
View the source code
The design of these classes are not necessarily what you need for you application and you are free to use the code in any way you see fit. Just let me know and I can post an update here on the blog.
July 23rd, 2008 | Flex