DataGrid Double-Click To Edit

| 28 Comments

Several people have asked about changing the default editing behavior of a DataGrid so that starting an edit session requires a double-click instead of the default single-click.

Here's my approach:

Download Source
Run Demo

28 Comments

Seems to introduce a new bug...if you scroll with something being edited, the next attempts to edit a field selects the wrong field. (using 9,0,45,0 on Win)

---------------------------
Alex responds:

Thanks for catching that. I uploaded a fix for that.
I should also mention that this solution presumes that all renderers implement IDropInListItemRenderer.

Hey Alex,

I don't know why under my IE7 in Vista you last couple of blog posts with demos cannot be loaded. The SWF generate an invalid char javascript error of some sort.

I have to load it within Firefox to get it to work.

-Boub

I'm running Windows XP and use IE 7.0 but cannot view the swf files either. I too have to use Firefox.

---------------------
Alex responds:

Hmm, maybe I'll have to upload html wrappers as well.

I've implemented the same functionality, but in a different way. My class just simulates a single-click when a double-click occurs. That way it should still work even if the code for DataGrid is changed in the future.

public class DoubleClickDataGrid extends DataGrid {

public function DoubleClickDataGrid() {
super();
doubleClickEnabled = true;
}

override protected function mouseDoubleClickHandler(event:MouseEvent):void {
super.mouseDoubleClickHandler(event);

// simulate a click (just calling the mouseUpHandler wont work)
super.mouseDownHandler(event);
super.mouseUpHandler(event);
}

override protected function mouseUpHandler(event:MouseEvent):void {

// prevent edits on normal mouse-up
var saved:Boolean = editable;
editable = false;
super.mouseUpHandler(event);
editable = saved;
}

}

Hey,

Thanks so much for this, helped a lot!!!

p.s I used this on a Flex desktop app hooked up to a datagrid that is feed via xml

thanks,
abZ

(i think i may have this comment incorrectly on another post please disregard the other)

that is nice thing. How can I do it for tree control.
It does not have dataColumn.

Regards
Yasir

----------------------
Alex responds:

You should be able to replace that event with similar code from List.as like this:

var listEvent:ListEvent =
new ListEvent(ListEvent.ITEM_EDIT_BEGINNING, false, true);
// ITEM_EDIT events are cancelable
listEvent.rowIndex = rowIndex;
listEvent.columnIndex = 0;
dispatchEvent(listEvent);

I am trying to make a tree that upon a particular drag and drop will immediately make the item that was just dropped to be an editor.

The idea is to have a tree where a "New Item" can be dragged into a particular place in the tree and once it is dropped, the user has the ability to name it. If the user decides not to name it, it should go away.

I have been trying for some time to make this to no avail. This post is the first thing that I have found that has been helpful. If anyone here has any additional info that might be useful for what I am doing I would appreciate it.

Thanks.

--------------------------
Alex responds:

I assume you saw this post as well? http://blogs.adobe.com/aharui/2008/03/custom_arraycollections_adding.html

Any suggestions on how to double-click on an unused list entry in order to insert a new item?

----------------------
Alex responds:

Start here: http://blogs.adobe.com/aharui/2008/03/custom_arraycollections_adding.html

I found some issue with this. I transofrmed it to work with List. Elements in the list can be deleted with key. After deletion, it starts editing at the newly selected item.
Do you have a solution for this?

----------------
Alex responds:

You didn't say where you want it to go. I'd probably put in some mode where you're in "newEntry" mode or not and when someone clicks delete switch out of newEntry mode and run the List normally.

I use your DoubleClickDataGrid with an ItemEditor. The ItemEditor consists of 1 TextField and 2 Buttons (Cancel and Submit). And the DoubleClickDataGrid is in a Repeater.

Now my question: how can I control (cancel or submit) the ItemEditor with this 2 Buttons correctly?

At present, I use KeyboardEvents. That means when I click the Cancel-Button, I "dispach" the KeyCode 27 to the TextInput in the ItemEditor (and the KeyCode 13 when Submit is clicked).

Is this good style? Because now I have some problems with your DoubleClickDataGrid - Component.

When I click the Cancel-Button in the current ItemEditor the edit will be canceled and the old value of this cell is in this cell (like you press the Esc Button on you Keyboard).

This works fine.

When I click my submit button, the old value will be replaced with the new one (like you press the ENTER Button). But now when I click (one time - not doubleclick) in a row of another or the same DoubleClickDataGrid in the Repeater the ItemEditor starts!?

This only happens when I use my submit-Button.

When I use my cancel-Button, ESC, ENTER or focusout with the mouse, this did not happened.

Any idea?

-----------
Alex responds:

I would try dispatching an itemEditEnd event with different DataGridEventReasons for submit and cancel

This is really a good and very useful to me.
But i need to double click edit the tree control, even i have followed the same way which is there in List.as
But it is not working as expected.
Could you please help me out in getting the tree editable on double click

----------------------
Alex responds:

I don't have time right now. I'd ask for help on FlexCoders.

Another option is to prevent the List (et al) from editing when you don't want it to. Subclassing is not required for this option. Use the itemEditBeginning and prevent the default action (editing the item).

I chose to use the rowIndex and require a second click. You can change the rowIndex without "clicking", so i fixed that with the itemClose/itemOpen events.

Sometimes it will edit on a single click if you've been collapsing or opening the branches. That could be solved by listening to itemOpen/itemClose events.

itemEditBeginning="confirmEdit(event)"
   itemOpen="previousIndex=-1"
   itemClose="previousIndex=-1"
/>
private var previousIndex:int;
private function confirmEdit(event:ListEvent):void {
  if (previousIndex != event.rowIndex) {
    previousIndex = event.rowIndex;
    event.preventDefault();
  }
}

keywords: Tree Flex edit on double click

Thanks for that grid! My comment here is somewhat on the side of a doubleclick grid, but it is related enough that I post it here. I am using your grid, but I want to be able to use my keyboard for navigating it. I am trying to make an F2 KeyboardEvent fake a double click, so that I can edit a cell. My problem is that the 'edit index' seems to not move when I keyboard UP or DOWN through the list. Also, my F2-triggered doubleclick on the Datagrid event does not seem to actually do anything. Might you have time to give me a hint..?
Thanks!

----------------------------
Alex responds:

On F2, set editedItemPosition.

Thanks, this works great for editing on double click. However, I would also like to handle the single click event. Any tips since the single click fires before the double click?

---------------------------------
Alex responds:

Not sure what you want to do, but you can always respond to MouseEvent.MOUSE_DOWN or CLICK

2 questions

1-how can i do to set the entire row editable?

2-how can i pass a parameter(parameterTest) in a row

and get this parameter in 'as' class

dgColumn = columns[dilr.listData.columnIndex];
dgColumn.editable = false;

to set whether is editable or not

thank you

---------------------
Alex responds:

you can't make the whole role editable at once although you could try floating a single column's editor over the whole row.

The .data property of the renderer is the entire data item and you can pull other properties off it.

To deny editability of a particular cell, you call preventDefault on the ITEM_EDIT_BEGINNING event. Setting the flags will not work.

Thank You Adobe and Alex

Great Blog by Alex, special thanks to Adobe Team

Regards,
Vajahat Ali
Software Engineer
Software Innovations
Lahore,Pakistan

my way to do it :


in the constructor : doubleClickEnabled = true;
addEventListener(ListEvent.ITEM_DOUBLE_CLICK, onEdit, false, 0, true ); addEventListener(ListEvent.ITEM_FOCUS_OUT, onEditing, false, 0, true );

then i clone and change the message send by the List/Datagrid

private function onEdit( e:ListEvent ):void
{
this.editable = true;

var clone:ListEvent = new ListEvent( ListEvent.ITEM_EDIT_BEGINNING,
e.bubbles,
e.cancelable,
e.columnIndex,
e.rowIndex,
e.reason,
e.itemRenderer);

dispatchEvent( clone );
}

private function onFocusOut( e:ListEvent ):void
{
this.editable = false;
}

and it's done :D

Hi Alex.
Thanks for the exemple, I was actually looking how to do that, and your post saved me a lot of time ;)

I just have a little but yet annoying bug :
- Click on an editable field of the datagrid
- Give the focus to an other window (using alt+tab for instance)
- Return to your browser/standalone player : the field enters in edition state :/

It seems to happen when the "activate" event is dispatched, but I haven't been able to find why :s

-------------------------
Alex responds:

That might be fixed when 3.4 comes out (due 'soon'), but for now you should be getting an ITEM_EDIT_BEGINNING event that you can use to block the edit session.

Hi Alex,

the demo looks great, I do have a problem though....I am recently new to Flex and I am doing something wrong. I have a working program that has a HttpService tag and handler that populates a datagrid from mysql.

I changed the mxml to read local:DoubleClickDataGrid as per your example and created a new ActionScript class file in my project with your class code in it.

When I compile I get an error in the mxml at the line with a message that the prefix local is not bound.

After some googling I am lost...any clues appreciated as to what I have done wrong much appreciated. Thanks for your time and sharing this with the community.
Stu.

-------------------
Alex responds:

You probably have to add xmlns:local="*" or some path in your top tag next to the xmlns:mx attribute

Hi Alex, Great postings! I've tried to implement your example, but it doesn't work as I have custom editors/renderers and I think that's what is causing the problem. I'm already using a custom DG that allows me to keep focus in my editor as a couple of the column editors have multiple fields. Any thoughts?

---------------------
Alex responds:

Maybe instead of a custom DG, use the post about multi-field editors

Hi Alex,

I have got this working now but am relatively new to flex - after googling to confusion I hope you can point me in the right direction.

When my table was a simple datagrid I had the following event defined:

tagsGrid.addEventListener(DataGridEvent.ITEM_EDIT_END, updateTagItem);

where tagsGrid is the name of the datagrid.

now I have changed the datagrid to DoubleClickDataGrid the event listner fails with "cannot access property or method of null object reference"

could you tell me how to refer to the custom component in the event listener

once again thanks for all your great help

Stu.

--------------------
Alex responds:

If the exception is thrown in the listener, then you need to check the code in the listener. Just because you've used a subclass of DG shouldn't change how you wrote that code. Maybe you reorganized the code in some way. You'll get a faster response if you post your code and the full stacktrace with line numbers on the Adobe Flex Forum

Hi Alex

this is following on from last nights question - after more troubleshooting it is not a DoubleClickDataGrid issue, it happens also with plain old DataGrid.

the issue I have is in the application container I have a ViewStack, under the viewstack I had two canvas defined, the DataGrid was in the first canvas, in this scenario the AddEventListner works fine, the AddEventListner is in an AS function init() which is run onCompletion of the Application container.

When I add a new canvas, even an empty one above the canvas containing the datagrid I immediately get the #1009 errors again.

I am missing something I guess in my understanding of Flex framework but cannot work out what is happening...

I know this is now off topic for DoubleClickDataGrid but if you can offer me a pointer through your experience it will be very much appreciated.

thanks
Stu.

---------------
Alex responds:

That sounds like you'll need to read up on deferred instantiation and creationPolicy. We create viewstack items "just in time". You'll see many Forum posts on this topic

Hi Alex, thank you for this very useful tip !

Jana, great solution to the doubleClickDatagrid! so simple and effective!

Cheers!

Hi Alex,
I'm trying to do a similar thing but reversed: I want to have a doubleClick action on a List, but still allow single click to invoke editing. What happens instead is that doubleclick just invokes the itemEditor. Is there a way I can set a doubleClick handler on a list so that doubleClick will not trigger the itemEditor?
--Henry

Hi Alex,
Great !! Thanks.
However, I've got a problem. The edit works very well when an item is double clicked, but I would like to call a function when a single click occurs. I've added a call to a function on the "itemClick" event of my datagrid, but the event is fired before a double click so now the double-click edit doesn't work any more... Any ideas on how to separate both events correclty ? Thanks.

Leave a comment


Type the characters you see in the picture above.

About this Entry

This page contains a single entry by Alex Harui published on March 7, 2008 2:56 PM.

Smooth Scrolling List was the previous entry in this blog.

Custom ILists, CheckBoxDataGrid, Merged Arrays is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.