Pages

Thursday, July 31, 2008

Flex CRUD application with drag and drop and LifeCycle

I remade my old Drag and Drop Employee application by using Adobe LifeCycle Data Services( which is free for one cpu ). In the first edition I used BlazeDS, but with LifeCycle it is a little bit easier to do CRUD operations on an Employees table. In BlazeDS I had to made different java methods which does the CRUD operations. Now I only have to add an new Employee object to the ArrayCollection or update an Employee oject in the ArrayCollection and LifeCycle does the transaction. But LifeCycle has something extra it can push the changes to the other Flex clients which are using the same Data Service.
This are the features of the demo application. I can drag an employee in the Tree to an other department. Click on an employee and a new update Tab is shown where I can update the employee or I can create an new employee in a create employee tab.
Here are some screenshots.




To let this example work you need to do the following things.

setup lifecycle in jdeveloper

configure lifecycle for the employees table

download Flexlib for the dragable and closeable Tabs. These guys did a perfect job.

Here is the source code of java side and here is the Flex code

These are the things I needed to do.

<mx:DataService id="ds" destination="employee" message="messageHandler(event.message)"/>

<mx:ArrayCollection id="employeeArray" />

Step 1 fill the employeeArray


public function init():void{
ds.autoCommit=false;
ds.autoSyncEnabled = true;
ds.addEventListener(ResultEvent.RESULT, resultHandler);
ds.addEventListener(DataServiceFaultEvent.FAULT, faultHandler);
ds.addEventListener(DataConflictEvent.CONFLICT, conflictHandler);
var token:AsyncToken = AsyncToken(ds.fill(employeeArray));
token.kind = "fill";
}

Step 2 wait for the employee retrieving result, sort this result on departmentId and Firstname and build a new xml from the Arraycollection for the Tree.

private function resultHandler(event:ResultEvent):void
{
if (event.token.kind == "fill")
{
// fill tree
sortEmployees();
refreshTree();
}
}

private function sortEmployees():void {
var deptSortField:SortField = new SortField();
deptSortField.name = "departmentId";
deptSortField.numeric = true;
var firstNameSortField:SortField = new SortField();
firstNameSortField.name = "firstName";
firstNameSortField.numeric = false;

/* Create the Sort object and add the SortField object created earlier to the array of fields to sort on. */
var employeeDataSort:Sort = new Sort();
employeeDataSort.fields = [deptSortField,firstNameSortField];

/* Set the ArrayCollection object's sort property to our custom sort, and refresh the ArrayCollection. */
employeeArray.sort = employeeDataSort;
employeeArray.refresh();
}
public function refreshTree():void{
mainXML = new XMLDocument();
var rootXML:XMLNode = mainXML.createElement("root");
rootXML.attributes.type = "root";

for ( var i:int = 0 ; i < employeeArray.length ; i++ ) {

var department:int = employeeArray.getItemAt(i).departmentId;
var search:Array = rootXML.childNodes;
var deptXML:XMLNode = null;

if ( search.length > 0 ) {
for ( var b:int =0 ; b < search.length ; b++ ) {
if ( search[b].attributes.id == department.toString()) {
deptXML = search[b];
break;
}
}
}
if ( deptXML==null ) {
deptXML = mainXML.createElement("department");
deptXML.attributes.label = department;
deptXML.attributes.type = "dept";
deptXML.attributes.id = department.toString();
rootXML.appendChild(deptXML);
}
var firstName:String = employeeArray.getItemAt(i).firstName;
var lastName:String = employeeArray.getItemAt(i).lastName;
var employee:int = employeeArray.getItemAt(i).employeeId;

var elementXML:XMLNode = mainXML.createElement("employee");
elementXML.attributes.label = firstName+" "+lastName;
elementXML.attributes.type = "emp";
elementXML.attributes.id = employee;
deptXML.appendChild(elementXML);
}
mainXML.appendChild(rootXML);
myXml = new XML(mainXML.toString());

tree.dataProvider = myXml;
openAllNodes();
}


Step 3 When we want to change an employee we have to find this employee, we will use a filter function and I add the code for an update and an insert

private function filterEmployees():void {
employeeArray.filterFunction = processFilter;
employeeArray.refresh();
}

private function removeFilterEmployees():void {
employeeArray.filterFunction = null;
employeeArray.refresh();
}


private function processFilter(employee:Object):Boolean {
return parseInt(employee.employeeId) == searchEmployeId;
}

// update
var employeeLocal:Object = null;
// search the employee
searchEmployeId = employeeId;
filterEmployees();
// if found we can update the department.
if ( employeeArray.length == 1 ) {
employeeLocal = employeeArray.getItemAt(0);
}
removeFilterEmployees();

employeeLocal.departmentId = departmentId;
employeeLocal.email = email;
employeeLocal.firstName = firstName;
employeeLocal.lastName = lastName;
employeeLocal.jobId = jobId ;
employeeLocal.hireDate = hireDate;


ds.commit();
var token:AsyncToken = AsyncToken(ds.fill(employeeArray));
token.kind = "fill";

// insert
employee = new Employee();
employee.employeeId = employeeId;
employee.departmentId = departmentId;
employee.email = email;
employee.firstName = firstName;
employee.lastName = lastName;
employee.jobId = jobId ;
employee.hireDate = hireDate;
employeeArray.addItem(employee);
ds.commit();
var token:AsyncToken = AsyncToken(ds.fill(employeeArray));
token.kind = "fill";

No comments:

Post a Comment