The following example shows how you can dynamically add new columns to a Flex DataGrid control by setting the columns property.
Full code after the jump.
<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2008/03/04/dynamically-adding-new-columns-to-a-datagrid-control-in-flex/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
verticalAlign="middle"
backgroundColor="white">
<mx:Script>
<![CDATA[
import mx.controls.dataGridClasses.DataGridColumn;
private function addDataGridColumn(dataField:String):void {
var dgc:DataGridColumn = new DataGridColumn(dataField);
var cols:Array = dataGrid.columns;
cols.push(dgc);
dataGrid.columns = cols;
}
private function init():void {
addDataGridColumn("col4");
}
]]>
</mx:Script>
<mx:ArrayCollection id="arrColl">
<mx:source>
<mx:Array>
<mx:Object col1="A.1" col2="A.2" col3="A.3" col4="A.4"/>
<mx:Object col1="B.1" col2="B.2" col3="B.3" col4="B.4"/>
<mx:Object col1="C.1" col2="C.2" col3="C.3" col4="C.4"/>
<mx:Object col1="D.1" col2="D.2" col3="D.3" col4="D.4"/>
<mx:Object col1="E.1" col2="E.2" col3="E.3" col4="E.4"/>
<mx:Object col1="F.1" col2="F.2" col3="F.3" col4="F.4"/>
</mx:Array>
</mx:source>
</mx:ArrayCollection>
<mx:ApplicationControlBar dock="true">
<mx:Button label="Add column" click="init();" />
</mx:ApplicationControlBar>
<mx:DataGrid id="dataGrid"
dataProvider="{arrColl}"
width="400"
rowCount="6">
<mx:columns>
<mx:DataGridColumn dataField="col1" />
<mx:DataGridColumn dataField="col2" />
<mx:DataGridColumn dataField="col3" />
</mx:columns>
</mx:DataGrid>
</mx:Application>
View source is enabled in the following example.




hi..
could u please tell me the best and easiest way of writing itemrenderers for a Flex application.becoz i am beginner of this technology i hav been using flex 2.0.1 for the last one year…i feel sometimes difficult to code them.
thanks man. exactly what I was looking for.
i need your help because i would like to make a dynamic datagrid, the number of column would depend on what is sent by the httpservice (after a request by sql), and can be sent first but though i tried to make it by creating a datagrid by actionscript, it doesn’t work, i don’t succeed to make the datagrid take it into account before being populated. Excuse my english cause i’m french, i hope you have understood my problem and that you can help me. Thank you.
lesieux,
Does this help?
<?xml version="1.0" encoding="utf-8"?> <!-- main.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" verticalAlign="middle" backgroundColor="white" creationComplete="init();"> <mx:Script> <![CDATA[ import mx.collections.XMLListCollection; import mx.controls.Alert; import mx.controls.DataGrid; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; private var dp:XMLListCollection; private var dataGrid:DataGrid; private function httpService_fault(evt:FaultEvent):void { Alert.show(evt.fault.faultString); } private function httpService_result(evt:ResultEvent):void { var res:XML = evt.result as XML; dp = new XMLListCollection(res.node); dataGrid = new DataGrid(); dataGrid.rowCount = 5; dataGrid.dataProvider = dp; addChild(dataGrid); } private function init():void { httpService.send(); } ]]> </mx:Script> <mx:HTTPService id="httpService" url="data2.xml" resultFormat="e4x" fault="httpService_fault(event);" result="httpService_result(event);" /> </mx:Application><?xml version="1.0" encoding="utf-8"?> <!-- data.xml --> <root> <node c1="ONe.1" c2="TWo.1" c3="THREe.1" c4="FOUr.1" /> <node c1="ONe.2" c2="TWo.2" c3="THREe.2" c4="FOUr.2" /> <node c1="ONe.3" c2="TWo.3" c3="THREe.3" c4="FOUr.3" /> <node c1="ONe.4" c2="TWo.4" c3="THREe.4" c4="FOUr.4" /> <node c1="ONe.5" c2="TWo.5" c3="THREe.5" c4="FOUr.5" /> <node c1="ONe.6" c2="TWo.6" c3="THREe.6" c4="FOUr.6" /> </root>Also, I should add, if you want to specify a column order, you can set the
columnsproperty Array, as shown in the following snippet:var c1:DataGridColumn = new DataGridColumn("@c1"); var c2:DataGridColumn = new DataGridColumn("@c2"); var c3:DataGridColumn = new DataGridColumn("@c3"); dataGrid = new DataGrid(); dataGrid.columns = [c3, c1, c2]; dataGrid.rowCount = 5; dataGrid.dataProvider = dp; addChild(dataGrid);Peter
Thank you for your quick answer, it’s very nice and professional, i’m going to study your code and will give you a response as soon as i can.
In order to use your code, I have made a php file to transform the result of a sql request in xml. Now, I don’t know how i can manage in flex to call the php to receive the data. Have you got an idea? Thank you.
lesieux,
Can you use the <mx:HTTPService /> tag to call the PHP?
Peter
Hey I am trying to embed a ProgressBar into data grid and I receive an error your article did the combo boxes (and it worked)
what is up with ProgressBar??
Awesome, definitely works. Two questions.
1st. can I dynamically label these using .columnCount?
2nd. can I make the new columns invisible on creation?
Appreciate any help.
-G
Greg,
Does this work for you?
private function addDataGridColumn(dataField:String):void { var dgc:DataGridColumn = new DataGridColumn(dataField); dgc.visible = false; dgc.headerText = "col " + (dataGrid.columns.length + 1); var cols:Array = dataGrid.columns; cols.push(dgc); dataGrid.columns = cols; }Peter
Peter, you rock!
Modified it a bit, needed it to set the datafield, not the headertext.
Here’s my code:
private function addDataGridColumn(dataField:String):void { var dgc:DataGridColumn = new DataGridColumn(dataField); dgc.visible = false; var cols:Array = peopleMainDB.columns; cols.push(dgc); peopleMainDB.columns = cols; trace("Number of columns:" + peopleMainDB.columns.length) } private function init():void { var x:String = "icon " + (peopleMainDB.columns.length + 1); addDataGridColumn(x); }Thanks again, wish I had you around for all of my flex problems.
Hi,
Several weeks ago I was wrestling with DataGrid renderers.
The above posts helped… as well as other sources I googled up. Without going into the specifics of my own solution (needed to be entirely ActionScript, i.e. no MXML) here are some posts I found useful (hopefully this blog doesn’t treat this like a spam post). Hopefully these help out others who face similar challenges.
http://philflash.inway.fr/flex/dgRendererSimple/dgRendererSimple.html
…a couple more (WordPress doesn’t like too many URLs in posts):
http://philflash.inway.fr/flex/dgRendererSimple/srcview/index.html
http://www.mail-archive.com/flexcoders@yahoogroups.com/msg85212.html
http://www.adobe.com/devnet/flash/articles/detecting_datagrid_edits.html
Yet some more:
http://blog.flexexamples.com/2008/03/04/dynamically-adding-new-columns-to-a-datagrid-control-in-flex/
http://www.actionscript.org/forums/showthread.php3?t=163781
http://www.returnundefined.com/2006/10/item-renderers-in-datagrids-a-primer-for-predictable-behavior
…and the last (Moderator: you might want to combine these posts, if you think your readers will find useful. Thanks.)
http://bugs.adobe.com/jira/browse/FLEXDOCS-142
http://blog.flexmonkeypatches.com/tag/itemrenderer/
http://www.nabble.com/item-renderers-in-a-datagrid-with-dynamically-created-columns-td16567760.html
http://blogs.adobe.com/aharui/2007/03/thinking_about_item_renderers_1.html
http://blogs.adobe.com/aharui/MultilineHTML.zip
Both the tutorial in toto, and the comment that helped Vincent Lesieux, were tremendously useful to me. I had decided that I would like to be able to change the entire contents of a DataGrid (from price-related data to valuation-related data) on the client side as a selection, as part of a Watchlist/Portfolio manager app. The number of columns would change as a result.
Thanks to this tute and others on this site, I can now offer a customised list of columns, fetch the data from mySQL, and populate the new colums… or replace the entire DataGrid in one fell swoop using pre-defined sets of columns.
I’ve been meaning for a month to write a thank-you for this, and for other insightful entries here: my only excuse for not having done so until now is that I have been absolutely drowning in tasks that had to be done in order to finish the apps.
Thanks muchly,
GT
I am using this example with a checkbox instead of a button.
How does the code change to delete the column when unchecked, instead of adding a duplicate column?
Kirk,
I’d probably just try and toggle the
visibleproperty on the DataGridColumn. Something like this:<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" verticalAlign="middle" backgroundColor="white"> <mx:ArrayCollection id="arrColl"> <mx:source> <mx:Array> <mx:Object col1="A.1" col2="A.2" col3="A.3" col4="A.4"/> <mx:Object col1="B.1" col2="B.2" col3="B.3" col4="B.4"/> <mx:Object col1="C.1" col2="C.2" col3="C.3" col4="C.4"/> <mx:Object col1="D.1" col2="D.2" col3="D.3" col4="D.4"/> <mx:Object col1="E.1" col2="E.2" col3="E.3" col4="E.4"/> <mx:Object col1="F.1" col2="F.2" col3="F.3" col4="F.4"/> </mx:Array> </mx:source> </mx:ArrayCollection> <mx:ApplicationControlBar dock="true"> <mx:CheckBox id="checkBox1" label="Toggle col1" selected="true" /> <mx:CheckBox id="checkBox2" label="Toggle col2" selected="true" /> <mx:CheckBox id="checkBox3" label="Toggle col3" selected="true" /> </mx:ApplicationControlBar> <mx:DataGrid id="dataGrid" dataProvider="{arrColl}" width="400" rowCount="5"> <mx:columns> <mx:DataGridColumn dataField="col1" visible="{checkBox1.selected}" /> <mx:DataGridColumn dataField="col2" visible="{checkBox2.selected}" /> <mx:DataGridColumn dataField="col3" visible="{checkBox3.selected}" /> </mx:columns> </mx:DataGrid> </mx:Application>Peter
Thank you for the quick response. That is a much more elegant solution.
The code for the checkbox works well but when I use send a new request out using httpservice call to PHP all the columns appear again….Even if none are selected on the checkboxes…Is there something I am missing?
Might have answered my own question…I am sure you have a better solution bur I found this and it worked for me…
http://blog.classsoftware.com/index.cfm/2007/6/17/Flex-Datagrid-Visibility-Bug