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.


17 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

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;".