1

I've gotten a checkbox header renderer to work well with flat DPs, but a hierarchical collection view is another story. On click, I want it to select all checkboxes in a given column. Here is my code:

var dp:HierarchicalCollectionView = _dataGrid.dataProvider as HierarchicalCollectionView; var testDp:GroupingCollection = dp.source as GroupingCollection; var rawDp:ArrayCollection = testDp.source as ArrayCollection;

for(var i:int=0 ; i < rawDp.length ; i++){ rawDp[i][_dataField] = cb.selected; }

It selects all checkboxes on the 2nd level of data, but doesn't select the top level of data. What am I missing here? I can't seem to find it.

Any tips are greatly appreciated. Thank you.

fumeng
  • 1,771
  • 5
  • 22
  • 61

1 Answers1

1

For hierarchical data you have to use a cursor which iterates over all levels of the hierarchical data.

var dp:IHierarchicalCollectionView = _dataGrid.hierarchicalCollectionView;
var cursor:IViewCursor= dp.createCursor();

while (!cursor.afterLast)
{
    cursor.current[_dataField] = cb.selected;
    cursor.moveNext();
}

Howerver, this works only with nodes that have previously been opened. So either expand all nodes with _dataGrid.expandAll() (you can collapse them afterwards since the nodes only have to be opened once) or iterate your hierarchical data manually:

function setCheckBoxValue(children:ArrayCollection, value:Boolean):void
{
    for each (var child:Object in children)
    {
        if (child.hasOwnProperty("children") && child["children"])
            setCheckBoxValue(child["children"], value);

        child[_dataField] = value;
    }
}

var myDataProvider:HierarchicalData = /* your data provider */;

// Call it like this...
setCheckBoxValue(myDataProvider.source, cb.selected);

Update: To answer your second question...

  1. Create a new CheckBoxColumn which extends AdvancedDataGridColumn. You can use it to preconfigure your headerRenderer and itemRenderer.
  2. In your custom item renderer you get hold of your column like this:
    grid = AdvancedDataGrid(listData.owner);
    column = grid.columns[listData.columnIndex] as CheckBoxColumn;
  3. Do the same in your header renderer.
  4. Whenever the CheckBox value in one of your item renderers changes dispatch a event through your column. Something like: column.dispatchEvent(new Event("checkBoxValueChanged"));
  5. Your header render should add an event listener to the column for the "checkBoxValueChanged" event (or whatever you call it). Whenever that event is fired loop through your data provider and update the headers CheckBox accordingly.

In theory that should work. HTH

Gerhard Schlager
  • 3,155
  • 1
  • 31
  • 53
  • That worked great, thank you. The issue I now face is de-selecting the checkbox in the header renderer when I de-select a checkbox in the item renderer. I've found several online examples but none seem to work. Do you know how to link those values together? Even a theoretical explanation would be of great help. – fumeng Jan 07 '11 at 18:35
  • I'd write a custom column as well as a custom item renderer. The item renderer (CheckBox) for each cell could dispatch a change event via column. The header renderer could listen to those events from the column. – Gerhard Schlager Jan 07 '11 at 19:49
  • That's what I've been trying to do from within a change handler in my itemRenderer a la: – fumeng Jan 07 '11 at 19:55
  • data[_dataField] = cb.selected; var dp:IHierarchicalCollectionView = _dataGrid.hierarchicalCollectionView as IHierarchicalCollectionView; dp.dispatchEvent(new CollectionEvent(CollectionEvent.COLLECTION_CHANGE)); – fumeng Jan 07 '11 at 19:55
  • First, I wouldn't use a CollectionEvent to signal such things. That could have some strange side effects... At least use a custom event for such things. Second, I've updated my answer. I've outlined the basic things you should implement. That should get you started. BTW: Don't forget to mark this answer as helpful. ;-) – Gerhard Schlager Jan 07 '11 at 20:17
  • It worked like a charm; and I learned something. I hope I marked your answer correctly as helpful. I tried registering to do it. Thank you very MUCH for your generosity and help! – fumeng Jan 07 '11 at 20:51
  • quick note: the cursor routine you coded above only sets the dataField property of the parent nodes...meaning, if the nodes aren't expanded, the children dataField properties don't get set. – fumeng Jan 07 '11 at 22:13
  • Yes, that's one of the annoying problems with the HierarchicalCollectionView and it's cursor. I forgot to mention that... I've updated my answer one more time with some suggestions to remedy this problem. – Gerhard Schlager Jan 08 '11 at 10:48
  • Thank you. I decided to use the _dataGrid.expandAll() method because I couldn't get access to the datagrid's dataProvider as HierarchicalData; it appears as a HierarchicalCollectionView. And its source is a GroupingCollection. So, I'm going to have to figure out how to work with it that way. But I thank you very much for your time and generosity. – fumeng Jan 10 '11 at 16:27