A 3-state checkbox in an AdvancedDataGrid ItemRenderer

There is a post in Flex component Yahoo group on how to show a 3-state checkbox in an AdvancedDataGrid.

It has been implemented for the Flex Tree Control in the Flex cookbook.

I thought lets write a similar example for AdvancedDataGrid. I made some changes in the original sample and here it is; working for the AdvancedDataGrid control.

Example here

Source here

Advertisements

122 thoughts on “A 3-state checkbox in an AdvancedDataGrid ItemRenderer

  1. HI, thanks, can you you perhaps add another column to your grid, I have also used the same technique, my grid column with the rendered check box do not resize correctly if wordWrap=”true”

  2. Great example! I was simply trying to get unique images prepended to the label in the tree. You’re work saved me a ton of time figuring out this new Advanced DataGrid and its new renderers.

    Thanks!
    RJ

  3. Sameer,
    Thanks for the example. Do you have a similar example using AdvancedDataGridItemRenderer which puts the CheckBox in a different column than the tree (instead of AdvancedDataGridGroupItemRenderer)? Thanks.

  4. Hi Jay,
    Do you want the same behavior of the check box (as it is present in the ADGGroupItemRenderer) in the ADGItemRenderer also.
    Or do you just want a renderer with text and checkbox in it.

  5. Hi Sameer,
    I wonder if its just my browser or everyone sees it like that.
    For the 3 state checkbox rendered, the dot (image) doesn’t appear in the center of the checkbox (square), but on the bottom of the checkbox.
    I saw this problem even with the flex cookbook example for 3 state checkbox in a tree… Interestingly, its rendered perfectly in Flex 2, but misaligns only Flex 3.

    Do you also see this?

  6. Do you mean that when you compile the same Flex cookbook code in Flex 2, it shows the dot image in the center and when compiled with Flex 3 it shows the image in the bottom?

  7. Sameer,
    Can you point me to any examples that show drag and drop between two ADGs with slightly different object models (but both based on HierarchicalData)? Thanks.
    Jason

  8. You can traverse through the Hierarchical collection returned by the AdvancedDataGrid.dataProvider property and check all the items which have state as “checked”.
    For example,


    var cursor:IViewCursor =
    IHierarchicalCollectionView(adg.dataProvider).createCursor();
    while (!cursor.afterLast)
    {
    if (cursor.current.state == "checked")
    // got the item, do operation

    cursor.moveNext();
    }

  9. Hi
    Sameer
    i had seen ur example it is nice
    but can give the same checking checkBox example with
    the flat data because i am using flat data from DB

  10. Hi Sameer,

    ich have also data from a database and an ArrayCollection instead of a XML structure.

    Your code is not working for me with the ArrayCollection as dataProvider.

    I tried 2 days to figure out the difference but it’s not working.

    That is very sad 😦

  11. First you need to have a property in the items in your ArrayCollection to store the state.
    Then you need to make some changes in the Renderer. The renderer assumes the data to be xml and modify it using xml syntax (you can see the @ [at] symbol). You can see this line being used at various places –
    item.@state = state;

    You need to remove the @ [at] symbol. So, just make it –
    item.state = state;

    There will be some more minor changes which you can figure out.
    Otherwise, you can share a sample and I’ll have a look at it.

  12. Yes i have a property called “checkbox” and therefor item.checkbox

    I think there is a little problem with the “HierarchicalData”, because i used the normal ArrayCollection as DataProvider and not the HierarchicalData(ArrayCollection). And so the child-checkboxes were not refreshed.

    So i try to convert my ArrayCollection to HierarchicalData.

    • Hi Marcus

      did u get ur proplem solved..
      Checkbox are not getting updated, when I click arrow mark of group node it gets updated..
      Please let me know if u have fixed the problem
      Thanks
      vijay

      • The issue that Marcus was facing was resolved.
        The reason – Objects are not bindable and changing their properties will not notify that something is changed.
        The simplest solution for your case is to use ObjectProxy instead of Object.

        Otherwise, when you are updating the state by doing –
        item.state = state;
        You have to notify to the collection that something in it has changed.
        You can do so by using the ICollectionView.itemUpdated() method.

  13. I don’t get it. I change the checkbox property of my item, but the “set data(value:Object)” function is not fired. That i really strange.

    Should I post the full code here or is it better to send you a mail with the full example?

  14. Hi!

    First of all, thank you for this control. I’ve found it very useful.
    Can you give me some help to make it dinamic?
    I mean, i`m using it with datas got from a server. And when i`m updateing the data to the advancedDatagrid.dataProvider, the list item that have been checked dosent trigger the parent node to “open”.

    Thanks.

  15. The data you are getting from the server will be in the form of Objects. Objects are not bindable and changing their properties will not notify that something has changed.
    So, in the renderer, when you set the state you can notify the collection that something in it has changed by using the ICollectionView.itemUpdated() method.

    If this is not what you are looking for, then it’ll be great if you can send a simple sample explaining your issue..

    • Sameer,
      I tried your code on flex 4 with ArrayCollection, it seems crashed with a “white” screen, even I have changed all item.@state to item.state. Could you let me know if this renderer supports flex 4, or you have better solutions for ArrayCollection data (from DB). Thanks in advance,

  16. Hmm im pretty new to Flex so I`m trying to explain my problem.
    I have to grids:
    – a simple datagrid contains some editable row (id=”dgFiles”)
    – an AdvancedDatagrid with your groupItemRendere. (id=”adgTexts”)

    When the user selects a row in dgFiles, the script sending a request to the server, and getting the ids that should be checked in in the adgTexts. So the main goal is to save the checked rows id from the adgTexts and attache it to the selected item in the dgFiles.

    Here are the datagrids:

  17. Is the CheckADGRenderer.as file customized for the ‘label’ and ‘state’ columns in your example? I can’t seem to get it work.

    I am using an ArrayCollection and I added a property called ‘state’.
    Although I have 4 other properties that I am displaying in the advanced datagrid. Do I need to include all of them in the AS file?

    Also, you stated how to get the checked values, but I’m not sure where to place the code. Could you post an example?

    ps. great work!

  18. The file CheckADGRenderer is customized only for the state property.
    See comments 17 and 22 above for the required steps on how to make this control work with ArrayCollection.
    If that does not help then let me know.

  19. Hi Sameer,

    Excellent Sample. Can i use this code to have a checkbox in tha grid header? if so then how can i acheive the functionality of “Select All” in Datagrid control.

    Thanks in advance.
    Vinitha

  20. Hello Sammer,

    I need to use the CheckADGRenderer as an ItemRendenderer instead of an ItemGroupRenderer.
    I have a grid with hierarchical data, but I need the checkbox in others columns.
    For example:
    property1 property2
    HData1 true false
    HData1A true false
    Item1AA true false
    Item1AB true false
    HData1B true false
    Item1BA true false
    Item1BB true false

    Do you think that you can update the code to do this?
    I’m very new in flex and I can’t get it working.
    Thank you very much.

    (Excuse my poor english).

  21. You can use CheckBox in other columns by setting the itemRenderer property of that column.
    Or do you want to use CheckADGRenderer in other columns?

  22. I want to use the CheckADGRenderer.
    Can I post code here?

    I use the ExternalInterface to get the data from a js function that shoots a AJAX.
    I transform the XML in a ArrayCollection, then I populate the grid with it.

    I need to use the checkboxs in diferent columns. And the CheckADGRenderer would give me exactly what I want (if I could get it work correctly…)

  23. So, you want to use CheckADGRenderer in other columns also.
    As of now, you can use it in only one column which is the first column by default. You can change the column by setting the “treeColumn” property.

    You can to extend AdvancedDataGrid and override some methods like makeListData(), etc.. to accomplish this.

    You can mail me here prosameer@gmail.com

  24. I need to Embed 2 LinkButton inside Advanced Datagrid. If i tried to embed ny Advanced grid position doesn’t maintain for link button proerply or If i keep it as 2 Seprate Column as link button column Scroll bar disappears for expanded Advanced Grid…. do you have solutions for that…

  25. Hi Sammer,
    Thank you for your example and hints. I need to use flat data and I adapted the example to use flat data but I could not get it initialize with three states (only checked or unchecked).
    I could not find a smart way to do it. Do you have any suggestions?
    I will send you my sample by e-mail I hope it is OK.
    Haluk

  26. Quick update for those trying to get this working with a flat GroupingCollection. The set function isn’t getting fired and the cascading checkboxes aren’t being updated because the GroupingCollection refreshes only on demand for performance reasons.

    To make it work beautifully, all that’s needed (in addition to above) is to add the line below at the end of toggleChildren:

    adg.dataProvider.refresh();

    Thanks Sameer for figuring this all out… I would never have thought of using updateDisplayList for the alignment!

  27. FYI!

    For the message I read earlier where the dot appears at the bottom when compiled with Flex 3, the solution to fix that would be to make the following change.

    In the CheckADGRenderer class under the updateDisplayList function, set the value for myImage.y = myCheckBox.y – 3 instead of myImage.y = myCheckBox.y + 4 within the if condition for STATE_SCHRODINGER.

  28. Is it possble to control the depth till which CheckBox are rendered? Say if in oen of the child I dont have property state then where / how I shud specify that for a particular level of node/leaf there are no checkboxes?

  29. You can put a check in the CheckADGRenderer or use rendererProviders property in AdvancedDataGrid. It provides options to specify renderers for a particular Depth, having a particular property, etc..

  30. but renderer wont help as I need the checkbox with the hierarchial data. I have tried putting check in the component but its still rendering the checkboxes till the most lowest leaf node of the tree. Any other workaround or placeholder in code as to whr i can put the check?

  31. First off thanks for the great example, its already been very helpful. What I’d like to be able to do is have the lowest level children within the datagrid as clickable. Previously I had them as link buttons, but when I leave the item renderer in for the link button it overrides the checkbox. Could you steer me in the direction of how to make only the lowest level items within the hierarchy clickable link buttons?

  32. If you want link buttons only in the lowest level children, you can set the itemRenderer property on the column.
    You can also use rendererProvider property on the AdvancedDataGrid for customizing the renderers position.

  33. Setting the item renderer then removes the checkbox that is at that level, is it possible to still have a checkbox without the label and then have the linkbutton act as the label for that box?

  34. Is there any way that I can render a TextInput and a Label inside AdvancedDataGridColumn (Header)? And while clicking the Label the default sort functionality of column must happen/

  35. Sameer, this example is grt… I am looking for a small variation from this example. I need the checkboxes only for the grouped items. So is there a property which i set ??? A code snippet wud be really appreciated and its helpful to a grt extent

  36. You can set the itemRenderer in the column –


    <mx:columns>
    <mx:AdvancedDataGridColumn dataField="@label" itemRenderer="mx.controls.
    advancedDataGridClasses.
    AdvancedDataGridGroupItemRenderer" />
    <mx:AdvancedDataGridColumn dataField="@state" itemRenderer="mx.controls.
    advancedDataGridClasses.
    AdvancedDataGridGroupItemRenderer" />
    </mx:columns>

  37. I have another question about the license of your component. You said it’s open source, but which open source license do you use? Is it possible to use it in an commercial product without any charge or limitations?

  38. Hey Sameer,

    Thanks a lot for this component, it works really well. However, I do have a question that hopefully you can provide some clarity.

    For instance, in your example, the datasource used is an XMLList, where all ‘folder’ nodes have the state attribute = “unchecked”. As expected, when the datagrid is rendered, all nodes are indeed unchecked.

    This issue I run into is, if any of those state attributes are modified to “checked”, only the corresponding folder node is actually checked. The parent nodes do not have the schrodinger dot.

    Say, for instance I have a function that assigns
    a.b.c.@state = “checked”

    Right now, when I do that I get

    * a – unchecked
    ** b – unchecked
    *** c – checked

    Is there a function that can be called, after modifiying the state attributes, to make it show correctly?

    * a – schrodinger
    ** b – schrodinger
    *** c – checked

    I am not sure what is needed to be done – refresh/update the dataprovider?

    Many Thanks!

  39. Hi Sameer,

    Can u make all the checkboxes(Including parent and Child) selected on a Button click?

    Lets say we have two buttons “Select All” and “Deselect All” doing selection and removing selection.

  40. Hi Sameer,
    awesome code. Really helped me understand some stuff.

    I still have a problem though… I would like to enable dragging between items. I added this in the datagrid.

    dragEnabled=”true”
    dropEnabled=”true”
    dragMoveEnabled=”true”

    When I try to move something,I get the following error
    Error #1009: Cannot access a property or method of a null object reference.

    The error comes from : function set data(value:Object)

    Any help would be greatly appreciated.
    Thanks

  41. Hi Steven,
    This error occurs when you start dragging. A drag proxy is created and the data property is set before adding the drag proxy to the display list.
    So, at the time of setting the data, the checkBox and listData will be null.
    To workaround this issue you have to add some null checks in the set data method in renderer. Something like –

    super.data = value;

    if (myCheckBox == null || AdvancedDataGridListData(super.listData).item == null)
    return;
    ……

    Also, some cases like updating the state of the parent,, etc.. needs to be handled after the drag-drop is complete.

  42. Hi Sameer,
    I have a currency column which i was formating using a CurrencyFornatter.The things were working fine.But now my client wants that i should make currency column a hyperlink column.
    So now iam using linkbutton as my ItemRenderer,but the problem is iam loosing Formatting.
    here is my code.

    The data is coming as it is.
    I think i need to set label property of linkbutton with the formatted rather than pure datafield.

    Thanks in advance

  43. Hi Sameer,
    Here’s a screen-shot of how I see the example in IE7, Firefox 3 And Chrome as well…

    Is it really an issue with the browsers or Flex 3 renderer?

    PS. I’ve the latest Flash 10 player installed.

  44. So, what’s the issue here. Is the Application being cut on the right side as shown in the image?
    If you are wondering what the small black rectangle is, which is being shown for some CheckBoxes in the Application. Its the Schrodinger state denoting that some of the parent node’s children are checked, unchecked state and/or in again in schrodinger state.

  45. Yes Sameer I understand the meaning in it… And the image is cropped by me…
    The issue is that the dot is appearing at the bottom of the square instead of in the middle of the checkbox.
    And this happens only for Flex 3, but not when compiled in Flex 2.

  46. I’ve not tried with Flex2.
    However, you can change the x/y position of the image in the CheckADGRenderer file.
    In updateDisplayList() method, look out for myImage.x/y. It is set to checkBox.x/y + 4. You can change it to get the desired result you want.

  47. I implemented this for AdvancedDataGrid in Flex 3 and from the beginning I’m getting the image at the bottom only. So, I assumed its meant to be like that from the original Flex cookbook sample.
    If it behaves in a different manner in Flex 2, then may be we should change the y position of the image.

  48. Hmmm, ok…
    Well, now you know πŸ™‚ It should indeed be the dot coming in the center of the checkbox, as its coming that way in Flex 2.
    Same is the case when compiling the Cookbook code in Flex 2 and 3.

    Perhaps you can update the code here, and make it look better.

  49. Hi, Sameer.
    It’s a great component, we are using it in our enterprise application. However, we have a problem we can’t solve.
    We have our ADG inside a module. the module is set to 100% width and 100% height. When the module is dropped inside a container wich does not provide enough space for the ADG, the module shows a vertical scroll bar, as expected.
    The problem is that when one of the grouped check is clicked, moving the scroll up and down shows that the rest of the grouped items are not always being refresed correctly. It happend only in grouped checks, and never in item checks.
    Everyplace where we combine the scroll bar and the item renderer we have refreshing problem, and we don’t know the reason, any idea?

  50. Hi, Sameer
    We finally found the problem. We are gruping an ArrayCollection via Actionscript, using GroupingCollection objects. So the grouped items does not have an state field like the item ones.
    We solved this issue by modifying the setCheckState function this way:

    private function setCheckState (checkBox:CheckBox, value:Object, state:String):void
    {
    if (state == STATE_CHECKED)
    {
    checkBox.selected = true;
    }
    else if (state == STATE_UNCHECKED)
    {
    checkBox.selected = false;
    }
    else if (state == STATE_SCHRODINGER)
    {
    checkBox.selected = false;
    }
    else checkBox.selected = false; // NEW LINE
    }

    Hope this helps. Thak you

  51. Actually, you can provide the state (selected property) in the group nodes while Grouping also by using Grouping.groupObjectFunction. You can provide an Object containing the selected property using this function.

    • Hi Sameer
      As Marcus mentioned earlier , Checkbox are not updated on clicking instead they get updated when i click on the arrow marks of group node..
      please let me know if any solution.

  52. Thanks Sameer ..
    I tried collectionview.itemUpdated(item); it worked..

    I have one more issue..I have two grouping field, I want to change just the label of the first grouping field with other column value which is not grouped..
    i have this code in GroupLabelFunction to calculate no of childnode and display along with group label..
    grpFunc(data:Object,column:AdvancedDataGridColumn):String
    {
    var gc:IGroupingCollection = adgChequeInfo.dataProvider.source as GroupingCollection;
    var childCount:int = gc.getChildren(data).length;
    return data[gc.grouping.label] + “(” + childCount + “)”;
    }
    instead of showing the group label of grouped item I want to show the other columns value..[eg am showing id field , instead want to show the name for that id field]

  53. Hi Sameer,

    Great example, thanks!
    Jay on March 20, 2008 had asked how you can place the checkbox in a different column in an ADG and I had a similar question, but with the functionality that you currently have implemented for the three states.

    Basically, exactly the same functionality you have already but just moving the checkboxes to a different column and having the tree in the first column (and maintaining the parent/child checkbox relationship).

    Any help would be awesome…thank you so much.
    Dan

    • Hi Dan,
      Good to see that you figured it out yourself. You can post that sample for others to see.
      Let me know if you face any other issue.

  54. ha hi dude..,
    i want the same logic to be done but with the arraycollection as an dataprovider.. i mean by using the grouping fields..

  55. Hi Sameer,
    first of all I should thank you for this great control!
    I’m using it in my application. my data provider is an array collection (I have a flat data). and in the UI, user can add grouping to the data! my problem is that, we I select a parent(check the checkbox) the children don’t get notified and their state don’t change, or if a parent is selected and i deselect one of its children, the parent doesn’t get notified and its state doesn’t change!
    maybe it’s because my data provider is not hierarchical, so I need to change something in your code!

    I would appreciate your help,

    Thanks
    Gol

  56. Hi Sameer,
    I’m trying to give the user the ability to turn the checkboxes on and off! The following code is the function that I’m writing. getNodeModification() returns the attribute in xml report which says wether the checkboxes should be on or off! so I don’t actually know how to write the else part (i.e. when nodeModification == “off”).
    I tried setting groupItemRenderer to null, but this removed all of my groupings!! any suggestions?

    Thanks

    private function enableNodeModification()
    {
    var nodeModification:String = getNodeModification();
    if(nodeModification == “on”)
    {

    myADG.groupItemRenderer = new ClassFactory(CheckADGRenderer);

    }

    }

  57. So, what I understand is that you need to show the usual groupItemRenderer (the one with folder/leaf icon) if nodeModification is off.

    Try this –
    myADG.groupItemRenderer = new ClassFactory(mx.controls.advancedDataGridClasses.AdvancedDataGridGroupItemRenderer);

  58. hi
    sameer i am using ur ADGRenderer it is very nice and working fine for me. may data is in the form of objects so i made flat data and it is working fine for me say i had 3 entries in my ADG and i checked 2 of them and say delete it working fine but when i try to do with last entry after a server call and after deleting the entry when it comes to rerender the Advance Data Grid it is throwing an error
    in ADGRenderer at line no 211 that is
    super.measure(); i am not getting why it is happening
    please help thanks
    Sagar

  59. I have an adg hierarchical data with check box as itemrender in a separate column.I want to display/delete the checkbox on tree close/open .Is there any way to do ?

    • One way will be to use rendererProvider property of the AdvancedDataGrid and set it with the appropriate renderer in the ITEM_CLOSE event handler. In the ITEM_OPEN event handler, set the property to null.

      The other way will be to write a custom item renderer and handle the things their.

  60. Hi,

    Is it possible to lock the checkbox that will not user check or uncheck with certain criteria?

    Thanks in advance. πŸ™‚

    • Yes, you can achieve this. For example, you can have a property in the dataProvider and in the renderer disable the checkbox based on that

  61. I use a ArrayCollectionWithFilters as provider.
    And I specify for every item if it is checked or not(setting the Version field) and i want the parent category to be checked if all children are selected.

    I use GroupingCollection and I don’t know how to set check the grouping Object on creation of grid.

  62. Now I didn’t multiselection columns when check box click in advanced data grid in flex3.I want to do like gmail ,when check box click,that row selected and other click like that.But it is not yet okay now.I can’t find any source code like that in Internet and I can’t develop by myself.Help me!

    • Do you need to select the row on click of the checkbox, and keep on adding the checked rows to the selected rows?
      For this, you can set the selectedItems property of the AdvancedDataGrid in the renderer. You can access AdvancedDataGrid in the renderer through the listdata.owner property.

  63. Just wanted to post to say thx, been trying to make this myself from adobe itemrenderer examples all day, to no avail, i had to make some minor changes to my own code but all were asked/explained in the comments, thx again

  64. Hi

    I need to know if anybody knows how to extend the “AdvancedDataGridGroupItemRenderer” (the one with icon) in ADG

    to add another control like label/textbox etc

    Thanks in Advance for the reply

  65. Hi,

    I also use this great piece of code, but I have a problem:

    I need the checkboxes only in one layer. I tried to filter that in updateDisplayList method, but it works only randomly.
    To switch, I used this : AdvancedDataGridListData(super.listData).depth != 3 and I set myCheckBox.visible to false, if the condition is fullfilled. My DataProvider is a Grouping Collection. I also casted it to HierarchicalData, but I don’t think that there is the problem.

    Please help

    Piecko

    • Try using rendererProviders property in AdvancedDataGrid to set the renderer. You can set the depth and other properties there.

    • Hello again,

      one minute before giving up, I found the problem:

      I had to define an else-Function to explicitly say : myCheckBox.visible = true

      That’s it. I don’t know why it works, but it does πŸ˜‰

      Greatz to everybody

      Piecko

      P.S: Now it’s time for a beer πŸ˜‰

      • So, the renderers are recycled and reused. Thats why once the checkBox is set to visible=false, it’ll not show up again unless you set visible=true in some condition which now you are doing in the else part.

    • If you click the link, a page with the download option opens up. If that’s not the case with you, you can send me your e-mail address and I’ll forward the source.

  66. How to search in a tree of CheckBox .I need to search even the child node. Mine is 3 state tree of checkBox . Can anyone please help me.

    Thanks

  67. How to customize the treecolumn itemRenderer in advancedDataGrid. Becuase first column is being used for the navigation button in advancedDataGrid. But i have the my custom itemrenderer in first column so advancedDataGrid is displaying the only navigation button without rendering the my itemrenderer. It looks like it is using its internal itemrenderer.

  68. ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
    at flash.display::DisplayObjectContainer/getChildIndex()
    at mx.managers::SystemManager/getChildIndex()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:1652]
    at mx.managers::SystemManager/mouseDownHandler()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:3439]

    Am getting the above message when i run the application.

  69. King Raja – I’ve got it working in Flex 4.6, my only issue (as with others) was changing the @state to state, and adding adg.dataProvider.refresh(); as others have stated for use with a flat grouping collection.

  70. Hi Sameer, not sure if can respond now, i found this example as I was searching for similar kind, and implemented by changing few things, it works fine locally. But when kept in actual data from DB, after grouping , when we click on the expanding buttons , it wont expand for the children.
    any know issues experienced from your side, using this implementation

  71. Hi,

    this example is working perfectly. i am facing one issue. if child row has progressbar, it is showing group row also. i want to fix it asap. example i have A,B is the group. a1,a2 is the child of the A group. i have added progressbar into a1,a2 but progressbar showing in A group row also.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s