Flex Dynamic Data Binding 101 – Part Three

We’ve covered basic data binding with Actionscript in part one and simply sticking components together in part two, now lets look at something a bit more interesting. As I’m working on a contact manager at the moment I’m going to use this as the basis for this little tutorial (hey, I’m lazy and the code is just sitting there….).

First things first lets create a panel with a list to display the contacts, a little form to get the contact information and some buttons for managing the data.

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">

	<mx:Panel title="Contacts" layout="horizontal">

		<mx:VBox>
			<mx:List id="people"/>
			<mx:Button label="Delete Person" enabled="false"/>
		</mx:VBox>

		<mx:Form>
			<mx:FormItem label="First Name">
				<mx:TextInput id="firstName"/>
			</mx:FormItem>
			<mx:FormItem label="Last Name">
				<mx:TextInput id="lastName"/>
			</mx:FormItem>
			<mx:Button label="Add Person"/>
		</mx:Form>
	</mx:Panel>

</mx:Application>

This creates a basic panel which should look something like this.

Contact Form

Note that I’ve set the delete button to disabled as initially we won’t have any contacts, so we won’t have anything to delete.

Now we need to create the code that are going to make the mini application work. First we need an array collection to act as the data provider for the list.

<mx:Script>
	<![CDATA[
		import mx.collections.ArrayCollection;
		[Bindable]
		private var peopleColl:ArrayCollection = new ArrayCollection();
	]]>
</mx:Script>

The peopleColl needs to be bindable as we are going to attach this to the list.

<mx:List id="people" dataProvider="{peopleColl}"/>

Like that.

Next we are going to need a function to add a person.

<mx:Script>
	<![CDATA[
		import mx.collections.ArrayCollection;
		[Bindable]
		private var peopleColl:ArrayCollection = new ArrayCollection();

		private function addPerson():void
		{
			var obj:Object = new Object();
			obj.firstName = firstName.text;
			obj.lastName = lastName.text;

			peopleColl.addItem(obj);
		}
	]]>
</mx:Script>

And get the button to call the function when it is clicked.

<mx:Button label="Add Person" click="addPerson()"/>

Cool. Now when we enter details into the form and click ‘Add Person’ this adds the person’s details to the array collection. But hang on – look at the list

Contact Form with no Label Renderer

Ah. The list is getting updated by the data binding, but doesn’t know how to display the items. It, by default, calls the toString() function which in the case of an Object returns [object Object] . Not good enough for a proper display. So we add a label function to the list so it knows how to display the item.

<mx:Script>
	<![CDATA[
		import mx.collections.ArrayCollection;
		[Bindable]
		private var peopleColl:ArrayCollection = new ArrayCollection();

		private function addPerson():void
		{
			var obj:Object = new Object();
			obj.firstName = firstName.text;
			obj.lastName = lastName.text;

			peopleColl.addItem(obj);
		}

		private function peopleLabelFunction(item:Object):String
		{
			return item.firstName + " " + item.lastName;
		}
	]]>
</mx:Script>

Then tell the list to use this function

<mx:List id="people" dataProvider="{peopleColl}" labelFunction="peopleLabelFunction"/>

Now the list will display correctly.

Contact Form wit Label Renderer

Nice. A couple of notes. Normally when assigning a function to a component such as a click event you would put the call to the function in the “” such as click = “doSomething()” and you could send an event to the function too, click = “doSomething(event)”. In the case of a list component you only need to put in the name of the function.

The label function only receives objects, so you do need to know what the structure of the object is in order to extract the correct string and return it.

OK lets get the delete button working now. First lets enable it. We need to change the enabled property.

<mx:Button label="Delete Person" enabled="{peopleColl.length > 0}"/>

OK, what’s going on here? We are using data binding to do a comparison, on the fly, with the length of the peopleColl. If it is empty the comparison will be false, if not the comparison with be true. And as we are using data binding this will do the hard work for us, we don’t need another function operating on the button enabled property.

Right, now the delete function.

<mx:Script>
	<![CDATA[
		import mx.collections.ArrayCollection;
		[Bindable]
		private var peopleColl:ArrayCollection = new ArrayCollection();

		private function addPerson():void
		{
			var obj:Object = new Object();
			obj.firstName = firstName.text;
			obj.lastName = lastName.text;

			peopleColl.addItem(obj);
		}

		private function peopleLabelFunction(item:Object):String
		{
			return item.firstName + " " + item.lastName;
		}

		private function deletePerson():void
		{
			if (people.selectedItem != null)
			{
				peopleColl.removeItemAt(people.selectedIndex);
			}
		}
	]]>
</mx:Script>

Again – all we need to do is operate on the peopleColl array collection, we don’t need to get anywhere near the list component as it is bound to peopleColl. I’ve also added a little test to make sure that the list is actually selected or we’d get an error. Lets add the function to the delete button.

<mx:Button label="Delete Person" enabled="{peopleColl.length > 0}" click="deletePerson()"/>

And if you try out the app here you can see we can add and remove people from the list, and the delete button will disable itself if you delete all the people from the list. Alright, I know there is no validation, so you can add empty objects into the list, sheesh! Give me a break, we haven’t finished yet! On to part four.

Tags »

Author:admin
Date: Monday, 14. January 2008 7:32
Trackback: Trackback-URL Category: Flex, Tutorials

Feed for the post RSS 2.0 Comment this post

2 comments

  1. 1

    Thanks 4 help,
    I was trying to enable a button throw the function but it wasn’t work propelly.

  2. 2

    Sorry I’m going to need a bit more info before I can help!!

Submit comment