11
May
08

Creating an editable DataGrid control in Flex

The following example shows how you can create an editable Flex DataGrid control by setting the editable property on the DataGrid and DataGridColumn objects.

Full code after the jump.

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2008/05/11/creating-an-editable-datagrid-control-in-flex/ -->
<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 label="Student A" score="85" />
                <mx:Object label="Student B" score="48" />
                <mx:Object label="Student C" score="71" />
                <mx:Object label="Student D" score="88" />
                <mx:Object label="Student E" score="24" />
                <mx:Object label="Student F" score="64" />
                <mx:Object label="Student G" score="76" />
                <mx:Object label="Student H" score="76" />
                <mx:Object label="Student I" score="93" />
                <mx:Object label="Student J" score="88" />
                <mx:Object label="Student K" score="48" />
                <mx:Object label="Student L" score="76" />
            </mx:Array>
        </mx:source>
    </mx:ArrayCollection>

    <mx:DataGrid id="dataGrid"
            dataProvider="{arrColl}"
            editable="true"
            rowCount="8">
        <mx:columns>
            <mx:DataGridColumn dataField="label"
                    editable="false" />
            <mx:DataGridColumn dataField="score"
                    editable="true" />
        </mx:columns>
    </mx:DataGrid>

</mx:Application>

View source is enabled in the following example.

When working with editable DataGrid controls, there are three events which can be useful: itemEditBeginning, itemEditBegin, and itemEditEnd.

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2008/05/11/creating-an-editable-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.events.DataGridEvent;

            private function addEvent(evt:DataGridEvent):void {
                eventsArrColl.addItem(evt);
            }

            private function clearEvents():void {
                eventsArrColl = new ArrayCollection();
            }
        ]]>
    </mx:Script>

    <mx:ArrayCollection id="arrColl">
        <mx:source>
            <mx:Array>
                <mx:Object label="Student A" score="85" />
                <mx:Object label="Student B" score="48" />
                <mx:Object label="Student C" score="71" />
                <mx:Object label="Student D" score="88" />
                <mx:Object label="Student E" score="24" />
                <mx:Object label="Student F" score="64" />
                <mx:Object label="Student G" score="76" />
                <mx:Object label="Student H" score="76" />
                <mx:Object label="Student I" score="93" />
                <mx:Object label="Student J" score="88" />
                <mx:Object label="Student K" score="48" />
                <mx:Object label="Student L" score="76" />
            </mx:Array>
        </mx:source>
    </mx:ArrayCollection>

    <mx:ArrayCollection id="eventsArrColl" />

    <mx:ApplicationControlBar dock="true">
        <mx:Button label="Clear DataGrid" click="clearEvents();" />
    </mx:ApplicationControlBar>

    <mx:DataGrid id="dataGrid"
            dataProvider="{arrColl}"
            editable="true"
            rowCount="8"
            itemEditBegin="addEvent(event);"
            itemEditBeginning="addEvent(event);"
            itemEditEnd="addEvent(event);"
            itemFocusIn="//addEvent(event);"
            itemFocusOut="//addEvent(event);">
        <mx:columns>
            <mx:DataGridColumn dataField="label"
                    editable="false" />
            <mx:DataGridColumn dataField="score"
                    editable="true" />
        </mx:columns>
    </mx:DataGrid>

    <mx:DataGrid id="eventsDataGrid"
            dataProvider="{eventsArrColl}"
            itemRenderer="mx.controls.Label"
            verticalScrollPolicy="on"
            rowCount="9"
            width="100%">
        <mx:columns>
            <mx:DataGridColumn dataField="columnIndex" />
            <mx:DataGridColumn dataField="dataField" />
            <mx:DataGridColumn dataField="itemRenderer" />
            <mx:DataGridColumn dataField="reason" />
            <mx:DataGridColumn dataField="rowIndex" />
            <mx:DataGridColumn dataField="type" />
        </mx:columns>
    </mx:DataGrid>

</mx:Application>

View source is enabled in the following example.


26 Responses to “Creating an editable DataGrid control in Flex”


  1. 1 Prashanth Samanth May 14th, 2008 at 3:34 am

    Hello, I am UI Designer and new to Flex

    according to our new project,
    we have Combo box which has Any and Specific,and default is Any. and if the User Selects the Specific, we need to Show a “Text Input”, so that User can specify a value to search.

    Can you please let me known how to do that By Action Script

    Thank a lot in Advance
    PSamanth

  2. 2 peterd May 14th, 2008 at 8:23 am

    Prashanth Samanth,

    Does this work for you?

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
            layout="vertical">
    
        <mx:Form width="350">
            <mx:FormItem label="User:">
                <mx:ComboBox id="comboBox">
                    <mx:dataProvider>
                        <mx:Array>
                            <mx:String>Any</mx:String>
                            <mx:String>Specific</mx:String>
                        </mx:Array>
                    </mx:dataProvider>
                </mx:ComboBox>
                <mx:TextInput id="textInput"
                        visible="{comboBox.selectedItem == 'Specific'}"
                        includeInLayout="{textInput.visible}" />
            </mx:FormItem>
            <mx:FormItem label="Date range:" direction="horizontal">
                <mx:DateField id="startDate" />
                <mx:DateField id="endDate" />
            </mx:FormItem>
        </mx:Form>
    
    </mx:Application>
    

    Peter

  3. 3 Brent May 21st, 2008 at 9:24 am

    Hi Peter.

    First, terrific site. It is my #1 goto site for working examples of real-world Flex scenarios. Thank you for keeping this site updated. It’s is extremely useful to me.

    Question: How would I make a datagrid editable, but also add the “restrict” attribute to that field. I see how to do it to text fields, but how do I add it for a datagrid? Like in your example above, restrict the field so that the score had to be numeric? I can see adding an editEnd event that looks to see if it’s a number and then not allowing it. Is that the best way? I was hoping I could just add the restrict tag somewhere easily.

    thanks !!!

  4. 4 Brent May 21st, 2008 at 1:52 pm

    OK I found the answer. Only the text input component will accept the restrict tag. But you can add an item renderer and do it like this.

    http://blog.classsoftware.com/index.cfm/2007/6/11/Flex-Datagrid-Editing-Cells

    I like this because it solves 2 problems:

    1. Telling the user which fields are editable.
    2. Ability to restrict the input chars without more functions.

    I made some slight variations on this in order to center the field values.

  5. 5 Prashanth Samanth May 26th, 2008 at 11:56 pm

    Hey peterd,

    Thanks a lot Dude, that works, I had implemented same code for Multiple Combo Boxes and it’s very easy to use

    Thank a lot again

  6. 6 Prashanth Samanth May 27th, 2008 at 12:16 am

    Hello

    How to create a Browse Button in Flex, Like we give “type=”file” in HTML, so that we can browse the file from System and upload

    This is the HTML Tag: , which I want to include in Flex

  7. 7 peterd May 27th, 2008 at 12:21 am

    Prashanth Samanth,

    File uploads and file downloads are handled by the FileReference class. For a few examples, see
    http://blog.flexexamples.com/tag/filereference/.

    Peter

  8. 8 Prashanth Samanth May 27th, 2008 at 3:58 am

    Peterd,

    I even want a Text input before the Browse, so that the User can directly type the path he want to upload…

    PSamanth

  9. 9 Prashanth Samanth May 27th, 2008 at 4:18 am

    Peted,

    File uploads and Downloads I got this and implemented, please have look at this
    http://livedocs.adobe.com/flex/3/html/help.html?content=17_Networking_and_communications_9.html,

    thought it will help you too

    PSamanth

  10. 10 Brent May 28th, 2008 at 1:41 pm

    Yeah yeah check this out. Dig this, Johnson !!

    Here’s your dataGrid code:

    <mx:DataGridColumn headerText="Quantity" dataField="Quantity" textAlign="center" itemRenderer="path.to.your.view.EditableCellRenderer"
    itemEditor="path.to.your.view.EditableCellEditor" />
    

    And here’s your editable cell editor:

    <?xml version="1.0" encoding="utf-8"?>
    <mx:TextInput xmlns:mx="http://www.adobe.com/2006/mxml"
    	width="100%" height="100%"
    	restrict="0-9">
    
    	<mx:Script>
    		<![CDATA[
    			import mx.controls.DataGrid;
    
    			/**
    			 * Override data setter to set cell text according to the dataField
    			 */
    			public override function set data(value:Object):void
    			{
    				var dg:DataGrid = owner as DataGrid;
    				text = value[dg.columns[dg.editedItemPosition.columnIndex].dataField];
    			}
    		]]>
    	</mx:Script>
    </mx:TextInput>
    

    This is even better since you don’t need to know which order your dataGrid column is and cuts your code by like 90%.

  11. 11 Brent May 28th, 2008 at 4:25 pm

    Opps forgot the renderer above.

    <?xml version="1.0" encoding="utf-8"?>
    <mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml"
    implements="mx.controls.listClasses.IDropInListItemRenderer"
    horizontalAlign="center"
    verticalScrollPolicy="off" horizontalScrollPolicy="off"
    preinitialize="init()">
    <mx:Label id="CellText" width="93%" paddingLeft="20" />
    <mx:Label textAlign="right" text="+" toolTip="Edit" width="12" styleName="editPlusSign" />
    <mx:Script>
    <![CDATA[
    import mx.controls.dataGridClasses.DataGridListData;
    import mx.controls.listClasses.BaseListData;
    import mx.controls.DataGrid;
    
    private var iListData:BaseListData;
    
    /**
     * Implement listData getter from IDropInListItemRenderer
     */
    public function get listData():BaseListData
    {
      return iListData;
    }
    
    /**
     * Implement listData setter from IDropInListItemRenderer
     */
    public function set listData( value:BaseListData ):void
    {
        iListData = value;
    } 
    
    /**
    * Add event listener for when data changes
    */
    private function init():void
    {
        addEventListener("dataChange", handleDataChanged);
    }    
    
    /**
     * When data changes update the cell text based on the dataField
     */
    private function handleDataChanged(event:Event):void
    {
        // Cast listData to DataGridListData.
        var myListData:DataGridListData = DataGridListData(listData);
        CellText.text = data[myListData.dataField];
    
    }
    ]]>
    </mx:Script>
    </mx:HBox>
    
  12. 12 Alex C Aug 26th, 2008 at 7:51 am

    Hi. Is there an example of how to do paging on a Flex datagrid? This way you only show a certain number of records per page and have Next/Previous buttons to let the user view more pages of records or jump to a specific page.

  13. 13 bhargavi Aug 29th, 2008 at 7:05 am

    hi i want one thing is that after editing the cell value of data grid , i want that changed cell value.please anybody can help me.

  14. 14 SD.Plox Sep 3rd, 2008 at 9:03 am

    Hi Guys,

    our team is trying to perform text selection on datagrid cells, but we haven’t found a property, (selectable isn’t) an method, or a flex facility for this task…

    is a renderer necessary for this case?

    best regards,

    SD.Plox

  15. 15 peterd Sep 3rd, 2008 at 10:41 am

    SD.Plox,

    There may be easier/better ways, but you can definitely create a custom item renderer and set the selectable property to true, as seen in the following example:

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    
        <mx:Array id="arr">
            <mx:Object c1="One.1" c2="Two.1" c3="Three.1" />
            <mx:Object c1="One.2" c2="Two.2" c3="Three.2" />
            <mx:Object c1="One.3" c2="Two.3" c3="Three.3" />
            <mx:Object c1="One.4" c2="Two.4" c3="Three.4" />
            <mx:Object c1="One.5" c2="Two.5" c3="Three.5" />
            <mx:Object c1="One.6" c2="Two.6" c3="Three.6" />
            <mx:Object c1="One.7" c2="Two.7" c3="Three.7" />
            <mx:Object c1="One.8" c2="Two.8" c3="Three.8" />
        </mx:Array>
    
        <mx:DataGrid id="dataGrid"
                dataProvider="{arr}"
                editable="false">
            <mx:itemRenderer>
                <mx:Component>
                    <mx:Label selectable="true" />
                </mx:Component>
            </mx:itemRenderer>
        </mx:DataGrid>
    
    </mx:Application>
    

    Or, you could also just create a custom item renderer based on the default DataGridItemRenderer and set the selectable property there instead:

    <mx:DataGrid id="dataGrid"
            dataProvider="{arr}"
            editable="false">
        <mx:itemRenderer>
            <mx:Component>
                <mx:DataGridItemRenderer selectable="true" />
            </mx:Component>
        </mx:itemRenderer>
    </mx:DataGrid>
    

    Peter

  16. 16 peterd Sep 3rd, 2008 at 10:56 am

    Another option may be an editable DataGrid with a selectable (and non-editable) item editor:

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    
        <mx:Array id="arr">
            <mx:Object c1="One.1" c2="Two.1" c3="Three.1" />
            <mx:Object c1="One.2" c2="Two.2" c3="Three.2" />
            <mx:Object c1="One.3" c2="Two.3" c3="Three.3" />
            <mx:Object c1="One.4" c2="Two.4" c3="Three.4" />
            <mx:Object c1="One.5" c2="Two.5" c3="Three.5" />
            <mx:Object c1="One.6" c2="Two.6" c3="Three.6" />
            <mx:Object c1="One.7" c2="Two.7" c3="Three.7" />
            <mx:Object c1="One.8" c2="Two.8" c3="Three.8" />
        </mx:Array>
    
        <mx:Component id="dgIR">
            <mx:DataGridItemRenderer selectable="true" />
        </mx:Component>
    
        <mx:DataGrid id="dataGrid"
                dataProvider="{arr}"
                editable="true">
            <mx:columns>
                <mx:DataGridColumn dataField="c1" editable="false" />
                <mx:DataGridColumn dataField="c2" itemEditor="{dgIR}" />
                <mx:DataGridColumn dataField="c3" itemEditor="{dgIR}" />
            </mx:columns>
        </mx:DataGrid>
    
    </mx:Application>
    

    Peter

    Note: Only the last 2 columns in the DataGrid control are editable. Also, you have to click the cell once to bring up the item editor. Another option could be using a TextInput/TextArea control and setting its editable property to false.

  17. 17 Stuart Ward Sep 4th, 2008 at 11:44 am

    Peter,
    Is is possible to extend this a bit and select text across two or more cells in a given row - still using the typical click and drag highlight method that is used in your examples?

    I am aware that the Advanced DataGrid has a multiple select feature, but it relies on conrol-clicking each cell and selected the entire contents of the cell.

    Thanks for your help,
    Stuart

  18. 18 Sireesha Dec 2nd, 2008 at 5:01 am

    Hi,

    Could you please elaborate more on Custom DataGrid in MXML code?

    As per the Above Code DataGrid Columns and values are defined statically but when Webservice is used and returning data in DataGrid what to be written in the code to get the values dynamically and datagrid columns dynamically…i.e., in the array how to get the values dynamically ?

    Coould you please guide me how to do this?

    Regards
    Sireesha.

  19. 19 Ujjwal B Soni Jan 18th, 2009 at 8:49 am

    Hi,

    The datagrid posted here is not editable. Can you throw some light on creating an editable datagrid connected with database.

    Cheers!!!

    Ujjwal B Soni

  20. 20 Peter deHaan Jan 18th, 2009 at 7:16 pm

    Ujjwal B Soni,

    Only the second column (score) in the example’s data grid is editable.

    Peter

  21. 21 Scarlet sail Jan 18th, 2009 at 10:31 pm

    Hi Peter,

    If I use xml not ArrayCollection, how can I edit datagrid and save the change back to the xml source?

    Many thanks.

  22. 22 wpageiii Feb 17th, 2009 at 12:36 pm

    Not sure if this is possible…You seen like the guy to ask…

    I would like to build a datagrid dynamically with amounts cnts etc…like this..

    oColumnDef = new DataGridColumn();
    oColumnDef.headerText = "Amount";
    oColumnDef.dataField = "S"+Storesdp.getItemAt(i).data+"_all_amt";
    oColumnDef.width = 60;
    oColumnDef.sortable = true;
    oColumnDef.visible = true;
    oColumnDef.editable = false;
    oColumnDef.wordWrap = false;
    oColumnDef.labelFunction = amtLabelFunction;
    oColumnDef.setStyle("textAlign","right");
    colArray.push(oColumnDef);
    

    Then have one column as a combobox…like this…

    oColumnDef = new DataGridColumn();
    oColumnDef.headerText = "Age";
    oColumnDef.width = 50;
    oColumnDef.sortable = true;
    oColumnDef.visible = true;
    oColumnDef.editable = true;
    oColumnDef.wordWrap = false;
    oColumnDef.itemRenderer = new ClassFactory(BarometerView.comboboxrenderer);
    oColumnDef.rendererIsEditor= true;
    colArray.push(oColumnDef);
    

    This works as expected…combo renderer I would like to change the dg values for that row based on the users selection (users can select All, 30, 60, 90, 120, 150, 180)
    so in the changeHandler of the combo I have some code but cannot seem to figure out the correct syntax to make it work…I have attempted using the selectedIndex of datagrid…

    I am not sure my method is correct as the dataprovider for the dg contains separate fields for all, 30, 60, 90 etc….

    Perhaps I should use a repeater instead of datagrid so I would have more control and an my simple structure (renderers are a pain)…Thoughts? I am aware that this post may be difficult to interpret but I did not want to post to much code…as I do not assume others want to do all the work for me…I am just looking for a nudge in the right direction…

    I was hoping to use a datagrid rather that repeater for performance reasons…Let mw know if you need other information or if anyone is aware of other resources that would help

  23. 23 Nayk Feb 19th, 2009 at 3:37 am

    Hi, does anyone know how to adapt Brent’s CellEditable for columns using labelFunction (not dataField) ?
    thanks

  24. 24 Bartimus Mar 10th, 2009 at 2:13 pm

    Anyone else have issues where the scroll bar will fire off itemEdit events and it passes the last item you edited? So for example you’d click on the number in the example above and then when you’d scroll it would open the editor for the same element. For the life of me I can’t figure out why its doing that.

  25. 25 Bartimus Mar 10th, 2009 at 2:17 pm

    Okay sorry to double post, I just figure out what is making the scroll bar fire the events, I think its a flex bug. If you have selectable=false in the datagrid then i think it confuses some of the events and the scrollbars with execute them.

  26. 26 abhishek Apr 22nd, 2009 at 6:52 am

    hello frnds,
    could we make rounded corners of datagrid?
    abhishekchess1@gmail.com
    thx in advanced,
    :)

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

  • Powered by Redoable 1.2
  • Cornify
  • Feeds burnt by Feedburner
  • Feed