Editing DataGrids with Popup Windows in Flex

Exclusive offer: get 50% off this eBook here
Flex 3 with Java

Flex 3 with Java — Save 50%

Develop rich internet applications quickly and easily using Adobe Flex 3, ActionScript 3.0 and integrate with a Java backend using BlazeDS 3.2

$23.99    $12.00
by Keith Lee | December 2009 | Web Development

The DataGrid is a commonly used component when creating applications in Flex. The component can represent columnar data with ease when connected to a dataProvider. There is a method of editing the data in the DataGrid without using an itemEditor. Of course, there is nothing wrong with using an itemEditor, but this alternative method of using a PopUp window deserves some consideration when implementing applications. This article by Keith Lee describes how to create a DataGrid, display a popup for each row of the DataGrid and add, edit or remove data from the DataGrid using the PopUp.

To start with we'll create a DataGrid which will contain a first name and a last name. We will add a Panel container to place our DataGrid into. Here is what our initial app looks like:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">
<mx:Panel title="Pop Up Window" >
<mx:DataGrid width="100%" height="100%">
<mx:columns>
<mx:DataGridColumn headerText="First Name"/>
<mx:DataGridColumn headerText="Last Name"/>
</mx:columns>
</mx:DataGrid>
</mx:Panel>
</mx:Application>

You'll notice the common Application tag along with the Panel. Immediately inside the Panel is our all important DataGrid. Note, if you are not familiar with the basics of Flex then stop here and head over to the Adobe site for an introduction. Although this tutorial is not complex, I wont be able to focus on the fundamentals.

I've set the DataGrid width and height attibutes to 100%. This will force it to expand to the size and width of the panel. You can make this application full screen by setting the same attributes on the Panel tag. Inside our DataGrid tag is the columns tag. Here we can describe what each column of our DataGrid will contain. In this case, one column for first name and one column for the last name. Here is a first look at our app:

Flex 3 with Java

Adding Data

The ease of Flex has allowed us to create this simple user interface with little effort. Now we come to a point where we need to add data to the DataGrid. The easiest way to do this is to use the dataProvider attribute. We will add an ArrayCollection Object to the script portion of our application to hold all the names which will appear in our DataGrid. The DataGrid and the accompanying ArrayCollection will look something like this:

<mx:DataGrid id="names" width="100%" height="100%" 
dataProvider="{namesDP}">
<mx:columns>
<mx:DataGridColumn headerText="First Name"
dataField="firstName"/>
<mx:DataGridColumn headerText="Last Name"
dataField="lastName"/>
</mx:columns>
</mx:DataGrid>

[Bindable]
public var namesDP:ArrayCollection =
new ArrayCollection ([
{firstName:'Keith',lastName:'Lee'},
{firstName:'Ira',lastName:'Glass'},
{firstName:'Christopher',lastName:'Rossin'},
{firstName:'Mary',lastName:'Little'},
{firstName:'Charlie',lastName:'Wagner'},
{firstName:'Cali',lastName:'Gonia'},
{firstName:'Molly',lastName:'Ivans'},
{firstName:'Amber',lastName:'Johnson'}]);

The dataProvider attribute binds the DataGrid to the nameDP ArrayCollection. The ArrayCollection constructor's argument is an array of objects. Each object has a firstName and lastName property. If you wanted to expand on this application, you can add more data to this Array. You should also notice that the DataGridColumn tags also have an addition. We've set the dataField equal to the property in the dataProvider. The dataField is the real key in populating the DataGrid. Here is what our populated DataGrid looks like:

Flex 3 with Java

We've now created the foundation of our application.

Activating the DoubleClick Event

By default the DataGrid doubleclick event is turned off. This means when a user doubleclicks an entry nothing will happen. In order to tell the DataGrid to trigger the doublelcick event we need to set the doubleClick and doubleClickEnabled attributes of the DataGrid tag. It looks like this:

<mx:DataGrid width="100%" height="100%" 
doubleClick="showPopUp(event)" doubleClickEnabled="true">

I've set the doubleClick attribute to a method called showPopUp. We've not written this method yet, but it will be responsible for displaying the PopUp window which will allow editing of the DataGrid data. For now, let's add the Script tag and an empty showPopUp method:

<mx:Script>
<![CDATA[

import mx.events.ItemClickEvent;

public function showPopUp(event:MouseEvent):void{

// show the popup
}

]]>
</mx:Script>

The Script tag is a child of the Application tag.

Flex 3 with Java Develop rich internet applications quickly and easily using Adobe Flex 3, ActionScript 3.0 and integrate with a Java backend using BlazeDS 3.2
Published: June 2009
eBook Price: $23.99
Book Price: $39.99
See more
Select your format and quantity:

Creating the PopUp

To create the PopUp for editing, you will need to create a new component for this project. This component will serve as the popup window for editing. Check with your version of the IDE (if using one) to determine how best to accomplish this task. Once you are ready to write the MXML for our popup window use the following code. I'll refer to this as the PopUp window.

<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical" title="Edit Name">
<mx:Form width="100%" height="100%">
<mx:FormItem label="First Name">
<mx:TextInput id="firstName"/>
</mx:FormItem>
<mx:FormItem label="Last Name">
<mx:TextInput id="lastName"/>
</mx:FormItem>
</mx:Form>
<mx:HBox width="100%">
<mx:Button label="Save"/>
<mx:Button label="Close"/>
</mx:HBox>
</mx:TitleWindow>

Here, our root item is the TitleWindow unlike Application in our main application. The TitleWindow is the perfect component for this task because it is already optimized for being a PopUp window. To go into more detail, I've added a Form which will contain the first name and last name fields as well as a Save and Close button. Once the popup is shown, we will populate the TextInput fields with the first and last names respectively. If the Save button is clicked, the data is saved back to the DataGrid. If the Close button is clicked no changes will be made to the DataGrid and the PopUp will disappear.

For more information on Flex Forms and the TitleWindow, see :

http://livedocs.adobe.com/flex/3/html/help.html?content=layouts_12.html

http://livedocs.adobe.com/flex/3/html/help.html?content=layouts_08.html

Now that we have our PopUp window created, we can move on to the job of making it appear when our DataGrid is doubleclicked. Enter the PopUpManager. The PopUpManager is a class which facilitates PopUps in Flex apps. The following code should be added to our Application file and the PopUp window. We'll start here by importing the manager class:

import mx.managers.PopUpManager;

Once this is imported, we can make use of the createPopUp method to show the PopUp. The createPopUp method returns an IFlexDisplayObject which points to our PopUp window. We'll need to keep the reference to this PopUp so that we can continue to comminucate with it. This means we will need to import the IFlexDisplayObject class in our Application:

import mx.core.IFlexDisplayObject;

Next we can call the createPopUp method to show the Popup. Here is the method call:

editNameWindow=PopUpManager.createPopUp(this, 
nameEditorPopUp, true);

We are assigning the return method to a previously declared variable called editNameWindow. The arguments to createPopUp are the parent - the displayObject over which to open the window, class - the WindowTitle component class to display as the popup and modal - an optional value which indicates whether or not the window takes all input until it is closed. Here is the updated Script tag for our application:

<mx:Script>
<![CDATA[

import mx.events.ItemClickEvent;
import mx.core.IFlexDisplayObject;
import mx.managers.PopUpManager;
import mx.core.IFlexDisplayObject;


public var editNameWindow:IFlexDisplayObject;

public function showPopUp(event:MouseEvent):void{

// show the popup
editNameWindow=PopUpManager.createPopUp(this,
nameEditorPopUp, true);

}

]]>
</mx:Script>

Here is what the current app looks like:

Flex 3 with Java

I've taken the liberty of making the application full screen by setting the width and height attributes of the Panel to 100%. This makes the screen less crowded for our new PopUp. Notice that we are not able to click on the DataGrid. This is because we set the modal argument to true.

Centering and Closing the Popup

For the previoius screen shot to look as it does, I moved the popup to the center of the window. We don't want users to be required to do this, so let's center it for them. This is done by calling the CenterPopUp method, passing it the TitleWindow you wish to center. This code will go into the PopUp window class. It is easily done here because we can tie the calling of CenterPopUp to the creationComplete event. Here is what we need to add:

  1. The creationComplete event should call a centerWindow method:
    <mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" 
    layout="vertical"
    title="Edit Name"
    creationComplete="centerWindow()">
  2. Add the centerWindow method
    <mx:Script>
    <![CDATA[

    import mx.managers.PopUpManager;

    private function centerWindow():void {

    PopUpManager.centerPopUp(this);

    }

    ]]>
    </mx:Script>

Just as in our Application file, we need to import the PopUpManager. Notice the call to centerPopUp passes 'this', which is the TitleWindow. Doubleclicking on a datagrid item nows shows a perfectly center aligned PopUp.

To Close this window we will use a similar method to centering. For this case, we will connect our Close button to a new method of our PopUp which will call the removePopUp method. Here are the two steps we need to follow:

  1. Add the click event to our Close button. The click event will call the closeWindow method:
    <mx:Button label="Close" click="closeWindow()"/>
  2. Add the closeWindow method
    private function closeWindow():void{

    PopUpManager.removePopUp(this);

    }

There is also another method we can employ to allow the user to close this window. The TitleWindow can display a close icon on the upper right portion of the PopUp. This is a common location where close buttons appear. We can turn on the display of this button and also tell the TitleWindow to call our closeWindow method if it is clicked on. This can be implemented by adding two attributes:

showCloseButton="true" close="closeWindow()"

Populating the PopUp with First and Last Name

This is probably the most complicated part of this application. Here we must pass data to our PopUp and display the data in the TextInput fields. The first step in carrying out this task is to cast our PopUp to a type which we can work with. When we created the PopUp, we were able to save an IFlexDisplayObject returned to us by createPopUp. This Object needs to be cast to a nameEditorPopup which is our TitleWindow class as shown below. If you named your PopUp something different, you will cast it to the name of the you created (instead of nameEditorPopup).

// cast to a nameEditorPopup
myPopUp = nameEditorPopUp(editNameWindow);

Next, we can simply assign our DataGrid selected item and the namesDP ArrayCollection to properties of our PopUp:

// pass the popUp my DataGrid Item
myPopUp.DataGridName = names.selectedItem;
myPopUp.DataGridNameAC = namesDP;

Of course, we'll have to make the related changes in our PopUp Object, but we'll get to that in a second. It is important to note here that we are assigning both the item which was doubleclicked on and the entire ArrayCollection. We need the object which is doubleclick on (selectedItem) to populate the TextInput fields in the PopUp. We will bind these properties as you will see below. We need the ArrayCollection because we need to call the itemUpdatedMethod of the ArrayCollection so that the DataGrid will be update to reflect data which has been changed in the ArrayCollection. There are other methods of doing this, but this one will suffice for this demonstration.

Here is the updated showPopUp method from the Application:

public var editNameWindow:IFlexDisplayObject;

public var myPopUp:nameEditorPopUp;

public function showPopUp(event:MouseEvent):void{

// show the popup
editNameWindow=PopUpManager.createPopUp(this,
nameEditorPopUp, true);

// cast to a nameEditorPopup
myPopUp = nameEditorPopUp(editNameWindow);

// pass the popUp my DataGrid Item
myPopUp.DataGridName = names.selectedItem;
myPopUp.DataGridNameAC = namesDP;

}

For the PopUp window we need to make several changes. First we need to create two variables for saving the ArrayCollection and the selectedItem of the DataGrid:

[Bindable] public var DataGridName:Object;
[Bindable] public var DataGridNameAC:ArrayCollection;

Next, we'll need to bind our Forms firstName and lastName to the properties of our DataGridName object:

<mx:Form width="100%" height="100%">
<mx:FormItem label="First Name">
<mx:TextInput id="firstName" text="{DataGridName.firstName}"/>
</mx:FormItem>
<mx:FormItem label="Last Name" >
<mx:TextInput id="lastName" text="{DataGridName.lastName}"/>
</mx:FormItem>

This will effectively populate the first and last name of the DataGrid row. Here is what it will look like:

Flex 3 with Java

Saving the Data

Lastly, we need to save the changes made by the user back to the DataGrid. The first step here is to create a method to save our form data to the ArrayCollection and call the itemUpdatedMethod of the ArrayCollection. Here is what our method will look like (this is in the PopUp window):

private function saveName():void{

// update the name
DataGridName.firstName = firstName.text;
DataGridName.lastName = lastName.text;

// update the array collection
DataGridNameAC.itemUpdated(DataGridName);

// close the window
closeWindow();
}

Nothing too complicated here. We are simply saving the text from the Form's firstName and lastName back into the DataGridName object. Doing this will directly change the DataGrid because the DataGridName is a reference to the selected Item od the DataGrid. We then need to update the display by calling DataGridNameAC.itemUpdated. If we don't call this second method, the user may be left with the impression that the data was not saved, because the screen may not update.

Finally, we call the closeWindow() method to remove the Popup.

Complete Code

Main Application

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">
<mx:Panel title="Pop Up Window" width="100%" height="100%">
<mx:DataGrid id="names" width="100%" height="100%"
doubleClick="showPopUp(event)"
doubleClickEnabled="true" dataProvider="{namesDP}">
<mx:columns>
<mx:DataGridColumn headerText="First Name"
dataField="firstName"/>
<mx:DataGridColumn headerText="Last Name"
dataField="lastName"/>
</mx:columns>
</mx:DataGrid>
</mx:Panel>

<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;

import mx.events.ItemClickEvent;
import mx.core.IFlexDisplayObject;
import mx.managers.PopUpManager;
import mx.core.IFlexDisplayObject;

[Bindable]
public var namesDP:ArrayCollection =
new ArrayCollection ([{firstName:'Keith',lastName:'Lee'},
{firstName:'Ira',lastName:'Glass'},
{firstName:'Christopher',lastName:'Rossin'},
{firstName:'Mary',lastName:'Little'},
{firstName:'Charlie',lastName:'Wagner'},
{firstName:'Cali',lastName:'Gonia'},
{firstName:'Molly',lastName:'Ivans'},
{firstName:'Amber',lastName:'Johnson'},
]);

public var editNameWindow:IFlexDisplayObject;

public var myPopUp:nameEditorPopUp;

public function showPopUp(event:MouseEvent):void{

// show the popup
editNameWindow=PopUpManager.createPopUp(this, nameEditorPopUp, true);

// cast to a nameEditorPopup
myPopUp = nameEditorPopUp(editNameWindow);

// pass the popUp my DataGrid Item
myPopUp.DataGridName = names.selectedItem;
myPopUp.DataGridNameAC = namesDP;

}

]]>
</mx:Script>
</mx:Application>

Title Window (POPUP)

<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical" title="Edit Name" creationComplete="centerWindow()"
showCloseButton="true" close="closeWindow()">
<mx:Form width="100%" height="100%">
<mx:FormItem label="First Name">
<mx:TextInput id="firstName" text="{DataGridName.firstName}"/>
</mx:FormItem>
<mx:FormItem label="Last Name" >
<mx:TextInput id="lastName" text="{DataGridName.lastName}"/>
</mx:FormItem>
</mx:Form>
<mx:HBox width="100%">
<mx:Button label="Save" click="saveName()"/>
<mx:Button label="Close" click="closeWindow()"/>
</mx:HBox>

<mx:Script>
<![CDATA[

import mx.managers.PopUpManager;
import mx.collections.ArrayCollection;

[Bindable] public var DataGridName:Object;
[Bindable] public var DataGridNameAC:ArrayCollection;

private function centerWindow():void {

PopUpManager.centerPopUp(this);

}

private function closeWindow():void{

PopUpManager.removePopUp(this);
}

private function saveName():void{

// update the name
DataGridName.firstName = firstName.text;
DataGridName.lastName = lastName.text;

// update the array collection
DataGridNameAC.itemUpdated(DataGridName);

// close the window
closeWindow();
}

]]>
</mx:Script>
</mx:TitleWindow>

Summary

We were able to create a alternative method to using itemRenderers and ItemEditors for changing data in our datagrid. This method is straight forward and extenable allowing it to be adapted to your own application. From here you'll need to focus on saving the DataGrid data to you server or desktop application.

Related Links:

http://livedocs.adobe.com/flex/3/html/help.html?content=layouts_12.html

http://livedocs.adobe.com/flex/3/html/help.html?content=layouts_08.html

http://livedocs.adobe.com/flex/3/html/help.html?content=dpcontrols_6.html

http://livedocs.adobe.com/flex/3/html/help.html?content=databinding_1.html

 

If you have read this article you may be interested to view :

 

Flex 3 with Java Develop rich internet applications quickly and easily using Adobe Flex 3, ActionScript 3.0 and integrate with a Java backend using BlazeDS 3.2
Published: June 2009
eBook Price: $23.99
Book Price: $39.99
See more
Select your format and quantity:

About the Author :


Keith Lee has been a software developer since graduating college in 1999 with an MS in Systems Administration and Computer Networking. He has developed in many languages, but more recently in Flex/ActionScript and PHP. Presently he is a contributing author for the Developer Shed Network of sites and consults on private projects. Keith currently serves as Senior Software Developer of Special Projects for Ziff Davis Enterprise.

Books From Packt


ADempiere 3.4 ERP Solutions
ADempiere 3.4 ERP Solutions

ModSecurity 2.5
ModSecurity 2.5

Asterisk 1.6
Asterisk 1.6

JBoss RichFaces 3.3
JBoss RichFaces 3.3

jQuery 1.3 with PHP
jQuery 1.3 with PHP

Ext JS 3.0 Cookbook
Ext JS 3.0 Cookbook

Joomla! with Flash
Joomla! with Flash

jQuery UI 1.7: The User Interface Library for jQuery
jQuery UI 1.7: The User Interface Library for jQuery


No votes yet
Excellent by
Excellent post.....

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
k
y
d
F
5
L
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software