Foundation XML for Flash
| ||
| ||
|
In this section well put together everything weve covered so far and create a simple application. The application will use a trimmed -down version of our address book XML document, and well use Flash to manage changes to the data. Well use a DataGrid component and create multiple component bindings, and well track the changes in a DataSet component.
Exercise 4: A simple address book application
|
In this exercise, well build a simple address book application that will allow us to add, edit, and delete records in Flash. To update the content externally, well need to send the data to a server-side file for processing. I wont include this functionality in the example, but you will see the XML content that Flash provides to the server-side file. If you want to add server-side functionality, youll need to build it yourself using a language like ColdFusion, PHP, or ASP.NET.
Well use the starter file addressBook.fla and start by adding an XMLConnector.
Configure the XMLConnector
The first stage in this exercise is to open the starter file addressBook.fla and add an XMLConnector component. In this exercise, were using data from the file address_simple.xml , so youll need to make sure that both files are in the same folder.
You can see the file address_simple.xml in your resources, and Ive shown the XML document here. Notice that this file contains no attributes and only <id> , < name > , and <phone> child elements. Ive left out the <address> element so that there arent too many columns in the DataGrid.
<?xml version="1.0" encoding="UTF-8"?> <phoneBook> <contact> <id>1</id> <name>Sas Jacobs</name> <phone>123 456</phone> </contact> <contact> <id>2</id> <name>John Smith</name> <phone>456 789</phone> </contact> <contact> <id>3</id> <name>Jo Bloggs</name> <phone>789 123</phone> </contact> </phoneBook>
-
Start Flash if necessary and open the starter file addressBook.fla . Figure 8-35 shows the interface. It consists of a DataGrid component, two TextInput components , a TextArea, and three buttons .
Figure 8-35: The Flash interface for the address book application Ive made the DataGrid component editable, so we can modify the data within each cell . You can use the TextInput components to add new entries, and clicking the Delete selected button will delete the selected row from the DataGrid. When were ready to process the changes, well click the Process changes button. The TextArea component will display the XUpdate statements.
-
Drag an XMLConnector component into the Flash movie and configure it as shown in Figure 8-36. Give it the instance name address_xc .
Figure 8-36: Configuring the XMLConnector component -
In the Schema tab of the Component Inspector, import a schema from the file address_simple.xml . Make sure you select results : XML first. Figure 8-37 shows the imported schema. It replicates the structure from the XML document.
Figure 8-37: The schema created from the file address_simple.xml
You could also have imported a trimmed-down version of the address_simple.xml file, providing it contained at least two data rows. As there were only three rows of data in the XML document, there wasnt much advantage in using a shortened version of the XML file.
Add a DataSet component and related bindings
At this point, youll need to add a DataSet component to the movie and bind it to the XMLConnector. You will also bind the DataSet to the DataGrid component so that the data displays in the interface. It is important that the contents of these two components are identical so that they synchronize whenever the user makes changes to the data.
-
Drag a DataSet component into your movie and give it the instance name address_ds .
-
Add a binding from the XMLConnector to the DataSet. Select the contact array and bind it to the dataProvider of the DataSet. Make sure the direction is set to out .
-
Create a new layer called actions and add the following code line on frame 1. The line triggers the XMLConnector to load the external XML document. If you test the movie at this point, nothing will happen because we havent yet bound the DataSet to the DataGrid component.
address_xc.trigger();
-
Add two bindings between the DataSet and DataGrid components. Both are in/out bindings. The first should bind the dataProvider and the second, the selectedIndex . These bindings will keep the DataSet and DataGrid synchronized.
-
Well need to add component properties to the schema for the DataSet. This will create the correct columns in the DataGrid component. Select the DataSet and click the Schema tab in the Component Inspector. Click the Add a component property button, as shown in Figure 8-38.
Figure 8-38: Clicking the Add a component property button in the Schema tab -
Enter the field name id and make sure that you select the datatype Integer . Repeat the process to add the name and phone fields. They are String datatypes. Make sure that the names you use match the names of the elements in the schema. Figure 8-39 shows the completed Schema tab for the DataSet with the new component properties.
Figure 8-39: The Schema tab showing the new component properties -
Test the movie and you should see the DataGrid populated with data from the XML document. Figure 8-40 shows the interface at this point. The order of the component properties dictates the order of the columns in the DataGrid.
Figure 8-40: The Flash interface showing the populated DataGrid component
At this point, weve bound data from the XMLConnector to a DataSet and then onto the dataProvider of a DataGrid component. We also bound the selectedIndex of the DataSet and DataGrid so that both components always contain the same data. Its critical that you dont forget the second binding.
Configure the Add and Delete buttons
Now we need to modify the DataGrid so that we can add new contacts, as well as edit and delete existing entries.
-
Add the code shown here to the actions layer. This code specifies what happens when you click the Add button. It finds the new name and phone number from the data input fields and adds them to the dataProvider of the DataGrid. This will display the new entry in the DataGrid. The dataProvider of the DataGrid is bound to the dataProvider of the DataSet so the DataSet will be updated with the new information.
add_btn.onRelease = function():Void { var newName:String = name_txt.text; var newPhone:String = phone_txt.text; if (newName.length >0 && newPhone.length>0) { address_dg.dataProvider.addItem({name:newName, phone:newPhone}); } }
-
Add the following code to the actions layer. When you click the Delete button, Flash will remove the selected row from the dataProvider of the DataGrid. Again, the binding to the DataSet ensures that Flash also updates the dataProvider for the DataSet.
delete_btn.onRelease = function():Void { var selRow:Number = address_dg.focusedCell.itemIndex; address_dg.dataProvider.removeItemAt(selRow); }
-
Test the movie and check that you can add, edit, and delete data in the DataGrid. The id column will be blank for new entries. This is because your server-side pages would normally generate the id or primary key field.
Add and configure the XUpdateResolver
In order to track the changes to our address book data, we need to generate a deltaPacket from the DataSet component. Well add an XUpdateResolver to interpret the deltaPacket from the DataSet component and create XUpdate statements.
-
Drag an XUpdateResolver component into your movie and name it address_rs .
-
Bind the deltaPacket from the XUpdateResolver to the deltaPacket of the DataSet component. Set the direction to in so that the XUpdateResolver receives the delta packet from the DataSet.
-
Display the Schema tab and select the deltaPacket from the XUpdateResolver component. Change the encoder setting to DatasetDeltaToXUpdateDelta and enter the following path in the encoder options:
phoneBook/contact[id='?id']
-
This is a critical step. If you dont add the correct path, you wont generate the correct XUpdate statements in the xupdatePacket . In our XPath statement, we go to the contact child element of the phoneBook element and set the child id element to the value from the id field in the DataSet.
-
Add a second XMLConnector to your movie and name it sendChanges_xc . You will use this XMLConnector to send the changes from Flash to server-side pages for updating. In this example, we wont configure the XMLConnector since we dont have any server-side pages prepared. You may want to complete these pages yourself.
-
Add another binding to the XUpdateResolver. This time the binding should send the xupdatePacket from the XUpdateResolver to the sendChanges_xc component. Youll notice that you have to select params when you add the binding because the data will be sent out of Flash.
-
We still need to generate the deltaPacket from the DataSet. Well need to configure the Process changes button to call the applyUpdates method of the DataSet component. Add the following code to your actions layer:
change_btn.onRelease = function():Void { address_ds.applyUpdates(); }
When you click the Process changes button, the DataSet will prepare the deltaPacket . Because weve added a binding to the XUpdateResolver, it will receive the deltaPacket and generate an xupdatePacket .
Displaying the xupdatePacket
If you test the movie at this point, nothing will appear to happen because we havent configured the sendChanges_xc component. Normally, we would link this to a server-side file to process the XUpdate statements. Im not going to do that in this exercise, but we will set up another binding so we can see the contents of the xupdatePacket .
-
Add another binding to the XUpdateResolver component. The binding should send the xupdatePacket to the text property of the xupdate_txt component. Set the direction to out . By binding the xupdatePacket to the text property of the TextArea component, well be able to display the XUpdate statements in the TextArea.
-
Test the movie and make some additions, edits, and deletions to the data. Click the Process changes button and check the contents of the TextArea. Here is some sample content that I generated:
<?xml version="1.0"?> <xupdate:modifications version="1.0" xmlns:xupdate="http://www.xmldb.org/xupdate"> <xupdate:update select="/phoneBook/contact[id='2']/name"> John R Smith</xupdate:update> <xupdate:remove select="/phoneBook/contact[id='3']"/> <xupdate:append select="/phoneBook"> <xupdate:element name="contact"> <id/> <phone>145 789</phone> <name>Roger Rabbit</name> </xupdate:element> </xupdate:append> <xupdate:append select="/phoneBook"> <xupdate:element name="contact"> <id/> <phone>987 123</phone> <name>Percy Penguin</name> </xupdate:element> </xupdate:append> </xupdate:modifications>
In the XML packet shown here, I updated the name of the contact with an id of 2 to John R Smith . I also added two new contacts: Roger Rabbit and Percy Penguin .
You can see the completed addressBook_completed.fla in your resource files.
Points to note from exercise 4
-
If you look at the contents generated by the XUpdateResolver, youll notice that they include XPath statements in the select attribute to identify the elements to update. Here is one example:
select="/phoneBook/contact[id='2']/name"
This XPath statement identifies the <name> element within the <contact> element that has an id of 2 . Notice that the statement uses the entity for the apostrophe character ' . You can find out more about XPath expressions in Chapter 3 and the Appendix.
-
In the previous example, I used a physical XML document. I could just have easily used a server-side page to generate the XML content. Server-side pages offer one way to connect to a database using XML, and this might be useful in the case of an XML-enabled database. I could also use server-side pages to proxy XML data from a web service. Ill discuss web services in more detail in the next chapter. If you choose a server-side file, dont forget to enter the complete server path in the URL field for the XMLConnector component, for example, http://localhost/XMLApplication/getData.aspx.
In the previous section, we used the Component Inspector to configure the data components in our application. Its also possible to achieve the same functionality using ActionScript. I could go into a lot of detail about how to script bindings; however, thats beyond the scope of this chapter. Instead, in the next section, Ill provide a brief overview of how to script the XMLConnector class and add simple bindings.
|