[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Set value of another cell in same row from DataGrid

Posted on 2009-12-18
5
Medium Priority
?
774 Views
Last Modified: 2012-05-08
Hi,

I'm experienced with ActionScript, but very new to Flex.

I've got a DataGrid with several columns, one of which contains ComboBoxes.  Each DataGrid column uses a custom itemRenderer, which is defined in an ActionScript class (not MXML).

On change of any of the ComboBoxes, I need to update a couple other cells in the same row of the DataGrid, based on the selectedItem and the values of still other cells in the same row.

I think DataGridListData(listItem) gives me the DataGrid object, but how to I access the other cells in the same row as the ComboBox?

TYIA
0
Comment
Question by:moagrius
  • 4
5 Comments
 
LVL 10

Accepted Solution

by:
mplord earned 2000 total points
ID: 26085184
Here's a quick tip on getting (from an ItemRenderer) the current grid, current grid column, and current column datafield property name:

var grid:DataGrid = DataGrid(DataGridListData(listData).owner);
var dgc:DGColumnBase = (grid.columns[DataGridListData(listData).columnIndex] as DGColumnBase);
var dgcfield:String = dgc.dataField;

However, to get/set other fields in the current selected row from the current itemRenderer, you don't need any of that.
'data' is you current row object. So data['propertyname'] is your access to the underlying row data.
Just work with 'data' (cast if necessary, e.g. (data as MyObject).field = ... )

So, e.g. you have two columns with combobox itemrenderers and within the itemrenderer you don't know which field you're editing, use dgcfield to figure it out.
Then use data['field'] to alter other contents.

After changing any data in other fields, you might well need to call 'this.invalidateDisplayList();' to ensure the grid is redrawn to show changes in other cells.

Final example:
In some cases I add in the constructor of my itemRenderer, an event listener for data change:

          public function MyItemRenderer()
          {
                ...
                this.addEventListener(FlexEvent.DATA_CHANGE, onDataChange, false, 0, true);
          }

then have:

        private function onDataChange(event:Event):void
          {
            var grid:DataGrid = DataGrid(DataGridListData(listData).owner);
            var dgc:DGColumnBase = (grid.columns[DataGridListData(listData).columnIndex] as DGColumnBase);
            var dgcfield:String = dgc.dataField;

            ... do stuff based on above conditions ...
            ... e.g. data['myOtherField'] = data[dgcfield]*100;

                this.invalidateDisplayList();
          }
0
 
LVL 19

Author Comment

by:moagrius
ID: 26086263
hey mplord,

thanks for replying - i was hoping you'd see this one.

your answer makes perfect sense, and is exactly what i was trying to do initially, but without success.  i'll post the relevant portions of the code and maybe you can tell me what i'm doing wrong.  i'm using the change event rather than the dataChange but afaik that shouldn't matter.

uomData is xml that just has two nodes per element: LABEL (hourly, daily, contract, other, etc) and RATE (the amount amount appropriate to the Unit) - you'll notice the line:

data.unitRate = selectedItem.RATE;

which is where i expected the last column of the datagrid to update, but it does not.  selectedItem.RATE does however alert out appropriately (shows the correct amount for the unit of measure).

i appreciate your help.
<!-- the application MXML -->

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" initialize="uomData.send()">

<mx:Script>
	<![CDATA[
	
		import mx.collections.ArrayCollection;
		
		[Bindable]
		private var lineItems:ArrayCollection = new ArrayCollection();
		
		private function addRow():void{
			var row:Object = {
				deleteRow : null,
				dateRate : new Date(),
				uom : uomData.lastResult.node,
				unitRate : 0
			}
			lineItems.addItem(row);
		}
		private function init():void{
			for(var i:int=0;i<2;i++){
				addRow();
			}
		}
	]]>
</mx:Script>
<mx:HTTPService
  		resultFormat="e4x"
  		result="init()"
  		url="http://localhost/billing/read-sql-table.php?table=UOM"
  		id="uomData" />
  		
<mx:DataGrid 
	id="dg"
	dataProvider="{lineItems}">
  <mx:columns>
  	<mx:DataGridColumn width="30" itemRenderer="renderers.DeleteRow" dataField="deleteRow" headerText="Delete" />
  	<mx:DataGridColumn width="120" itemRenderer="renderers.DateRate" dataField="dateRate" headerText="Date" />
  	<mx:DataGridColumn width="120" itemRenderer="renderers.UOMBox" dataField="uom" headerText="UOM" />
  	<mx:DataGridColumn width="30" dataField="unitRate" headerText="Unit" />
  </mx:columns>
</mx:DataGrid>
        
</mx:Application>







// the item renderer for the combo box

package renderers {
	
	import flash.events.Event;
	import mx.controls.dataGridClasses.*;
	import mx.controls.ComboBox;
	import mx.controls.DataGrid;

	public class UOMBox extends ComboBox {		
		
		private function changeHandler(event:Event):void{
			data.unitRate = selectedItem.RATE;
			DataGrid(DataGridListData(listData).owner).invalidateList();
		}
		override public function set data(value:Object):void{
		 	dataProvider = value.uom;
		}
		public function UOMBox():void		{
			labelField = "LABEL";
			addEventListener("change", changeHandler, false, 0, true);
		}		
	}
}

Open in new window

0
 
LVL 19

Author Comment

by:moagrius
ID: 26087045
got it - i overrode the data setter, but neglected to assign it to assign it back to super

this line in the override fixed it

super.data = value;
0
 
LVL 19

Author Closing Comment

by:moagrius
ID: 31667763
Thank you - I think I'll have a bunch more questions as I'm just now finishing up the books and trying to put theory in action - seems like you "grok" Flex, and I could use the help
0
 
LVL 19

Author Comment

by:moagrius
ID: 26087286
I've got another related issue - and opened a new Question for it - here:  http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/Flex/Q_24991480.html
0

Featured Post

Reclaim your office - Try the MB 660 headset now!

High level of background noise often makes it difficult for employees to concentrate fully on their jobs – or to communicate clearly on calls. The MB 660 headset helps you create a disruption free workspace.  

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

First things first - Preparation We need all the part for this install and it's much nicer to have them all on hand when you need them so here's what's required. Download Eclipse 3.5 32 bit (I like the Classic flavour) from here. (http://www.e…
Microsoft Office Picture Manager was included in Office 2003, 2007, and 2010, but not in Office 2013. Users had hopes that it would be in Office 2016/Office 365, but it is not. Fortunately, the same zero-cost technique that works to install it with …
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…

834 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question