Flex Datagrid Edit Cell on Row Click

With flex datagrids you sometimes find you have a datagrid with multiple columns but only one or two columns are editable.

Which column are editable are not immediately apparent to a user, they have to click on cells to find out what's editable or not editable.

You can add some sort of visual indication to show what cells are editable (see here) OR you can make clicking on a row edit a cell.

Here's how to detect clicking on a cell and set the editable column of the datagrid.

view plain print about
1<?xml version="1.0" encoding="utf-8"?>
2<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="init()" viewSourceURL="srcview/index.html">
3
    
4    <mx:DataGrid id="myDG" dataProvider="{customers}" rowCount="5" width="300" height="200" editable="true" itemClick="editCell(event)" >
5        <mx:columns>

6            <mx:DataGridColumn headerText="Name" width="100" dataField="name" editable="false" editorDataField="text" />
7            <mx:DataGridColumn headerText="Addresss" dataField="address" width="200" editable="true" />
8        </mx:columns>

9    </mx:DataGrid>

10    
11    <mx:Model id="custdata">
12        <customers>
13            <customer>
14                <name>Cust1</name>
15                <address>Address1</address>
16            </customer>
17            <customer>
18                <name>Cust2</name>
19                <address>Address2</address>
20            </customer>
21            <customer>
22                <name>Cust3</name>
23                <address>Address3</address>
24            </customer>        
25        </customers>
26    </mx:Model>

27
28    <mx:Script>

29        <![CDATA[
30            import mx.events.ListEvent;
31            import mx.collections.ArrayCollection;
32            
33            [Bindable] private var customers:ArrayCollection = new ArrayCollection();
34
35            private function init():void {
36                customers = new ArrayCollection(custdata.customer);
37            }
38            
39            public function editCell(event:ListEvent):void {
40                myDG.editedItemPosition = {columnIndex:1, rowIndex:event.rowIndex};
41            }
42        ]]>
43    </mx:Script>
44
45</mx:Application>

Code has been updated to work in Flex 3.

The only thing to be be careful of is that the itemClick event handler will be called not only if a cell in the datagrid is clicked on but also if the header of the datagrid is clicked on so you need to take one off the rowIndex when setting the edited item position.

Here what the code looks like when run (right click to view source and/or download):

Related Blog Entries

TweetBacks
Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
One thing to be careful of is when using this method is to handle column draging otherwise you can drag the columns about and then edit the wrong field (as the column index is hard coded).
# Posted By Justin Mclean | 7/1/07 10:03 AM
Hi. Nice tip, I was looking for this. Unfortunately, it's not working for me -- it always activates the first editor.

I've got two data grids in my app, with drag and drop between them. The destination list is the one I need to do this to. One column uses a custom item editor, a numeric stepper. Problem is, I drag one item, click it, nothing. Drag a second item over, click it -- the FIRST row's stepper highlights. Same happens for each, only the first row highlight no matr what row is clicked on. Thoughts?
# Posted By Steve | 7/15/07 11:08 AM
Hi Steve,

Email me your code and I'll take a quick look at it, sounds like you're not setting the row number.

Justin
# Posted By Justin Mclean | 7/16/07 5:36 PM
Thanks this is a great tip on editing datagrid cells.
The item renderer from a component doesn't seem to work for me.
I don't know if it's a bug or what.

But how about if I got numeric cell to edit and I want to format them?
# Posted By Lou | 7/27/07 1:14 PM
The simple way is to use a standard text input control but restrict what the user types by using setting the restrict attribute to be &quot;0-9&quot;.

Email me you code and I'll take a look at why the item renderer isn't working.
# Posted By Justin Mclean | 7/27/07 1:39 PM
Thanks Justin
That was exactly what i was looking for!
# Posted By Sinan | 11/17/07 12:09 AM
Great example Justin, thanks! I used your example as a stepping stone for something I'm trying to achieve. Based on a boolean in the selected row of a DataGrid I'd like to disable the editable property of a field. I thought itemClick might help me get around that but its not.

Do you know if there is a way to set an editable property on a specific cell? I still want the entire column to be editable but with some logic I need to disable a cell being editable depending on the value of a boolean in that selected row (selectedItem). Is this possible? Was having trouble with this and this post has gotten me the closest to figuring it out.
# Posted By Javier Julio | 12/20/07 8:59 AM
Yes it should be possible.

The simple way would be to enable/disable the text field based on the boolean ie the user can't edit the field event though it shows up as a text input.

I'll look into not having it text input coming up. My first try would be to make a custom renderer with a viewstack with a text field on the first view and a text field on the second. Then use the editable property to change the selectedIndex to display the non editable version or non editable version of the content.
# Posted By Justin Mclean | 12/20/07 9:20 AM
I am trying to use this idea and it is working great, except then I have a scrolling datagrid. When I select a row and the datagrid is not scrolled all the way to the bottom the whole datagrid jumps. I am using Flex 3. Has anyone else had this problem?
# Posted By Randy | 5/16/08 2:09 AM
This is a great plugin. Just FYI, in Flex3, the header row is treated differently, so you can remove the line:
if (event.rowIndex &gt; 0) {...}
and change the editedItemPosition to
rowIndex:event.rowIndex

Thanks!
# Posted By Chuck G | 6/18/08 12:38 AM
@Randy

I am having the same problem as you. If the datagrid is editable and scrollable, when you click on a cell with the mouse and the vertical scroll bar is not all the way down (possibly not all the way up as well) the rows jump around. You end up landing on the physical row number you intended, but since the scroll automatically moved, the data in that row is not the data you intended to click on.

I have tried using the AdvancedDataGrid to see if it might be fixed in that component. I have looked through all the properties of the DataGrid to see if there is something that could enable me to fix this behavior.

If anyone knows of a solution to this problem, I would love to hear it!

Thanks,
Lisa
# Posted By Lisa | 11/22/08 5:59 AM
Great tip. Thanks for making it public. Solved my problem exactly :-)
# Posted By Tech Per | 1/12/09 11:58 PM
@Randy and @Lisa The issue is probably a Flex 2 vs Flex 3 issue. I changed the code to work with Flex 3. Thanks @Chuck for pointing it out.
# Posted By Justin Mclean | 5/18/09 5:47 PM
Nice tip! Was able to use this in one of my projects :)!
# Posted By Roelof | 10/8/09 11:40 PM
Thanks glad I could help.
# Posted By Justin Mclean | 10/9/09 3:28 AM
To solve sorting issue, try this.
- add:
import mx.core.mx_internal;
use namespace mx_internal;

Add id to:
&lt;mx:DataGridColumn id=&quot;address&quot; headerText=&quot;Addresss&quot; dataField=&quot;address&quot; width=&quot;200&quot; editable=&quot;true&quot; /&gt;

Change editCell function to use address.colNum instead of index:
public function editCell(event:ListEvent):void {
myDG.editedItemPosition = {columnIndex:address.colNum, rowIndex:event.rowIndex};
}
# Posted By EnTomBet | 11/21/09 11:47 AM