04
Mar
08

Dynamically adding new columns to a DataGrid control in Flex

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.

View MXML

<?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.


18 Responses to “Dynamically adding new columns to a DataGrid control in Flex”


  1. 1 Mohammad Ismail Mar 6th, 2008 at 11:52 pm

    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.

  2. 2 Craig Mar 19th, 2008 at 8:23 am

    thanks man. exactly what I was looking for.

  3. 3 lesieux Mar 31st, 2008 at 2:45 pm

    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.

  4. 4 peterd Mar 31st, 2008 at 3:29 pm

    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 columns property 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

  5. 5 vincent lesieux Apr 1st, 2008 at 5:02 am

    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.

  6. 6 lesieux Apr 1st, 2008 at 2:34 pm

    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.

  7. 7 peterd Apr 1st, 2008 at 5:10 pm

    lesieux,

    Can you use the <mx:HTTPService /> tag to call the PHP?

    Peter

  8. 8 Joe Apr 8th, 2008 at 7:49 am

    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??

  9. 9 Greg Apr 21st, 2008 at 11:55 pm

    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

  10. 10 peterd Apr 22nd, 2008 at 12:06 am

    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

  11. 11 Greg Apr 22nd, 2008 at 1:16 am

    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.

  12. 12 PJW Jun 16th, 2008 at 12:59 pm

    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

  13. 13 GT Aug 29th, 2008 at 5:50 am

    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

  14. 14 Kirk Sep 30th, 2008 at 10:55 pm

    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?

  15. 15 peterd Oct 1st, 2008 at 12:18 am

    Kirk,

    I’d probably just try and toggle the visible property 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

  16. 16 Kirk Oct 1st, 2008 at 10:57 pm

    Thank you for the quick response. That is a much more elegant solution.

  17. 17 billp Nov 4th, 2008 at 3:40 pm

    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?

  18. 18 billp Nov 4th, 2008 at 4:14 pm

    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

Leave a Reply

This blog is terrible at eating HTML tags. If you plan on posting code/XML, please escape your "<" characters as "&lt;" and your ">" characters as "&gt;".




Badge Farm

  • Firefox 2
  • Powered by Redoable 1.2
  • Feeds burnt by Feedburner
  • Feed