Welcome to Sơn Phạm's Blog

Everything or Nothing

Flex 3: Use CheckBox HeaderRenderer to select/deselete CheckBox ItemRenderer in DataGrid

I spent much time to create CheckBoxHeaderRenderer and CheckBoxItemRender components used in DataGrid so that you can check/uncheck items or you can even check all items by clicking on the checkbox All at the DataGrid header.

Here is code for application (CheckBoxInDataGrid.mxml):

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
xmlns:component="test.view.component.*" horizontalAlign="center" verticalAlign="middle"
creationComplete="init()">
<mx:Script>
<![CDATA[
import mx.events.CloseEvent;
import mx.events.DataGridEvent;
import mx.events.FlexEvent;
import mx.events.ListEvent;
import mx.controls.Alert;
import mx.collections.ArrayCollection;
import test.model.dto.Category;

private function init() : void {
addEventListeners();
}

private function addEventListeners() : void {
deleteSelectedButton.addEventListener(MouseEvent.CLICK, handleDeleteSelectedButtonClicked);
}

private function handleDeleteSelectedButtonClicked(event : MouseEvent) : void {
if (checkAllCol.itemsSelected.length > 0) {
Alert.show("Are you sure you want to delete the seleted items?", "Confirm Deleted",
Alert.YES | Alert.NO, this, handleConfirmDeleteSelected, null, Alert.YES);
}
}

private function handleConfirmDeleteSelected(event : CloseEvent) : void {
if (event.detail == Alert.YES) {
var provider : ArrayCollection = myDataGrid.dataProvider as ArrayCollection;
for each (var item : Category in checkAllCol.itemsSelected) {
provider.removeItemAt(getItemIndex(provider, item));
}
checkAllCol.itemsSelected.removeAll();
}
}

private function getItemIndex(list : ArrayCollection, item : Category) : int {
for (var index : int = 0; index < list.length; index++) {
if (item.id == list[index].id) {
return index;
}
}
return -1;
}

public function initItemsSelected() : ArrayCollection {
var itemsSelected : ArrayCollection = new ArrayCollection();
for (var i : int = 0; i < 5; i += 2) {
var category : Category = new Category();
category.id = i;
category.title = "Title " + i;
category.description = "Description for title " + i;
itemsSelected.addItem(category);
}
return itemsSelected;
}

public function initItemList() : ArrayCollection {
var itemList : ArrayCollection = new ArrayCollection();
for (var i : int = 0; i < 20; i++) {
var category : Category = new Category();
category.id = i;
category.title = "Title " + i;
category.description = "Description for title " + i;
itemList.addItem(category);
}
return itemList;
}
]]>
</mx:Script>
<mx:VBox horizontalAlign="right">
<mx:DataGrid id="myDataGrid" dataProvider="{initItemList()}" sortableColumns="false">
<mx:columns>
<component:CheckBoxHeaderColumn id="checkAllCol"
headerRenderer="test.view.component.CheckBoxHeaderRenderer"
itemRenderer="test.view.component.CheckBoxItemRenderer"
itemsSelected="{initItemsSelected()}" headerText="All" width="50"/>
<mx:DataGridColumn id="titleCol" headerText="Title" dataField="title" />
<mx:DataGridColumn id="descriptionCol" headerText="Description" dataField="description" width="150" />
</mx:columns>
</mx:DataGrid>
<mx:Button id="deleteSelectedButton" label="Delete Selected"/>
</mx:VBox>
</mx:Application>

The CheckBoxHeaderColumn class (CheckBoxHeaderColumn.as):

package test.view.component
{
import mx.collections.ArrayCollection;
import mx.controls.dataGridClasses.DataGridColumn;

public class CheckBoxHeaderColumn extends DataGridColumn
{
public var itemsSelected : ArrayCollection;
public var checkBoxHeaderRenderer : CheckBoxHeaderRenderer;
public var checkBoxItemRenderer : CheckBoxItemRenderer;

public function CheckBoxHeaderColumn(columnName:String=null)
{
super(columnName);
}
}
}


The CheckBoxHeaderRenderer class (CheckBoxHeaderRenderer.as):

package test.view.component
{
import flash.events.MouseEvent;

import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.controls.CheckBox;
import mx.controls.DataGrid;

public class CheckBoxHeaderRenderer extends CheckBox
{
private var _headerColumn : CheckBoxHeaderColumn;

public function CheckBoxHeaderRenderer()
{
super();
}

override public function set data(value:Object):void {
var list : ArrayCollection = (listData.owner as DataGrid).dataProvider as ArrayCollection;
_headerColumn = value as CheckBoxHeaderColumn;
_headerColumn.checkBoxHeaderRenderer = this;
label = _headerColumn.headerText;
selected = (_headerColumn.itemsSelected.length == list.length) ? true : false;
}

override protected function clickHandler(event:MouseEvent):void {
super.clickHandler(event);
if (!selected)
_headerColumn.itemsSelected = new ArrayCollection();
else {
var list : ArrayCollection = cloneArrayColection((listData.owner as DataGrid).dataProvider as ArrayCollection);
_headerColumn.itemsSelected = list;
}
Alert.show(_headerColumn.itemsSelected.length + " items selected.");
_headerColumn.dispatchEvent(event);
}

public function cloneArrayColection(arrayCollection : ArrayCollection) : ArrayCollection {
var result : ArrayCollection = new ArrayCollection();
for each (var item : Object in arrayCollection) {
result.addItem(item);
}
return result;
}

}
}


The CheckBoxItemRenderer (CheckBoxItemRenderer.as):

package test.view.component
{
import flash.events.MouseEvent;

import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.controls.CheckBox;
import mx.controls.DataGrid;

import test.model.dto.Category;

public class CheckBoxItemRenderer extends CheckBox
{
private var _checkBoxHeaderColumn : CheckBoxHeaderColumn;

public function CheckBoxItemRenderer()
{
super();
}

override public function set data(value:Object):void {
var dataGrid : DataGrid = listData.owner as DataGrid;
var list : ArrayCollection = dataGrid.dataProvider as ArrayCollection;
_checkBoxHeaderColumn = dataGrid.columns[listData.columnIndex];
_checkBoxHeaderColumn.addEventListener(MouseEvent.CLICK, columnHeaderClickHandler);
_checkBoxHeaderColumn.checkBoxItemRenderer = this;
if (_checkBoxHeaderColumn.itemsSelected != null && list != null) {
selected = containsItem(_checkBoxHeaderColumn.itemsSelected, value);
}
}

override protected function clickHandler(event:MouseEvent):void {
super.clickHandler(event);
var dataGrid : DataGrid = listData.owner as DataGrid;
var list : ArrayCollection = dataGrid.dataProvider as ArrayCollection;
var item : Category = list[listData.rowIndex + dataGrid.verticalScrollPosition];
if (!selected) {
_checkBoxHeaderColumn.checkBoxHeaderRenderer.selected = selected;
removesItem(_checkBoxHeaderColumn.itemsSelected, item);
Alert.show("Item de-selected: " + item.title);
}
else {
_checkBoxHeaderColumn.itemsSelected.addItem(item);
Alert.show("Item selected: " + item.title);
if (_checkBoxHeaderColumn.itemsSelected.length == list.length)
_checkBoxHeaderColumn.checkBoxHeaderRenderer.selected = selected;
}
Alert.show(_checkBoxHeaderColumn.itemsSelected.length + " items selected.");
}

public function containsItem(list : ArrayCollection, target : Object) : Boolean {
for each (var item : Object in list) {
if (item.id == target.id)
return true;
}
return false;
}

public function removesItem(list : ArrayCollection, target : Category) : void {
for (var index : int = 0; index < list.length; index++) {
if (list.getItemAt(index).id == target.id) {
list.removeItemAt(index);
return;
}
}
}

private function columnHeaderClickHandler(event:MouseEvent):void {
selected = _checkBoxHeaderColumn.checkBoxHeaderRenderer.selected;
}
}
}

Finally, the Category class:

package test.model.dto
{
public class Category
{
public var id : int;
public var title : String;
public var description : String;

public function Category()
{
}
}
}

This is demo.

The flex 3 project can be downloaded here.

Đối đáp với người yêu

Comments

Anonymous Tuesday, November 4, 2008 5:24:38 PM

Navis Michael Bearly writes: Amazing Work

Anonymous Wednesday, December 17, 2008 1:01:56 PM

Anonymous writes: Hey Phạm Thanh Sơn, Can u tel me how to delete the particular record when click on the chekboxItemRenderer (or) all records at a time when click on CheckBoxHeaderRenderer. Can u please.........

Phạm Thanh Sơnphamthanhson Tuesday, December 23, 2008 9:03:12 AM

The property itemsSelected in the CheckBoxHeaderColumn class always contains checked records. So if you want to delete them you simply remove them out of the datagrid dataProvider.

Anonymous Wednesday, January 28, 2009 5:00:36 PM

Anonymous writes: Hi Phạm Thanh Sơn, First, thanks for your great work ! However I noticed that the rollOver on the dataGrid is not very fast and is random... I tried to solve that problem, but nothing works... Have you got a solution ? Thanks

Phạm Thanh Sơnphamthanhson Tuesday, February 3, 2009 3:48:17 AM

I've just updated code for the CheckBoxItemRenderer class and the changes are marked in royal blue color. Please let me know if this demo does not work as you're expecting.

Anonymous Wednesday, February 25, 2009 4:12:55 PM

Anonymous writes: Hi !! Thanks for the update, but i still have the same problem : when I move the mouse over the table, the line under the mouse cursor is not highlighted (the highlight stays on the first line that I move on). I think it might be caused by some event's beging caught by the header renderer, or something ?

Anonymous Thursday, February 26, 2009 8:00:36 AM

PH writes: Hi for info, I managed to fix the problem, simply by adding a call to super.data = value in the 'set data' method of component CheckBoxItemRenderer. Thanks again ! Cheers PH

Anonymous Sunday, March 29, 2009 9:21:44 AM

kiran writes: Nice article. One question: How can I Enable and disable check box when editable property is false. When I gave editable property as false I am able to check and uncheck (Both in Header as well as item in columns). Can you please suggest something that will do the same? Thanks in advance Kiran

Anonymous Wednesday, May 27, 2009 10:23:12 PM

xela writes: HI, i would like to know, how to unselect de check boxes after excecuting an event

Anonymous Tuesday, September 15, 2009 6:44:44 AM

suman writes: Hi, Can u please send me code for- How to delete selected items.

Anonymous Tuesday, September 15, 2009 6:47:24 AM

Anonymous writes: If i click on delete selected.The selected items should delete..Iam using ur code. Please send me the action script code for DELETE SELECTED....

Anonymous Tuesday, September 15, 2009 1:43:31 PM

suman writes: Thanks for ur hardwork. Iam using ur custom components. But iam having problem to delete select all/select one.Can u please send me code for delete selected.Iam very muc thankful to you......Please send me sooner...

Phạm Thanh Sơnphamthanhson Monday, September 21, 2009 4:40:45 AM

I am very sorry for the delay. I've just updated code to deleted selected items. Please let me know if it has any issue. Thanks.

Anonymous Monday, November 9, 2009 8:14:38 AM

A * R writes: Hi Sơn Phạm, Excellent work man.. You are my life saver.. :) thanks a lot.. But I had small concerns.. The first concern was the usage of Category in item rendered.. The problem for me is, my VO is something different.. the fix I did was a simple one.. I replaced the usage of Category with Object.. the next concern was the usage of property id in ‘removesItem()’ method.. In my VO there is no id property… so I had to do a small work around to fix it.. now the component works in a generic way.. I mean for any VO.. thanks a lot man.. great work…

Anonymous Tuesday, January 12, 2010 4:54:21 PM

Anonymous writes: To all developers.. Can you PLEASE start using XML lists and not Array Collections for demos please. It would make life a lot easier and reduce the number of messages. Thanks

Anonymous Tuesday, January 12, 2010 5:00:11 PM

Anonymous writes: To all developers.. Can you PLEASE start using XML lists and not Array Collections for demos please. It would make life a lot easier and reduce the number of messages. Thanks

Anonymous Wednesday, May 5, 2010 8:41:16 AM

Anonymous writes: Hi

Anonymous Tuesday, August 24, 2010 10:47:56 PM

suresh writes: Hi, Nice work, I would like to Align the Check box to center, how can I do that. Some examples mentioned updateDisplayList by passing width and height of the column, but it was extended Canvas. please let me know

Anonymous Tuesday, August 24, 2010 11:01:43 PM

suresh writes: sorry, it worked fine by overriding DisplayObject, Thanks

Anonymous Tuesday, August 24, 2010 11:02:35 PM

suresh writes: it worked with DisplayObject override

Anonymous Wednesday, September 22, 2010 11:41:33 AM

Dinesh writes: Hey it was amazing.. this really helped me a lot.. thank you so much for posting this...thank you again.. with regards, Dinesh

How to use Quote function:

  1. Select some text
  2. Click on the Quote link

Write a comment

Comment
(BBcode and HTML is turned off for anonymous user comments.)

If you can't read the words, press the small reload icon.


Smilies