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.

{ 32 comments… read them below or add one }
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
Hi,
I have a datagrid which is bound to an arrayCollection, where datagrid has 4 columns out of which i am bounding three fields.When the user clicks the row , i have to populate the row’s first column with an image control.but the image control that i am adding id added to the panel not to the datagrid
Thanks a lot. example in this link are quite helpful.
Hi,
Thanks for the great examples.
Is there a way to modifying the array collection to have an additional colection item element (column)
I’m trying to work out a simple problem – which is to have a grid (editable) I want to track changes made to the grid by a user while editing
My thought was to a item element to represent the state (new, dirty, delete …)
Then I’d have a submit method which would loop through the changes, post each record to the server (my server side code handles a single record vo not a collection)
Common interaction problem, some users prefer entering data in grid, vs a single form.
Any Thoughts would be appreciated,
Dan
hye..
i got this code with me:
how could i make some of the columns invisible??for example i want to make column b and c invisible.can it be done??
Hey, I have been looking at the example that you provided for adding dynamic columns to a datagrid that is coming back off an httpService.
I have a similar issue that I was hoping someone can help with. I currently am getting xml from php (which works fine) but the xml returned is multidimensional and I need to dynamically create a datagrid to handle the xml returned. The structure being returned is as follows:
<section>
<user> (can be mulitple users)
<firstname>
<lastname>
<document> (will be mutiple)
<submissiondate>
</document>
</user>
</section>
I am trying to get the data returned into a datagrid to display the section,firstname,lastname,and document as the column headers.
Thanks!
Hello ,
Could you tell me.. that getting a label from datagrid..
i’m breifly explain…
i had a two datagrid
first one is draging the image and put into datagrid by [img.name) to imgholder arraycollection
second one i have a check a arraycollection of same field of names in array..
first one has randomly pick the image and send it the datagrid.. like [one,three,two..)
i want to compare the data from the arraycollection to imgholder …..
if rowcol value of label is equal to the imgholder… if its same mean the list the label is equal…. else its unequal array…..
here, i can’t make to compare the two datagrid….
could give a code or explain to get….
my code…
Thanks & Regrads
BHUVAN
Hi,
I am novice in programation and flexo solutions, so I want to hide and unhide a column depending on some dynamic variable.
for example if the user select a check, it automatically show one specific column and if the user uncheck, that column is hide.
thanks
GAP
@Anonymous,
You can set the
visibleproperty on each DataGridColumn object, as seen in the following example:Peter
Hi,
i need to dynamically remove columns from the table.. how can this be done?
@Dinesh Kumar D,
The DataGrid control’s
columnsis just an Array, so you can use array methods to remove columns. For example, the following code removes the first column (using thesplice()method) each time you click the button:Also, in my previous comment I showed how you can toggle a DataGridColumn’s visibility by setting the Boolean
visibleproperty.Peter
After i have added or removed the columns from the datagrid, the contents in the datagrid seems to disappear. I have tried assigning the Arraycollection to the dataprovider property of datagrid.. But still i dont see any contents.. could you tell me why?
Peter–thanks for this. Not the post itself, but your generosity in the comments. I have found the documentation and samples from Adobe not very well articulated through code samples. The reliance on MXML is just so over the top; MXML is great except when you need flexibility. You should be able to program everything (and you can), but the examples are just not that great.
The more emphasis you put on AS3 examples the better. MXML is handy, but for flexibility, AS3 is much more useful and powerful.
peter–sorry if this is a stupid question…
but why isn’t there an explicit method for adding rows to the datagrid? something like dg.AddRow(myObject.name, myObject.job….)
the flex datagrid is different from the flash datagrid…
http://www.adobe.com/devnet/flash/quickstart/datagrid_pt1/
@charlie crystle,
In Flex you add data to the data provider (ArrayCollection, etc), not to the control itself.
Peter