Updated for Flash Builder 4 release version 🙂
In this article we will create a CRUD application using Adobe Flex and LiveCycle Data Services. Flash Builder 4 allows developers to build Flex front end for LiveCycle Data Services (LCDS) Data management service destinations with just couple of clicks, so we will use Flash Builder 4 to develop this application.
Below are the steps we will follow to complete our application
- Set up LiveCycle Data Services
- Use Flash Builder to generate Flex code to invoke methods in Java class on the server
- Retrieve data from server and display in the application
- Allow user to add/update/delete entries from the application
In this article we will be building a Flex application for a Data Management service destination in the samples application called lcds-samples bundled with LiveCycle Data Services ES2.
Article allows you to skip any of steps mentioned above and copy the code 🙂 Let’s get started 🙂
You can download the completed project from here http://sujitreddyg.com/fb4articles/release/LCDSCRUD.fxp
Install LCDS 3
Download LiveCycle Data Services 3 from this URL http://www.adobe.com/go/trylivecycle_dataservices. You will be downloading a file named lcds3-win.exe/lcds3-mac.zip, execute this file to install. I have installed LCDS 3 with Tomcat to C:\lcds3
Install Flash Builder 4
Download and install Flash Builder 4 from here http://www.adobe.com/products/flashbuilder/
Enabling RDSDispatchServlet
Flash Builder uses the RDSDispatchServlet (part of LCDS) to retrieve destinations information from the server. By default the RDSDispatchServlet is commented out in web.xml. Open C:\lcds3\tomcat\webapps\lcds-samples\WEB-INF\web.xml using a text editor and remove comment around RDSDispatchServlet Servlet definition and the URL mapping as shown below. Also set the “useAppserverSecurity” parameter value to “false” as shown below.
<servlet>
<servlet-name>RDSDispatchServlet</servlet-name>
<display-name>RDSDispatchServlet</display-name>
<servlet-class>flex.rds.server.servlet.FrontEndServlet</servlet-class>
<init-param>
<param-name>useAppserverSecurity</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>10</load-on-startup>
</servlet>
<servlet-mapping id=”RDS_DISPATCH_MAPPING”>
<servlet-name>RDSDispatchServlet</servlet-name>
<url-pattern>/CFIDE/main/ide.cfm</url-pattern>
</servlet-mapping>
Defining item class name
Set the item-class property of the Data Management service destination in Data Management service configuration file (C:\lcds3\tomcat\webapps\lcds-samples\WEB-INF\flex\data-management-config.xml) to the name of the object type which the assembler is expecting. Flash Builder 4 DCD requires this property to be set for the destinations you want to consume using DCD in Flash Builder. All the sample destinations in LCDS 3 beta 3 have this property set. Sample destination used in this article has item-class property set to flex.samples.product.Product class as shown below.
<properties>
<source>flex.samples.product.ProductAssembler</source>
<scope>application</scope>
<item-class>flex.samples.product.Product</item-class>
<metadata>
<identity property=”productId”/>
</metadata>
<network>
<paging enabled=”false” pageSize=”10″ />
</network>
</properties>
</destination>
Start LCDS server
Start LCDS samples data base from the start menu, start -> All Programs -> Adobe -> LiveCycle Data Services ES 3.0 -> Start Samples Database
Start LCDS server from the start menu, start -> All Programs -> Adobe -> LiveCycle Data Services ES 3.0 -> Start LiveCycle Data Services Server
Please make sure both the database and the server are started.
We have everything ready to develop a Flex application for data management service destinations using Flash Builder 4.
Create a Flex project
Start Flash Builder 4 from the start menu, start -> All Programs -> Adobe -> Adobe Flash Builder
Create a Flex project from File -> New -> Flex Project. You will see a window launched with options to fill project properties as shown in the image below. Fill project properties as shown in the image below.
In this screen:
- Set project name to LCDSCRUD
- Let the Application type be Web
- Use default Flex SDK (Flex 4.0)
- Set the Application server type to J2EE
- Select Use remote object access service check box
- Select LiveCycle Data Services ES
- Click next to continue
Now we need to set the server properties, you will see a screen with options to set the server properties as shown in the image below.
In this screen:
- Set the Root folder to c:\lcds3beta3\tomcat\webapps\lcds-samples
- Set the Root URL to http://localhost:8400/lcds-samples
- Set the Context root to /lcds-samples
- Leave the Output folder to default, which is on the server
- Click finish to continue
All we have to do now is to see how we can consume the service and create a Flex application. With Flash Builder 4 this is very simple, let’s see how Data centric Development (DCD) features in Flash Builder 4 lets us easily consume data management services and bind them to UI controls.
Consuming data management services from Flash Builder 4
- Select the Data/Services window shown in the image above. If this is not visible, select it from Window -> Data/Services
- Click on “Connect to Data/Service” (highlighted in the image) in the Data/Services window
You will see a window launched with options to select the type of service as shown in the image below.
In this screen, select LCDS and click on Next to continue. Flash Builder will display a window asking for RDS credentials. Since we turned off security for our RDSDispatchServlet by setting the “useAppserverSecurity” parameter to “false” in the web.xml, select “No password required” and click on OK to continue.
Now Flash Builder will retrieve all the Remoting service and Data Management service destinations exposed by the web application and displays as shown in the image below.
Our server settings are configured to point to the sample application bundled with LCDS called lcds-samples. This web application has lots of destinations exposed as shown in the image above. Destinations whose service-type is remoting-service are the Remoting service destinations and the ones whose service-type is data-service are the Data Management service destinations. In this sample we will use the “inventory” data management service destination. Select the destination and click on Finish to continue.
Flash Builder will generate all code required to consume the service selected and will list the Inventory service in the services explorer as shown in the image below.
You can also see that the return types for the operations (functions/methods of assembler) are properly set. Now that we have the service created, let’s create UI.
Creating UI
Please copy the code from this URL http://sujitreddyg.com/fb4articles/release/LCDSCRUD_1.mxml.txt into your main application file (LCDSCRUD.mxml in this sample). Code in the URL will add UI controls required for this sample application. After copying the code, your Flash Builder design view should look as shown in the image below.
Note: In this article to refer to a control, we will use value set for the id property of the controls.
Create Form for the Customer data type
We will display the details of the product entry selected in the listProducts control (created in previous step) in formSelectedProduct. Using Flash Builder you can bind a Form control to an entity instance. Right click on the formSelectedProduct and select “Bind to Data” as shown in the image below.
Flash Builder will display window as shown in the image below.
In this screen:
- We want the Form items to be generated based on a data type (Product) so select “Data type”
- Select Product from the list of data types
- We want the form to be editable, so select the “Make form editable” check box
- Click Next to continue
- Flash Builder will display the list of properties in the selected data type as shown in the image below. Flash Builder will also assign a UI control which it will use to display the property value as shown in the image below.
In this window, you can select the items which you want to be included in the form and UI control in which you want the property value to be displayed. You can also arrange the controls in the order in which you want them to be displayed. Select, arrange the properties and modify the controls as shown in the image above.
Flash Builder will add FormItems to formSelectedProduct and binds the values of the controls under formSelectedProduct to Product instance. In this sample Flash Builder generated a Product instance with “product” as its id. So we will refer to the Product instance bound to the items in formSelectedProduct as product.
Binding data to UI Controls
Now that we have our UI is ready, let’s get the data from the server and display it in the application.
Right click on the List and click on “Bind to Data ..” as shown in the image below.
Flash Builder will display window as shown in the image below.
In this screen:
- Select New service call
- Set Service to ProductService
- Set Operation to fill(…args): Product[]
- Set Bing to field to name
- Click on OK to continue
The fill(… args) function accepts optional parameters and so Flash Builder will automatically switch to code view to let you enter the arguments to be passed to the fill() function. In this example we will not pass any parameters, so leave the fill() function arguments empty as shown in the image below.
In previous step we bound the service call result to listProducts component, listProducts will send a request to the fill() function on the server and displays the result.
listProducts is displaying only the name of the Product, so let’s display complete details of the product in formSelectedProduct. Right click on the listProducts and select “Generate Change Handler” as shown in the image below.
Flash Builder will generate a function which will be invoked when user selects a different item in the listProducts. Flash Builder will also switch the view to Source view as shown in the image below, so that you can write code in the handler function generated.
Add the code below to the generated change handler function as shown in the image above.
product = listProducts.selectedItem as Product;
In the code snippet above, product is the instance of Product which was bound to the formSelectedProduct. In the code above, we are passing the reference of the selected Product instance in listProducts to the Product instance bound to formSelectedProduct. This line of code will populate formSelectedProduct with details of the selected product in listProducts control.
Now, let’s keep formSelectedProduct populated with values of the first Product entry in listProducts as soon as the product data is loaded from the server.
Understanding the CallResponder
How will you know when the data is returned from the server? For each service call generated in the application there will be a CallResponder class instance associated with it. CallResponder dispatches result event when the call to the service is successful and the data returned from the server can be accessed using a property called lastResult in CallResponder instance. To map the CallResponder instance with the service call, you have to pass the reference of the AsyncToken returned by the service call to the token property of the CallResponder. You can see service call AsyncToken reference passed to the CallResponder in listProducts_creationCompleteHandler function as shown below.
protected function listProducts_creationCompleteHandler(event:FlexEvent):void
{
fillResult.token = productService.fill();
}
CallResponder class will dispatch result event when the data is retrieved successfully from the server. You can add a handler to the result event to perform any logic when the server response is successful. In our case we will keep the first product in the listProducts to be selected and its value to be displayed in formSelectedProduct as soon as the data from the server is loaded on to the client.
Add a result event handler to the fillResult CallResponder as shown in the image below.
In the generated result handler add the following code. In the code below list is the List instance added in previous steps.
protected function fillResult_resultHandler(event:ResultEvent):void
{
if(listProducts != null)
{
listProducts.selectedIndex = 0;
product = listProducts.selectedItem as Product;
}
}
You can observe that Flash Builder also generated a Button (id=”button”) and also generated a click handler (button_clickHandler) for the Button, in which code to bind the values in the Form (id=”formSelectedCustomer”) to simpleCustomer object. Just delete the Button and the click handler.
You can see the LCDSCRUD.mxml file with code till this step at this URL http://sujitreddyg.com/fb4articles/release/LCDSCRUD_2.mxml.txt
At this point you can save and run the application. Application will launch in a browser and displays the data retrieved from the server as shown in the image below. You can view details of the products by selecting them from the list.
Performing Add/Update/Delete operations
Any data retrieved from a Data Management service destinations are managed on the client i.e. any changes made to the objects on the client will reflect on the server immediately. Since we want to commit changes to the server only on user interaction, let’s turn off the autoCommit property to false. Add the code below to listProducts_creationCompleteHandler function to turn off auto commit as shown in the image below.
productService.serviceControl.autoCommit = false;
Let’s invoke functions in the productService AS3 class when user clicks on Add/Update/Delete buttons created earlier.
Right click on the button labeled “Add” (id = “btnAdd”) and select “Generate Service Call ..” as shown in the image below.
Flash Builder displays window as shown in the image below, in which you can select the service call which you want to invoke when user clicks on the Button.
In this screen:
- Set the Service to ProductService
- Set the Operation to createProduct(arg0:Product)
- Click on OK to continue
The createProduct function selected expects an argument of the type Product. So Flash Builder 4 will switch to the source view and lets you enter the argument as shown in the image below.
We are creating a new instance of Product with default values to few properties and pass the reference to createProduct function. We pass the newly created Product instance reference to product so that user can modify the values of newly created product from formSelectedProduct control.
Code in the button click handler function will look as shown below. In the code snippet below we are also passing the AsyncToken returned by createProduct function to createProductResult, so that createProductResult object will dispatch result event when the service call is successful.
protected function btnAdd_clickHandler(event:MouseEvent):void
{
var newProduct:Product = new Product();
newProduct.category = “Enter category”;
newProduct.description = “Product description”;
newProduct.name = “Enter Name”;
newProduct.price = 0;
newProduct.qtyInStock = 0;
product = newProduct;
createProductResult.token = productService.createProduct(newProduct);
}
We also need to bind the changes made in the formSelectedProduct to the Product (id=”product”) so that the changes made by the user will be updated in the selected Product instance. Bind the values in the input controls to respective properties in Product instance as shown below and highlighted in the image below.
<fx:Declarations>
<valueObjects:Product qtyInStock=”{parseInt(qtyInStockTextInput.text)}”
price=”{parseFloat(priceTextInput.text)}”
category=”{categoryTextInput.text}”
description=”{descriptionTextInput.text}”/>
</fx:Declarations>
If you remember we turned off auto commit, so we need to call when user clicks the btnCommit. We also need to make sure the btnCommit is enabled only if there are any changes to the data on the client and that’s very simple just bind the btnCommit enabled property to commitRequired property as shown in the image below.
In the btnCommit_clickHandler function add the code below to commit all changes to the server.
protected function btnCommit_clickHandler(event:MouseEvent):void
{
productService.serviceControl.commit();
}
Similarly generate service calls for Update and Delete buttons, select updateProduct and deleteProduct operations respectively and pass the same product object as argument. You can view/copy the completed LCDSCRUD.mxml file at this URL http://sujitreddyg.com/fb4articles/release/LCDSCRUD.mxml.txt
Save and run your application. You will see your application launched in a browser and ready for performing CRUD operations on the database entries.
More articles on how to use Flash Builder 4 are available at this URL https://sujitreddyg.wordpress.com/flash-builder-4/
We developed a complete CRUD application for Data Management service destination in just few minutes. Flash Builder 4 and LCDS rocks 🙂