Flex 3: Two-way Form Databinding
I saw this "trick" in someone's code and have been using it lately so I thought I'd share. The idea is to create an object, bind it to the form elements, and bind the form elements to the object. In this example, I'm using a simple form from an app I'm working at the moment.
Userform.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:dto="com.katapultmedia.mystreamer.dto.*">
<mx:Script>
<![CDATA[
private function save():void{
}
]]>
</mx:Script>
<dto:User id="user" />
<mx:Binding source="firstNameField.text" destination="user.firstName" />
<mx:Binding source="lastNameField.text" destination="user.lastName" />
<mx:Binding source="emailAddressField.text" destination="user.emailAddress" />
<mx:Binding source="passwordField.text" destination="user.password" />
<mx:Binding source="isActiveCheck.text" destination="user.isActive" />
<mx:Form>
<mx:FormItem label="First Name">
<mx:TextInput id="firstNameField" text="{user.firstName}" />
</mx:FormItem>
<mx:FormItem label="Last Name">
<mx:TextInput id="lastNameField" text="{user.lastName}" />
</mx:FormItem>
<mx:FormItem label="Email Address">
<mx:TextInput id="emailAddressField" text="{user.emailAddress}" />
</mx:FormItem>
<mx:FormItem label="Password">
<mx:TextInput id="passwordField" text="{user.password}" />
</mx:FormItem>
<mx:FormItem>
<mx:CheckBox id="isActiveCheck" selected="{user.isActive}" />
</mx:FormItem>
<mx:FormItem>
<mx:Button label="Save" click="save()" />
</mx:FormItem>
</mx:Form>
</mx:VBox>
So, I'm not going to go line but line since it is pretty straight forward but here's a brief outline.
Form Items
- Each TextInput is bound to the user objects respective property (ex - firstNameField.text is bound to {user.firstName}).
- The isActiveCheck is bound to {user.isActive}
Binding Tags
- Each Binding tags source property is bound to one of the form items.
- Each Binding tags destination property is bound to the respective user property.
That's it. What happens is when I create an instance of this component I will set myUserForm.user = someUser; and when the user edits one of the form items the respective value of the user object will be updated instantly. This way, when the user clicks the Save button I can easily pull myUserForm.user and pass that dto (data transfer object) to the backend.
Kinda cool, huh? Well, I think so. Saves a good bit of Actionscript writing.
Enjoy.
Update: I should test code before posting. :-) I've removed the brackets around the source/destination properties on the Binding tags. They aren't needed.
Categories
Flash Platform0 TrackBacks
Listed below are links to blogs that reference this entry: Flex 3: Two-way Form Databinding.
TrackBack URL for this entry: http://mt.johncblandii.com/mt-tb.cgi/120


Another way you can do this is the use the change attribute of the form fields to update the model:
change="user.firstName = firstNameField.text"
Yep. I just prefer the cleaner, more readable version. Pure preference thing though.
Thanks Johan.
tried this for a while but i allways get this error:
warning: unable to bind to property 'firstName' on class 'Object' (class is not an IEventDispatcher
my vo looks this way:
package somePackage.vo
{
//[Bindable]
[Bindable(event="propertyChange")]
public class UserVO extends EventDispatcher
{
public var firstName:String = "enter first name";
}
}
same thing happens if i let vo extend EventDispatcher manualy.
thx
It sounds like you were trying to bind to an object that wasn't bindable.
You don't have to use [Bindable(name="propertyChange"]. You can just have [Bindable].
Glad you got it going though.
"text" isn't a valid property of the Checkbox control, right? When I change it to "selected" in my code, I get an error regarding the attempt to coerce a string to a boolean value. Hmmm...
No, there isn't a text property.
What you need to do to handle type coercion problems is to cast the value as that type.
So, if you're trying to take mycombo.selectedItem and use it as a boolean, do this:
var myboolean:Boolean = Boolean(mycombo.selectedItem);
...or...
var myboolean:Boolean = mycombo.selectedItem as Boolean;
Hope that helps.
Hello John,
Nice post.
I'm interested in seeing a clean way to add validation to this two-way binding example.
Best,
al
I've been pretty swamped lately but if I get some time I'll work on an example for you.