« Flex and ScaleMode | Main | Smooth Scrolling List »

CheckBox selection in DataGrid and List

Several folks have asked how to use Checkbox renderers to handle multiple selection in a DataGrid or List. There are some solutions out there already, but here's mine. Usual caveats apply.

Download Source
Run Demo

Comments

Do you have any suggestions for how to maintain the "selected" style you usually get with selected items in a list, the hightlight, etc? I posted a solution to this on my blog, but it's a hack at best. I think the ListBase is hardcoded to look for a CTRL or SHIFT modifier so I intercept mouse events and set those properties.

http://www.thegoldhold.com/?p=4

I'd love to hear your thoughts on a 'cleaner' approach, but that's what I had to do to get the job done.

Thanks for your thoughts as always.

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

In my example, I override drawSelectionIndicator to turn off the visuals. If you remove that override, you should see the items show selection as they are checked.

The basic principle of my example is to essentially make "dead" checkboxes. They don't handle mouse or key events at all and just let the List or DataGrid handle the clicks as if it was a regular renderer, except I force the control to think that the ctrl key is pressed all the time.

It sounds like you took a similar approach. I glanced at your code briefly and saw that there was some room for optimization so went ahead and posted mine.

Good stuff. I updated my example to override the selectItem function as well. Glad you posted your approach so I can make those changes in our project as I find myself using the checkboxes for most of our datagrids. Great to have such an active community to build on.

The following happens when reordering the columns in the grid:
TypeError: Error #1034: Typumwandlung fehlgeschlagen: mx.controls.dataGridClasses::DataGridItemRenderer@2de8cf11 kann nicht in mx.controls.CheckBox umgewandelt werden.
at CheckBoxDataGrid/drawItem()
at mx.controls.dataGridClasses::DataGridBase/drawVisibleItem()
at mx.controls.dataGridClasses::DataGridBase/makeRows()
at mx.controls.dataGridClasses::DataGridBase/makeRowsAndColumns()
at mx.controls::DataGrid/makeRowsAndColumns()
at mx.controls.listClasses::ListBase/makeRowsAndColumnsWithExtraRows()
at mx.controls.listClasses::ListBase/updateDisplayList()
at mx.controls.dataGridClasses::DataGridBase/updateDisplayList()
at mx.controls::DataGrid/updateDisplayList()
at mx.controls.listClasses::ListBase/validateDisplayList()
at mx.managers::LayoutManager/validateDisplayList()
at mx.managers::LayoutManager/doPhasedInstantiation()
at Function/http://adobe.com/AS3/2006/builtin::apply()
at mx.core::UIComponent/callLaterDispatcher2()
at mx.core::UIComponent/callLaterDispatcher()

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

Like I said, caveats apply. I would set draggable=false on the column so it stays as the first column.

Hi. This is very useful if the list is used "alone". I have a somehow different situation.

The data provider is to be changed externally (by a filter function), when the user writes in a textbox (shown items have the typed string as a substring). On the other side, the 'checked' state of the box must persist whether or not the item are filtered out, so using internal 'selectedItems' is out of question, because when items are filtered out they are of course automatically deselected.

Using just a custom function for selection with inthe checkBox renderer gives the 'show' part, but the 'change' part is much harder. Do you have any idea? If I just use the renderer as editor, the diplays shows garbage in the renderers...

Typically the list of 'checked' items lives in an ArrayCollection somewhere in the component.

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

I should have mentioned the limitations of this version. It doesn't allow the kind of functionality you are looking for nor does it allow sorting by selected entries. Both require storing some knowledge of the selection state in the dataProvider.

If you have a slot in your dataobjects to store selection state, great, and then I might not use the List's selection code at all.

If you don't have a slot for your dataobjects, you'll need a separate collection. One of these days, maybe I'll show how to do a mergedCollection. I thought Deepa was going to post an example, but I didn't see it on her blog.

Hi. This has worked great for me but I have been trying to work out how to have all the check boxes defaulted to selected.

I've tried a couple of things but can't get it to work.

Can you suggested a solution ?

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

I would just create an array of numbers from 0 to n and pass that into selectedIndices.

Hi Alex,
I have a question regarding the selection of a checkbox within the datagrid by default. As in, I am trying to get a checkbox to be checked by default using a dataprovider. I have an array with one of the elements as { source: "WH", repCost: "10.99", sourceableQuantity: "35", totalQuantity: "20", leadTime: "15", relevant: true}. I convert this Array to an ArrayCollection and pass this as a dataprovider to CheckBoxDataGrid. I have dataField="relevant" editorDataField="selected" rendererIsEditor="true"
width="20" sortable="false" editable="true" itemRenderer="controls.itemRenderers.CheckBoxRenderer" for the checkbox DataGridColumn. However, it doesnt display the checkbox as checked. What am I doing wrong?. Sorry if this is a noob question. Thanks for all your help.

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

You might be better off using this post:
http://blogs.adobe.com/aharui/2008/03/custom_ilists_checkboxdatagrid_1.html

thank you for this code.. appreciate it .. saved me a load of time.. :)

btw. rite now jus tryin to figure out and change it.. why do you have a checkbox selection on keyboard press.. i mean when you keypress 'S', 'I' or any character it selects the particular item in the list box. I jus want to get it into focus but selection only by mouse click..

i'll try to figure it would will shout fr help if required.. :)

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

I didn't set up that functionality, it is built into the list classes. They search for entries based on the last letter typed and selected them. You can turn that off by overriding the findString() method and have it do nothing.

Hi, It is really a great knowledge source all the samples you write. Thanks for all the help and greetings from México.
My question, once, I have this array of index, how can I send them all to a PHP, I'll take care the php part but what about the flex part, I would like to send not the index but the names so I can receive them with a php function and then submit them to a database, I would like to use it like a shopping cart selector.

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

If you are using this example, I would get the selectedItems array from the DataGrid. It will be an array of references to items in the dataprovider, and you can pull the appropriate fields and post them back to your server.

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)