Oct
19

DataGrid Weirdness With Checkboxes

Posted by Aaron West at 11:50 AM in Flex

DataGrid's are cool, but yeash I've run into a lot of problems with them. I've put together two *real simple* online demonstrations that illustrate the behavior I'm seeing with a grid. I'd love for someone more experienced to check out these two examples and offer any insight or solution.

http://www.aaronwest.net/flex/gridexample/DataGridExample1.html
This is a simple grid that uses a custom Checkbox item renderer written in AS3. Clicking the submit button will display whether or not each Checkbox is selected. Make some changes to the boxes, de-selecting a few or an entire column and then click the submit button to see the selected value. The Alert box usually displays the right info the first time through, but after you've gone through a few rounds of selecting and de-selecting some of the boxes it will not show you the correct true/false value of each box.

http://www.aaronwest.net/flex/gridexample/DataGridExample2.html
This is another simple grid that is the same as the previous one only with more rows of data to make the DataGrid scroll. De-select the first "Group Owner" Checkbox (row 1 with the ID = 12) and then click use the grid scroll bar to scroll up and down. As you scroll, other Checkboxes are selected and deselected at random.

Incidentally, if you right-click the DataGridExample1 movie you can view the source to see what I'm doing.

Aaron West's Gravatar
About this post:

This entry was posted by Aaron West on October 19, 2006 at 11:50 AM. It was filed in the following categories: Flex. It has been viewed 39496 times and has 31 comments.

1 related blog entries

31 Responses to DataGrid Weirdness With Checkboxes

  1. joshuajnoble

    I ran into a lot of similar problems in Flex 1.5 and I hoped that it would go away in Flex 2, sad to see that it hasn't. We used to do things like hide the datagrid, write all the data to an array, clear the datagrid and then repopulate the grid from the array. Sucky.

  2. Bryan

    Could this be an IE issue? I submitted multiple times and never saw a problem.

  3. No, I'm using Firefox. If you change the selection on one Checkbox and then view the results you typically won't have any problems. It's when you select an entire column or several Checkboxes where the issue becomes really easy to replicate. It also helps if you select the boxes quickly - although I have replicated this by selecting one box, waiting 2 seconds, selecting the second, etc. etc.

  4. Campbell

    Looks like a data binding issue to me. Maybe a fixe is to iterate over the actual Datagrid rows rather than the dataprovider. I know i know its sorta a hack but if it solves your problem today.... On occasions I have seen binding not doing updates to the bound data source when changing focus to diferent controls (ie the alert box), but I have not found the problem to be consistant. if you add an click handeler to you datagrid and TRACE off the values rather than Alert.show i think you will find that the datasource reflects the changes.....ushally does for me.

  5. JesterXL

    Yo G, this should help!

    <a href="http://www.jessewarden.com/archives/2006/10/checkb...;

  6. PhilFlash

    See more itemRenderer for DataGrid:

    IconRenderer, BackgroundColorRenderer, CheckBoxRenderer:
    http://philflash.inway.fr/flex/dgsimple

    CheckBoxRenderer, ComboBoxRenderer, ColorPickerRenderer:
    http://philflash.inway.fr/flex/dgRendererSimple

    Philippe

  7. Derrick Grigg

    Hey Aaron, here's a sample to address the filtering problem I think you were having <a href="http://www.dgrigg.com/post/DataGrid-ItemRenderer-w...;. Hope this helps.

  8. If you are using a CheckBox as an itemRenderer in a DataGrid and you expect it to change your underlying dataProvider, be sure that you have editable=&quot;true&quot; on the column rendererIsEditor=true and editorDataField=&quot;selected&quot;. Without these settings, when a CheckBox's selected property changes, you are not actually affecting the underlying dataProvider. If you set this itemRenderer to also be an editor, then the DataGrid automatically updates your data (similar to the default TextInput itemEditor of a DataGrid column). This will also solve your issue of scrolling and losing your selection.

    For more info on itemRenderers and recycling rows, the best article I know of is by Alex Harui on http://blogs.adobe.com/aharui. Search for his articles on itemRenderers.

  9. Jorge

    Did you know how insert HSlider components inside a Datagrid?

  10. @Jorge - You need to create an item renderer (using the ItemRenderer tag or equivalent ActionScript) inside one of your data grid cells. You configure the item render so it behaves like a Flex component or your own custom component (in your case the HSlider).

    Here's some additional information that should help you get started. Both links are to Adobe Flex live docs:

    http://tinyurl.com/4xz76d
    http://tinyurl.com/4axywy

  11. chandana

    Hi..

    i am facing the same problem with datagrid scroll and checkbox renderers..
    if possible can u post the solution.

    Thanks

  12. @chandana I never solved the problem I had. Several folks offered suggestions - some mentioned in the comments above - but none solved the problem 100%. I wound up using a different solution than a DataGrid with ItemRenderers. One of these days I plan to try the same type of implementation and see how I make out. Since Flex 3 is out, the problem may be more difficult to replicate or fixed altogether.

  13. Mina Sadek

    override protected function clickHandler(event:MouseEvent):void {
    do not override this function. If you want to override it call the parent one
    "super.clickHandler(event)"

  14. Thomas

    Thanks a lot Aaron for your DataGrid/Checkboxes solution. After few changes it worked instantly in my Flex 3 app.
    I'm very new to Flex programming so please let me ask two (maybe simple) questions regarding your example:
    1. How can I center the Checkboxes inside the column?
    2. How can I change the font size in the DataGrid? (I used Strings instead of Integers but I think that doesn't matter)
    Thanks in advance.

  15. WebGyver: I was having the same issues, needing to bind this puppy to XML instead of the ArrayCollection in the example. I headdesked for a while until I realized that, duh, the XML value is going to be a string and not a boolean, so I had to edit the mxml to test for whatever string in the XML meant true and what meant false. Ive put the new code up for your (or anyone elses) perusal.

  16. Arivuindia

    Hi Thomas,
    To make checkbox center, override the updateDisplayList function in renderer file

       override protected function updateDisplayList(w:Number, h:Number):void
       {
          super.updateDisplayList(w, h);

          if (listData is DataGridListData)
          {
             var n:int = numChildren;
             for (var i:int = 0; i < n; i++)
             {
                var c:DisplayObject = getChildAt(i);
                if (!(c is TextField))
                {
                   c.x = (w - c.width) / 2;
                   c.y = 0;
                }
             }
          }
       }

  17. In my case I solved this problem, the cause : i was using in the DataGridColumn the propperty dataField="CONFIRM" and my Webservice was sending "COFIRM" then the ArrayCollection was using COFIRM (N missed) instead CONFIRM too, when I solved this the problem gone...

  18. Scott

    I had the same problem and I found that it was happening
    when my dataprovider value representing the checkbox was
    not initialized to eiter true or false. In debugging it was showing
    up as undefined.
    I now set the value to false every time I add a row and there
    are no more strange scrolling problems

  19. Thanks for the tip Scott. I think its good practice to set all checkboxes to false to begin with.

  20. vin

    Hi Alex,


    I have created a check box item renderer for my datgrid.
    I will update the arraycollection by checking or unchecking
    the checkbox. I will submit the data to backend and I will assign the
    dataprovider with updated dataprovider. My data is getting
    updated but the some checkboxes are appearing as checked.
    They are not getting reinitialized.

    Can any body help me solve this issue.Its urgent

    Thanks
    vin

    thanks in advance
    vin

  21. Hissam

    I had problem with the List.
    in my item-renderer there was an image which i used to hide when the item is selected
    so when I scroll after selecting an item, one of the image of the coming renderes
    used to be invisible.
    It bugged me a alot but then I do the following in the item-renderer code

    override public function set data(value:Object):void
             {
                super.data=value;
                foldername.text= value.@name;
                
                if(this.owner is MyList){
                   var o:Object=(this.owner as MyList).SelectedData;
                   if(o!=value){
                      btnArrow.visible=true;
                   }else btnArrow.visible=false;
                }
             }
    //explanation

    1. MyList is my list component simply just extending List.
    2. I defined a variable
    var SelectedData:Object in MyList.
    which stores the data of the currently selected item.

  22. Panagiotis Kammas

    Hello Aaron,

    I am having the exact same problem you had in 2nd example

    I am using Flex 3.2

    Would you like to share with me the workaround you did?

  23. @ Panagiotis - I never actually fixed my grid. I wound up taking a different route altogether. That said, I know there is a solution to the problem and I believe there are several examples in the comments that address the issue. It's all about state management and I was missing something in my code + item renderer.

  24. Chris

    Check out page 192, "Flex 3 In Action"

  25. Mitch

    Thanks for this page Aaron...a painful, time consuming process, but I finally found a working solution using the examples posted here.

  26. darrin

    I just used validateNow() on the datagrid after the dataprovider for the datagrid is refreshed. seemed to do it for me.

  27. Ken

    I fixed it by adding the selected property to my checkbox:

    <mx:CheckBox id="chk" click="chk_click(event)" selected="{data.selected}" />

    I added an artificial property to my dataProvider objects called "selected" and set that in the chk_click function:

    data.selected = chk.selected;

  28. Ty

    Darrin,

    Thanks for chiming in. Your tip was a lifesaver. I had a complex ItemRenderer that was causing problems for the entire DataGrid anytime it had to scroll. Rows would start overlapping each other and the view generally became trashed the more the user scrolled. Added the validateNow() to the dataChange handler of the DataGrid and all seems to be working well.

  29. Monica

    Hallo, I am very new to flex and I am not following 100% on what I should do when I get the problem where you select options submit it and then the grid still displays selected boxes after you removed the once that you submitted. Problem is the same one vin had "I have created a check box item renderer for my datgrid.
    I will update the arraycollection by checking or unchecking
    the checkbox. I will submit the data to backend and I will assign the
    dataprovider with updated dataprovider. My data is getting
    updated but the some checkboxes are appearing as checked." will it be possible for someone to explain to me in dummy terms how to fix it.

  30. @artwitto

    Hi, I tried to use the recommendations you gave in this post, but as a noob, I've failed :( -it's kind of a consolation that even the experts have the same problem-. I once fixed a similar problem that I encounter in a DateField in a DataGrid (using SDK 3.2 and 3.6), and I solved by using this code:

    MXML:

    <mx:DataGridColumn headerText="Programa" dataField="programa" textAlign="left" editable="false"                        width="188" wordWrap="true"/>
    <mx:DataGridColumn headerText="Fecha Ingreso" dataField="fechaIngProg" width="100" editable="true"
                                   rendererIsEditor="true">
                                  <mx:itemRenderer>
                                        <mx:Component>
                                           <mx:DateField change="outerDocument.changingDateField(event)" yearNavigationEnabled="true"
                                           dayNames="['D', 'L', 'M', 'M', 'J', 'V', 'S']" monthNames="['Enero', 'Febrero', 'Marzo', 'Abril',
                                   'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre']" color="#760D0D"
                                   fontWeight="bold" textAlign="center"/>
                                        </mx:Component>
                                     </mx:itemRenderer>
                               </mx:DataGridColumn>


    Script:

    public function changingDateField(e:CalendarLayoutChangeEvent):void
             {
                var fila:Object = new Object;
                var indice:int = myArrayCollection.getItemIndex(myDG.selectedItem);
                
                fila.cuentaprograma = myDG.selectedItem.cuentaprograma;
                fila.cveprog = myDG.selectedItem.cveprog;
                fila.destino = myDG.selectedItem.destino;
                /* fila.fechaIngProg = Number(e.newDate.month+1)+"/"e.newDate.date+"/"+e.newDate.fullYear; */
                fila.fechaIngProg = e.currentTarget.selectedDate;
                fila.FedEst = myDG.selectedItem.FedEst;
                fila.idct = myDG.selectedItem.idct;
                fila.meta = myDG.selectedItem.meta;
                fila.monto = myDG.selectedItem.monto;
                fila.orden = myDG.selectedItem.orden;
                fila.programa = myDG.selectedItem.programa;
                
                myArrayCollection.setItemAt(fila,indice);
                myArrayCollection.refresh();
             
             }

    ------------------------------

    Sorry for the annoying code, but maybe this could be useful.

    I'll try the same for my checkbox issue, hoping it works.

  31. @artwitto

    The "outerdocument" is necessary if you have your AS code outside your main mxml.
    (I have an ActionScript file named 'sesion1.as'). That's why I needed the outerdocument declaration.

    Please, just ignore the first DataGrid column in the MXML code.

    I a few words, you just need to "call" your entire ArrayCollection in order to load your checkboxes properly once you have selected/unselected them.