Linking Data-Aware Controls

Posted: December 15, 2006 in Flex

Question:

How do I populate a DataGrid based on a selection from a ComboBox?

Answer:

Using an ArrayCollection bound to the dataProvider of a DataGrid, we can populate the ArrayCollection based on the selection made from the ComboBox.

Solution:

One of the requirements of a Rich Internet Application is the ability to populate one databound control based on a selection in another databound control.

I’m going to show you how to create a Flex application that populates a DataGrid based on the selected value in a ComboBox.

Let’s take a look at our code example below:

code segment 1 of 5 (LinkedBoxes.mxml)

1. <?xml version=”1.0″ encoding=”utf-8″?>
2. <mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml&#8221; layout=”absolute” creationComplete=”initApp()”>
3. …
4. </mx:Application>

In Code Segment 1 of 5 we are presented with a Flex application skeleton. The only addition to this bit of code is the function being called upon creationComplete.

Once the application has completed its construction we instruct the application to call the initApp() function. more on that later.

code segment 2 of 5

1. <mx:Panel title=”Combobox to DataGrid” width=”50%”>
2. <mx:VBox width=”100%” paddingTop=”5″ paddingLeft=”5″ paddingBottom=”5″ paddingRight=”5″>
3. <mx:Label text=”Selections from the ComboBox populate the DataGrid” fontSize=”16″ fontWeight=”bold” />
4.
5. <mx:HBox>
6. <mx:Label text=”Department: ” />
7. <mx:ComboBox change=”changeEvt(event)” id=”deptCB” >
8. <mx:ArrayCollection>
9. <mx:Object label=”- Select Department -” data=”” />
10. <mx:Object label=”Biology” data=”BIOL” />
11. <mx:Object label=”Chemistry” data=”CHEM” />
12. <mx:Object label=”Economics” data=”ECON” />
13. <mx:Object label=”Math” data=”MATH” />
14. </mx:ArrayCollection>
15. </mx:ComboBox>
16. </mx:HBox>
17.
18. <mx:DataGrid dataProvider=”{acCourses}” width=”100%”>
19. <mx:columns>
20. <mx:DataGridColumn headerText=”Course Name” dataField=”CORNAME”/>
21. <mx:DataGridColumn headerText=”Level” dataField=”CORLEVEL”/>
22. </mx:columns>
23. </mx:DataGrid>
24. </mx:VBox>
25. </mx:Panel>

Now we setup our user interface for the application (code segment 2 of 5). The following code will be placed starting on line 3 shown in code segment 1 of 5.

We start with a Panel with a title and a width of 50%.

Next, on line 2, we insert a vertical box – or VBox. The VBox will expand to be 100% of the parent – the Panel and contain a 5 pixel padding all around the sides.

On line 3 we use a Label to display a line of instruction.

The Label and ComboBox controls are contained within an HBox (horizontal box). Now let’s look at the ComboBox defined on line 7.

We instruct the ComboBox to execute the changeEvt() function when a change to the control has occurred as a result of user interaction.

An Event object is passed that contains a reference to the ComboBox. We use an ArrayCollection (lines 8 – 14) to populate the ComboBox.

Line 18 through 23 define our DataGrid. We instruct the DataGrid to bind a variable named, acCourses to the DataGrid’s dataProvider. This variable will be defined a bit later.

We define two DataGrid columns, one to display the Course Name and another to display the Level. The dataField attributes specify the name of the column contained in the dataProvider.

code segment 3 of 5

1. <!–setup connection to the CFC–>
2. <mx:WebService id=”myService” wsdl=”http://%5Byour web server here]/FlexDemos/LinkedBoxes/cf/Courses.cfc?wsdl” showBusyCursor=”true” result=”handleGetCourses(event)”>
3.
4. <mx:operation name=”getCourses” resultFormat=”object”/>
5.
6. </mx:WebService>

Code Segment 3 of 5 shows the WebService class used to retrieve the Courses data from a ColdFusion webservice. The ColdFusion CFC component is shown in Code Segment 4 of 5

The Operation listed on line 4, getCourses, will retrieve all the courses return it to Flex as an Object.

code segment 4 of 5

1. <mx:Script>
2. <![CDATA[
3. import mx.rpc.events.ResultEvent;
4. import mx.controls.Alert;
5. import mx.collections.ArrayCollection;
6.
7. private var oResult:Object;
8.
9. [Bindable] private var acCourses:ArrayCollection;
10.
11. private function initApp():void {
12. myService.getCourses.send()
13. }
14.
15. public function handleGetCourses(event:ResultEvent):void{
16. oResult = event.result as Object;
17. }
18.
19. private function changeEvt(event:Event):void {
20. acCourses = oResult[event.currentTarget.selectedItem.data];
21. }
22. ]]>
23. </mx:Script>

Now we write our ActionScript to make all of this come together.

Lines 3 to 5 of Code Segment 4 of 5 imports the three classes that will be needed in the following lines of code.

Line 7 defines a generic Object variable that will hold the results from our web server call.

Line 9 defines an ArrayCollection variable that will hold the subset of data containing only the courses related to the Department selected.

Remember the function called on creationComplete (line 2 of Code Segment 1 or 5)? Well, lines 11 – 13 defines that function. The initApp function calls our WebService class and executes the getCourses method in the our ColdFusion component. As you can see, we execute a webservice method using the syntax show above.

Lines 15 to 17 defines the function that will be called after our ColdFusion component returns its data. We access the data by referring to the result property of the event class and cast it as an Object. That Object is stored in the oResult variable.

Now here’s where the magic happens. Lines 19 to 21 defines the function that will called when the user selects a value from the ComboBox. We use the data of the selectedItem to dynamically provide the name of the structure key. If the user selects BIOL from the ComboBox, the BIOL structure element contained within the oResult object will be assigned to the acCourses variable. Because that variable has been bound to the DataGrid, the DataGrid’s data will automatically change.

code segment 5 of 5 (Courses.cfc)

1. <cfcomponent >
2.
3. <cffunction name=”getCourses” displayname=”GetCourses” access=”remote” returntype=”struct” output=”no” hint=”I get a listing of Courses.”>
4.
5. <cfset Var qryCourseList = “”>
6. <cfset Var stCourseInfo = “”>
7. <cfset Var stCourseData = “”>
8.
9. <!— get Course List – used for Course display —>
10. <cfquery name=”qryCourseList” datasource=”cfdocexamples”>
11. SELECT CourseList.Course_ID, CourseList.Dept_ID, CourseList.CorName, CourseList.CorLevel
12. FROM CourseList
13. ORDER BY Dept_ID, CorName
14. </cfquery>
15.
16. <!— Create a stucture that holds an array of structures —>
17. <cfset stCourseInfo = structnew()>
18.
19. <cfloop query=”qryCourseList”>
20.
21. <!— If the value of GENRE is not already a key value, make it one and assign an array as its value—>
22. <cfif NOT structkeyexists(stCourseInfo, ucase(Dept_ID))>
23.
24. <cfset stCourseInfo[ucase(Dept_ID)] = arraynew(1)>
25.
26. </cfif>
27.
28. <!—create a temporary structure to hold this company’s information—>
29. <cfset stCourseData = structnew()>
30. <cfset stCourseData.DeptID = Dept_ID>
31. <cfset stCourseData.CourseID = Course_ID>
32. <cfset stCourseData.CorName = CorName>
33. <cfset stCourseData.CorLevel = CorLevel>
34.
35. <!—append this structure to the array—>
36. <cfset arrayappend(stCourseInfo[ucase(Dept_ID)], stCourseData)>
37.
38. </cfloop>
39.
40. <cfreturn stCourseInfo>
41.
42. </cffunction>
43.
44. </cfcomponent>

Last but certainly not least we have our ColdFusion component (code segment 5 of 5). Since this tutorial is focused on Flex development, I will not spend a lot of time explaining the ColdFusion code. If you wish to learn more about developing in ColdFusion I suggest that you seek out the many references on ColdFusion starting with the ColdFusion Developer Center on the Adobe web site. So let me give you the highlights …

We define a remote function called getCourses. This function (or method) is called by our WebService class shown on line 2 of code segment 3 of 5.

On lines 10 to 14 we perform a SQL query to retrieve all the Courses sorted by department id (Dept_ID) and Course Name (CorName).

The rest of the code show us creating and populating the structure that will be returned to the Flex application.

So there you have it. This is just one of the many ways you can populate one data-aware control based on a selection from another. The two data-aware controls could have very easily have been a ComboBox and List or a TreeView and DataGrid.

The power of Flex leaves it to your imagination!

Advertisements
Comments
  1. amo says:

    Would be nice to disable smileys 😉

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s