Flex and Vertical Site: Accessing Data with SOAP
Although HTML, CSS and Javascript are technologies that are easy to get started with, they do not provide high-level components as is common with GUI frameworks for desktop applications. Luckily there has been a lot of progress in user interface frameworks for rich Internet applications the last few years. In this article we will show how one such toolkit, Adobe Flex, can be used together with Vertical Site (4.1 and above).
Introduction
Adobe Flex is a collection of technologies from Adobe Systems for developing rich Internet applications based on the Adobe Flash platform. It uses an XML-based markup language to define the graphical user interface, and ActionScript (a language based on ECMAScript) for interactivity.
We will be using Adobe Flex 3 and Adobe Flex Builder Eclipse plugin. Our application will retrieve employee information from Vertical Site, and show this in a list. When selected, more information about the selected employee will be shown.
Basic UI
Our first step is to create a new Flex project - simply start Eclipse, start a new project, select Flex Project in the new project wizard, enter a name for your project, and use the default settings for everything else. You'll be asked to switch to the Flex development perspective, and should end up with a default project as in figure 1.
First, we will add a component where we can list employee names. In the editor window, switch to the Source view, and change the XML to the following:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
width="100%" height="100%">
<mx:DataGrid horizontalCenter="0" id="dg" width="75%"
dataProvider="{cms.getContentBySection.lastResult.contents.content}">
<mx:columns>
<mx:DataGridColumn headerText="Employee Name"
labelFunction="displayEmployeeName/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
It is also possible to add this in the design view, by dragging a DataGrid from the list of Controls into the design view. The DataGrid is used for making simple lists of data. The content of data grid can be dynamically bound to a data source, but in this case we define a function in the labelFunction attribute, that will return the content because we will generate the complete employee name from the data we retrieve from Vertical Site.
The dataProvider attribute binds the grid to the most recent result of our access to the web service. Now we have a simple UI defined, we will need to hook our Flex application up to the web service.
By specifying an id attribute, we make sure we can reference it later.
Accessing Vertical Site
To access Vertical Site, we will use the SOAP service. We simply let Flex know where to get the WSDL file for the service, and the operation we want to access. This is done by adding the following XML inside the mx:Application element:
<mx:WebService id="cms"
wsdl="http://your.site.com/cms/rpc/soap.wsdl">
<mx:operation name="getContentBySection" resultFormat="e4x"/>
</mx:WebService>
Here we define a single operation, getContentBySection, since we will be retrieving employees that are published to a specific section.
The resultFormat attribute is important here, it will make the result of the operation available to us with ECMAScript for XML (E4X) - a programming language extension that adds native XML support, making it very simple to access the XML.
Next, we define an ActionScript function that will call the web service asynchronously.
<mx:Script>
<![CDATA[
import mx.rpc.AsyncToken;
import mx.rpc.AsyncResponder;
private function doRequest():void {
var req:Object = new Object();
req.menuItemKey = [39];
req.childrenLevel = 1;
cms.getContentBySection(req);
}
]]>
</mx:Script>
The menuItemKey is set to an array containing the IDs of the sections we want to get our content from, and childrenLevel is set to 1, to make sure we get data about images as well, exactly how we would do it when defining a datasource for an object in the Vertical Site admin interface.
Our call to cms.getContentBySection starts an asynchronous request to the web service, and since our data grid is tied to the most recent result from this call, it will automatically update when finished.
Next we have to define the function mentioned earlier, displayEmployeeName, to make sure the grid shows the correct information. Since we bind our data grid to cms.getContentBySection.lastResult.contents.content, each content element in the resulting XML will be assigned their own row, and we can access the data in each row as below.
function displayEmployeeName( row:Object, mx:DataGridColumn ):String {
return row.contentdata.firstname + ' ' + row.contentdata.surname;
}
The displayEmployeeName will be called for each row, and the string it returns shown in the grid.
Finally, to make the request happen automatically, we will add the creationComplete attribute to the mx:Application element, and set it to call the doRequest function.
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
width="100%" height="100%" creationComplete="doRequest();">
Enabling cross-domain requests
For security reasons, Flash doesn't allow cross-domain requests by default, and since we will be running our Flex application on our computer and accessing data from our Vertical Site installation we will have to enable this.
To check if cross-domain requests are allowed, Flash checks to see if the file crossdomain.xml is available on the target domain. I.e. if your Vertical Site installation is on example.com, it will check for the existence of http://example.com/crossdomain.xml.
If this file exists, and is served with content-type text/plain or application/xml, it will parse the file and see if the source domain is allowed.
If we have already created our content and published it to the appropriate section, we should now be able to run our Flex application. Right click on the project, and select "Run As" and then "Flex Application". This will open up the Flex application in your default browser. For more information on this, see the Cross-domain policy file specification.
The following example will enable cross-domain requests from any source:
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*" />
</cross-domain-policy>
Running the Flex application
If we have set up the cross-domain policy file correctly, and published content to the right section, we should now be ready to run our Flex application. This can be done by right clicking the project, selecting "Run As", and then "Flex Application". It will then be shown in your default browser (see figure 2).
Showing more information
Our current application is trivial and doesn't really offer any value, but we can easily expand it to show more details.
We will start by first adding an HBox that will control the layout of the application, and then adding a panel with an image element and fields for showing information about the employee. The HBox is simply an element that controls the layout of the application. For more on this and the other components used, please refer to the Flex 3 documentation.
Inside the HBox we add a panel with an image, some labels and text fields, ending up with the following:
<mx:HBox width="80%" height="345">
<mx:DataGrid horizontalCenter="0" id="dg" width="35%" height="100%"
dataProvider="{cms.getContentBySection.lastResult.contents.content}"
itemClick="itemClick(event);" >
<mx:columns>
<mx:DataGridColumn headerText="Employee Name" labelFunction="displayEmployeeName"/>
</mx:columns>
</mx:DataGrid>
<mx:Panel width="65%" height="100%" layout="absolute" id="datapanel">
<mx:Image y="10" width="180" height="180" id="image" x="10"/>
<mx:Label x="209" y="10" text="Title"/>
<mx:Label x="203" y="36" text="Email"/>
<mx:Label x="198" y="67" text="Phone"/>
<mx:Text x="246" y="10" width="110.5" id="title"/>
<mx:Text x="246" y="36" width="110.5" id="email"/>
<mx:Text x="246" y="65" width="110.5" id="phone"/>
</mx:Panel>
</mx:HBox>
On the data grid we have now added the itemClick attribute, which make sure that the function itemclick() will be called whenever the user selects an employee in the list. This function will update the fields in the panel.
function itemClick(event:Event):void {
datapanel.title = dg.selectedItem.contentdata.firstname + ' ' + dg.selectedItem.contentdata.surname;
title.text = dg.selectedItem.contentdata.title;
email.text = dg.selectedItem.contentdata.email;
phone.text = dg.selectedItem.contentdata.phone;
var imgContentKey:Object = dg.selectedItem.contentdata.image.@key;
var relatedContents:Object = cms.getContentBySection.lastResult.contents.relatedcontents;
var images:Object = relatedContents.content.(@key == imgContentKey).contentdata.images.image;
image.source = 'http://localhost:8080/cms/site/0/binary?id='+ images[0].binarydata.@key;
}
To show the image, we get the binary key of the related content, and use the servlet for getting binary data to show the image, as we would do in HTML.
Summary
Although Vertical Site is mainly used to generate HTML web pages, it is possible to use frameworks like Flex to enhance the user experience, as we show here. Flex can also be used in Adobe AIR, for developing desktop applications - an easy way to access Vertical Site data on your desktop.




Comments
If you want to comment on this article you need to be logged in.