ArtsAutosBooksBusinessEducationEntertainmentFamilyFashionFoodGamesGenderHealthHolidaysHomeHubPagesPersonal FinancePetsPoliticsReligionSportsTechnologyTravel

How-To Update Data in an Adobe Flex DataGrid Cell using e4x | ActionScript | XML | Flash

Updated on May 16, 2012

Capturing, editing and updating data in an Adobe Flex or Flash DataGrid using ActionScript is very easy. In fact a lot easier than the most examples will show. The one important fact you need to remember about DataGrids is that they are only there to display data and to capture data. They display data that is stored in the data store, which is most cases is an ArrayCollection or XMLList.

Through the incredible sophistication of the Flex (Flash) API and its fabulous implementation of the e4x (EcmaScript for XML) standard, a developer can traverse an ArrayCollection with ease. This article demonstrates how to capture data from the grid, modify and updated it with ease and very little code.

Create a Flex Application

First create a Flex Project: UpdateDataGrid. It can be an Air or Web type application.
Next, if you are using Flex Builder 4 and later, you can add a spark skin from a template, or simply add a color of your choice. For this example I chose the theme: Arcade
Switch to the Design view and drag and drop a Panel onto the Application screen. also drag and drop a DataGrid.
Switch to the code view and change the columns to:

  • headerText:”Title”, dataField=”title”
  • headerText:”Price”, dataField=”price”
  • headerText:”Quantity”, dataField=”quantity”
  • headerText:”Total”, dataField=”total”


Make the following property changes, additions to the DataGrid in the Code view:

  • editable=”true”
  • dataProvider=”{orderArr}”
  • id=”orderGrid”
  • itemEditEnd="orderGrid_itemEditEndHandler(event)"
  • doubleClickEnabled="true"
  • doubleClick="orderGrid_doubleClickHandler(event)"


Also make the Total column non editable as we will update this column based on the values that will be entered in the Price and/or Quantity columns:

<s:Panel x="75" y="139" width="735" height="210">
		<mx:DataGrid x="44" y="0" width="640" height="155" editable="true"
					 dataProvider="{orderArr}" id="orderGrid"
					 itemEditEnd="orderGrid_itemEditEndHandler(event)"
					 doubleClickEnabled="true"
					 doubleClick="orderGrid_doubleClickHandler(event)">
			<mx:columns>
				<mx:DataGridColumn headerText="Title" dataField="title"/>
				<mx:DataGridColumn headerText="Price" dataField="price"/>
				<mx:DataGridColumn headerText="Quantity" dataField="quantity"/>
				<mx:DataGridColumn headerText="Total" dataField="total" editable="false"/>
			</mx:columns>
		</mx:DataGrid>
	</s:Panel>

You can resize the DataGrid in the Design View to taste. Next I am going to add ActionsScript 3 code in the mxml file to handle the interaction with DataGrid through the itemEditEnd event and the doubleClick event. The former will be called every time the cursor leaves the focus of a cell by tabbing or by mouse click. The latter will be called when a user double clicks on the DataGrid.

Add a Script element to the file and define a bindable ArrayCollection: orderArr.

[Bindable]
protected var orderArr:ArrayCollection;

Add init Function

Next add a protected function, init() with a void return type. In the function set the ArrayCollection and add an empty row so the user will have at least an initial empty row when launching the app. Add the function to the CreationComplete event in the application element.

protected function initApp():void
{
	//initialize the ArrayCollection
	orderArr = new ArrayCollection();
	orderArr.addItem({title:'',price:'',quantity:'',total:''});
}

Add orderGrid_itemEditEndHandler Function

Now for the bulk of the logic of our application and the main objective of this tutorial, create a protected function, orderGrid_itemEditEndHandler(event:DataGridEvent), with a DataGridEvent as a parameter. Btw, Flex Builder 4 and later will generate this for you when you add the itemEditEnd, or any other event to an element.

protected function orderGrid_itemEditEndHandler(event:DataGridEvent):void
{


}

Add Cancel Event


In our function, first check to see if the user cancels an edit and exit, return, from the function

if (event.reason == DataGridEventReason.CANCELLED)
{
// Do not update cell.
return;
}

Find Row to Edit in ArrayCollection

Next and this is important, we will need to know which row is being edited in the Adobe Flex DataGrid and also to know which row to edit in the ArrayCollection: orderArr. We will use this object, data, to access and update all our values in the mx.DataGrid

/**
* If you need to update an existing record get the row number in the grid
* and fetch the record from the ArrayCollection. It will be the same row number.
* */
				
var data:Object = orderArr.getItemAt(event.rowIndex);

Get New Value from Cell

Next I will store the new value from the cell that is being edited in a variable to be used to update our ArrayCollection and by extension our mx.DataGrid display.

/**
 * Get the new value from the editor. We will need to convert this to number for the price, 
 * quantity and total column values
 * */
			
var newVal:String = event.currentTarget.itemEditorInstance.text;

Get Original Value from Cell

I will also create a variable to the old or initial value in case the user enters a faulty value and we need to replace the original value back into the cell. Notice I am accessing two different properties of the currentarget. To get the new value, I am using the itemEditorInstance and to get the original value, I am using the editedItemRenderer property.

/**
 * Get the original value;
 * */
var oldVal:String = event.currentTarget.editedItemRenderer.data[event.dataField];

Validate Value Input

Ok, now to make sure the user only enters a valid number for the price and/or quantity columns, I will add the following code:

/**
 * Test to see if the new value is a number. If not reset to original value
* */
				
if((isNaN(new Number(newVal)) && event.dataField=='price') ||
	(isNaN(new Number(newVal)) && event.dataField=='quantity') )
				{
					Alert.show("This is not a valid number","Error");
					
					switch(event.dataField)
					{
						case 'price':
							data.price = oldVal;
							break;
						case 'quantity':
							data.quantity = oldVal;
							break;
											}
					return;
				}

First we make sure that the value is indeed a number, by attempting to convert the value to a Number and if we are editing a cell in either the price or quantity columns. If the validation fails, display a error message using Alert. Also notice how the original value is returned to the ArrayCollection. All we need to do is update the appropriate field in the ArrayCollection using the e4x syntax. This is the jest of this tutorial. In this case: data.price = oldVal and data.quantity = oldVal. No need to create any custom ItemRenderers or Editors. You just need to update the ArrayCollection once you have a handle on the row object, which we determined with: var data:Object = orderArr.getItemAt(event.rowIndex). Now we can use data and the appropriate field to update our data values.

Update DataGrid with New Value

To update the Adobe Flex mx.DataGrid, you simply obtain check if you are in the appropriate field and the value is indeed a Number and that is is greater than 0. Also you can check that the next field that is need for the update, and in our case, it is the “Quantity” field also has a value greater than 0 and even if this is a bit redundant, to check if the value is a Number. If we have the proper conditions, we only need to set the total field in the ArrayCollection at the appropriate row, like so data.total=new Number(newVal) * new Number(data.price);

if(event.dataField=='price' && new Number(newVal) > 0 && !isNaN(new Number(newVal)))
{
if((new Number(event.itemRenderer.data['quantity']) > 0 &&     !isNaN(event.itemRenderer.data['quantity'])) )
	{
	   data.total = new Number(newVal) * new Number(data.quantity);
	}
}else if(event.dataField=='quantity' && 
                   new Number(newVal) > 0 && !isNaN(new Number(newVal)))
{
            if((new Number(event.itemRenderer.data['price']) > 0 &&      
                                                          !isNaN(event.itemRenderer.data['price'])) )
            {
	        data.total = new Number(newVal) * new Number(data.price);
            }
}

Complete Function Code

protected function orderGrid_itemEditEndHandler(event:DataGridEvent):void
			{
				if (event.reason == DataGridEventReason.CANCELLED)
				{
					// Do not update cell.
					return;
				}
				/**
				 * If you need to update an existing record get the row number in the grid
				 * and fetch the record from the ArrayCollection. It will be the same row number.
				 * */
				
				var data:Object = orderArr.getItemAt(event.rowIndex);
				
				/**
				 * Get the new value from the editor. We will need to convert this to number for the price, 
				 * quantity and total column values
				 * */
			
				var newVal:String = event.currentTarget.itemEditorInstance.text;
				
				/**
				 * Get the original value
				 * */
				var oldVal:String = 
					event.currentTarget.editedItemRenderer.data[event.dataField]; 
				
				/**
				 * Test to see if the new value is a number. If not reset to original value
				 * */
				
				if((isNaN(new Number(newVal)) && event.dataField=='price') ||
					(isNaN(new Number(newVal)) && event.dataField=='quantity') ||
						(isNaN(new Number(newVal)) && event.dataField=='total'))
				{
					Alert.show("This is not a valid number","Error");
					
					switch(event.dataField)
					{
						case 'price':
							data.price = oldVal;
							break;
						case 'quantity':
							data.quantity = oldVal;
							break;
						case 'total':
							data.total = oldVal;
							break;
					}
					return;
				}
				
				if(event.dataField=='price' && new Number(newVal) > 0 && !isNaN(new Number(newVal)))
				{
					if((new Number(event.itemRenderer.data['quantity']) > 0 && !isNaN(event.itemRenderer.data['quantity'])) )
					{
						data.total = new Number(newVal) * new Number(data.quantity);
					}
				}else if(event.dataField=='quantity' && new Number(newVal) > 0 && !isNaN(new Number(newVal)))
				{
					if((new Number(event.itemRenderer.data['price']) > 0 && !isNaN(event.itemRenderer.data['price'])) )
					{
						data.total = new Number(newVal) * new Number(data.price);
					}
				}
				
				
			}

Add New Row Function

Next we need a function,orderGrid_doubleClickHandler(event:MouseEvent) , to add a new row when the user double clicks on the DataGrid.

protected function orderGrid_doubleClickHandler(event:MouseEvent):void
			{
				/**
				 * Add a new empty on double-click
				 * */
				orderArr.addItem({title:'',price:'',quantity:'',total:''});
			}

That is it. Here is a sample output, screenshot, of the application:

Hope this has been helpful. As I said at the beginning, accessing and updating a cell in a DataGrid using the underlining dataProvider and using e4x syntax to access to appropriate field.

Comments

    0 of 8192 characters used
    Post Comment

    No comments yet.

    working

    This website uses cookies

    As a user in the EEA, your approval is needed on a few things. To provide a better website experience, hubpages.com uses cookies (and other similar technologies) and may collect, process, and share personal data. Please choose which areas of our service you consent to our doing so.

    For more information on managing or withdrawing consents and how we handle data, visit our Privacy Policy at: https://hubpages.com/privacy-policy#gdpr

    Show Details
    Necessary
    HubPages Device IDThis is used to identify particular browsers or devices when the access the service, and is used for security reasons.
    LoginThis is necessary to sign in to the HubPages Service.
    Google RecaptchaThis is used to prevent bots and spam. (Privacy Policy)
    AkismetThis is used to detect comment spam. (Privacy Policy)
    HubPages Google AnalyticsThis is used to provide data on traffic to our website, all personally identifyable data is anonymized. (Privacy Policy)
    HubPages Traffic PixelThis is used to collect data on traffic to articles and other pages on our site. Unless you are signed in to a HubPages account, all personally identifiable information is anonymized.
    Amazon Web ServicesThis is a cloud services platform that we used to host our service. (Privacy Policy)
    CloudflareThis is a cloud CDN service that we use to efficiently deliver files required for our service to operate such as javascript, cascading style sheets, images, and videos. (Privacy Policy)
    Google Hosted LibrariesJavascript software libraries such as jQuery are loaded at endpoints on the googleapis.com or gstatic.com domains, for performance and efficiency reasons. (Privacy Policy)
    Features
    Google Custom SearchThis is feature allows you to search the site. (Privacy Policy)
    Google MapsSome articles have Google Maps embedded in them. (Privacy Policy)
    Google ChartsThis is used to display charts and graphs on articles and the author center. (Privacy Policy)
    Google AdSense Host APIThis service allows you to sign up for or associate a Google AdSense account with HubPages, so that you can earn money from ads on your articles. No data is shared unless you engage with this feature. (Privacy Policy)
    Google YouTubeSome articles have YouTube videos embedded in them. (Privacy Policy)
    VimeoSome articles have Vimeo videos embedded in them. (Privacy Policy)
    PaypalThis is used for a registered author who enrolls in the HubPages Earnings program and requests to be paid via PayPal. No data is shared with Paypal unless you engage with this feature. (Privacy Policy)
    Facebook LoginYou can use this to streamline signing up for, or signing in to your Hubpages account. No data is shared with Facebook unless you engage with this feature. (Privacy Policy)
    MavenThis supports the Maven widget and search functionality. (Privacy Policy)
    Marketing
    Google AdSenseThis is an ad network. (Privacy Policy)
    Google DoubleClickGoogle provides ad serving technology and runs an ad network. (Privacy Policy)
    Index ExchangeThis is an ad network. (Privacy Policy)
    SovrnThis is an ad network. (Privacy Policy)
    Facebook AdsThis is an ad network. (Privacy Policy)
    Amazon Unified Ad MarketplaceThis is an ad network. (Privacy Policy)
    AppNexusThis is an ad network. (Privacy Policy)
    OpenxThis is an ad network. (Privacy Policy)
    Rubicon ProjectThis is an ad network. (Privacy Policy)
    TripleLiftThis is an ad network. (Privacy Policy)
    Say MediaWe partner with Say Media to deliver ad campaigns on our sites. (Privacy Policy)
    Remarketing PixelsWe may use remarketing pixels from advertising networks such as Google AdWords, Bing Ads, and Facebook in order to advertise the HubPages Service to people that have visited our sites.
    Conversion Tracking PixelsWe may use conversion tracking pixels from advertising networks such as Google AdWords, Bing Ads, and Facebook in order to identify when an advertisement has successfully resulted in the desired action, such as signing up for the HubPages Service or publishing an article on the HubPages Service.
    Statistics
    Author Google AnalyticsThis is used to provide traffic data and reports to the authors of articles on the HubPages Service. (Privacy Policy)
    ComscoreComScore is a media measurement and analytics company providing marketing data and analytics to enterprises, media and advertising agencies, and publishers. Non-consent will result in ComScore only processing obfuscated personal data. (Privacy Policy)
    Amazon Tracking PixelSome articles display amazon products as part of the Amazon Affiliate program, this pixel provides traffic statistics for those products (Privacy Policy)