FlexyBoz
FlexyBoz

Reputation: 195

When Scrolling my checkBox in itemRenderer is checked/unchecked

This is my application:


<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark">

    <s:layout>
        <s:VerticalLayout/>
    </s:layout>

    <fx:Script>
        <![CDATA[
            import mx.collections.XMLListCollection;
            import mx.controls.Alert;
            import mx.events.FlexEvent;

            import spark.components.gridClasses.IGridItemRenderer;

            public var modulesXMLList:XMLListCollection;

            private function onGridInitialize(event:FlexEvent):void{
                this.addEventListener('moduleItemChange', onModuleItemChange);
            }

            private function onModuleItemChange(event:Event):void{
                var item:IGridItemRenderer = event.target as IGridItemRenderer;

                if(!item || !item.data) 
                    //item.data.access = !item.data.access;
                    Alert.show(item.data.sub_module);    
            }

            protected function controlPanel_Datagrid_creationCompleteHandler(event:FlexEvent):void
            {
                modulesXMLList = new XMLListCollection(tempXML.module as XMLList);

                modulesXMLList.refresh();
                myDatagrid.dataProvider = modulesXMLList;

            }

        ]]>
    </fx:Script>

    <fx:Declarations>

        <s:RadioButtonGroup id="rbg1"/>
        <fx:XML id="tempXML" source="assets/myXMl1.xml"/>

        <!--<s:ArrayCollection id="moduleControlPanel_DP">
            <fx:Object habilitations_id ="1" module_id="4" sub_module="Sub1" default="false" access="true"/>
            <fx:Object habilitations_id ="1" module_id="4" sub_module="Sub2" default="false" access="true"/>
            <fx:Object habilitations_id ="1" module_id="4" sub_module="Sub3" default="false" access="true"/>
            <fx:Object habilitations_id ="1" module_id="4" sub_module="Sub4" default="true" access="true"/>
            <fx:Object habilitations_id ="1" module_id="4" sub_module="Sub5" default="false" access="true"/>
            <fx:Object habilitations_id ="1" module_id="4" sub_module="Sub6" default="false" access="true"/>
            <fx:Object habilitations_id ="1" module_id="4" sub_module="Sub7" default="true" access="true"/>
            <fx:Object habilitations_id ="1" module_id="4" sub_module="Sub8" default="false" access="true"/>
            <fx:Object habilitations_id ="1" module_id="4" sub_module="Sub9" default="false" access="true"/>
            <fx:Object habilitations_id ="1" module_id="4" sub_module="Sub11" default="true" access="true"/>
            <fx:Object habilitations_id ="1" module_id="4" sub_module="Sub11" default="true" access="true"/>
        </s:ArrayCollection>
        -->
    </fx:Declarations>


    <s:DataGrid id="myDatagrid" creationComplete="controlPanel_Datagrid_creationCompleteHandler(event)" rowHeight="35" fontSize="9"  
                x="20" y="20" width="184" height="176">
        <s:columns>
            <s:ArrayList>                   
                <s:GridColumn headerText="Default">
                    <s:itemRenderer>
                        <fx:Component>
                            <s:GridItemRenderer>
                                <s:RadioButton name="yoyo" group="{outerDocument.rbg1}" selected="@{data.default}" label="" horizontalCenter="0"/>
                            </s:GridItemRenderer>
                        </fx:Component>
                    </s:itemRenderer>
                </s:GridColumn> 
                <s:GridColumn headerText="Access" dataField="@access">
                    <s:itemRenderer>
                        <fx:Component>
                            <s:GridItemRenderer>

                                <fx:Script>
                                    <![CDATA[

                                        override public function set data(value:Object):void
                                        {
                                            // not sure of the details on when or why, but sometimes this method is passed a null value
                                            if(value != null)
                                            {
                                                //super.data = value;
                                                // set itemRenderer's state based on data value
                                                //chk.selected = value.access;
                                                super.data = value;
                                                validateNow();
                                            }
                                        }

                                        protected function Check_clickHandler(even:MouseEvent):void
                                        {

                                            dispatchEvent(new Event('moduleItemChange', true));
                                        }  
                                    ]]>
                                </fx:Script>

                                <s:CheckBox id="chk" click="Check_clickHandler(event)" label="" selected="@{data.access}" horizontalCenter="0"/>
                            </s:GridItemRenderer>
                        </fx:Component>
                    </s:itemRenderer>
                </s:GridColumn>
                <s:GridColumn headerText="Sub-Module" dataField="@sub_module" />
            </s:ArrayList>
        </s:columns>
    </s:DataGrid>

</s:Application>



And this my C<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark">

    <s:layout>
        <s:VerticalLayout/>
    </s:layout>

    <fx:Script>
        <![CDATA[
            import mx.collections.XMLListCollection;
            import mx.controls.Alert;
            import mx.events.FlexEvent;

            import spark.components.gridClasses.IGridItemRenderer;

            public var modulesXMLList:XMLListCollection;

            private function onGridInitialize(event:FlexEvent):void{
                this.addEventListener('moduleItemChange', onModuleItemChange);
            }

            private function onModuleItemChange(event:Event):void{
                var item:IGridItemRenderer = event.target as IGridItemRenderer;

                if(!item || !item.data) 
                    //item.data.access = !item.data.access;
                    Alert.show(item.data.sub_module);    
            }

            protected function controlPanel_Datagrid_creationCompleteHandler(event:FlexEvent):void
            {
                modulesXMLList = new XMLListCollection(tempXML.module as XMLList);

                modulesXMLList.refresh();
                myDatagrid.dataProvider = modulesXMLList;

            }

        ]]>
    </fx:Script>

    <fx:Declarations>

        <s:RadioButtonGroup id="rbg1"/>
        <fx:XML id="tempXML" source="assets/myXMl1.xml"/>

        <!--<s:ArrayCollection id="moduleControlPanel_DP">
            <fx:Object habilitations_id ="1" module_id="4" sub_module="Sub1" default="false" access="true"/>
            <fx:Object habilitations_id ="1" module_id="4" sub_module="Sub2" default="false" access="true"/>
            <fx:Object habilitations_id ="1" module_id="4" sub_module="Sub3" default="false" access="true"/>
            <fx:Object habilitations_id ="1" module_id="4" sub_module="Sub4" default="true" access="true"/>
            <fx:Object habilitations_id ="1" module_id="4" sub_module="Sub5" default="false" access="true"/>
            <fx:Object habilitations_id ="1" module_id="4" sub_module="Sub6" default="false" access="true"/>
            <fx:Object habilitations_id ="1" module_id="4" sub_module="Sub7" default="true" access="true"/>
            <fx:Object habilitations_id ="1" module_id="4" sub_module="Sub8" default="false" access="true"/>
            <fx:Object habilitations_id ="1" module_id="4" sub_module="Sub9" default="false" access="true"/>
            <fx:Object habilitations_id ="1" module_id="4" sub_module="Sub11" default="true" access="true"/>
            <fx:Object habilitations_id ="1" module_id="4" sub_module="Sub11" default="true" access="true"/>
        </s:ArrayCollection>
        -->
    </fx:Declarations>


    <s:DataGrid id="myDatagrid" creationComplete="controlPanel_Datagrid_creationCompleteHandler(event)" rowHeight="35" fontSize="9"  
                x="20" y="20" width="184" height="176">
        <s:columns>
            <s:ArrayList>                   
                <s:GridColumn headerText="Default">
                    <s:itemRenderer>
                        <fx:Component>
                            <s:GridItemRenderer>
                                <s:RadioButton name="yoyo" group="{outerDocument.rbg1}" selected="@{data.default}" label="" horizontalCenter="0"/>
                            </s:GridItemRenderer>
                        </fx:Component>
                    </s:itemRenderer>
                </s:GridColumn> 
                <s:GridColumn headerText="Access" dataField="@access">
                    <s:itemRenderer>
                        <fx:Component>
                            <s:GridItemRenderer>

                                <fx:Script>
                                    <![CDATA[

                                        override public function set data(value:Object):void
                                        {
                                            // not sure of the details on when or why, but sometimes this method is passed a null value
                                            if(value != null)
                                            {
                                                //super.data = value;
                                                // set itemRenderer's state based on data value
                                                //chk.selected = value.access;
                                                super.data = value;
                                                validateNow();
                                            }
                                        }

                                        protected function Check_clickHandler(even:MouseEvent):void
                                        {

                                            dispatchEvent(new Event('moduleItemChange', true));
                                        }  
                                    ]]>
                                </fx:Script>

                                <s:CheckBox id="chk" click="Check_clickHandler(event)" label="" selected="@{data.access}" horizontalCenter="0"/>
                            </s:GridItemRenderer>
                        </fx:Component>
                    </s:itemRenderer>
                </s:GridColumn>
                <s:GridColumn headerText="Sub-Module" dataField="@sub_module" />
            </s:ArrayList>
        </s:columns>
    </s:DataGrid>

</s:Application>


And this is my XML file:

<?xml version="1.0" encoding="UTF-8"?>

<modules>
    <module habilitation_id="1" module_id="1" sub_module="Sub1" default="true" access="true" />
    <module habilitation_id="1" module_id="2" sub_module="Sub2" default="true" access="true" />
    <module habilitation_id="1" module_id="2" sub_module="Sub3" default="false" access="false" />
    <module habilitation_id="1" module_id="2" sub_module="Sub4" default="false" access="true" />
    <module habilitation_id="1" module_id="3" sub_module="Sub5" default="true" access="true" />
    <module habilitation_id="1" module_id="3" sub_module="Sub6" default="false" access="true" />
    <module habilitation_id="1" module_id="4" sub_module="Sub7" default="true" access="true" />
    <module habilitation_id="1" module_id="4" sub_module="Sub8" default="false" access="true" />
</modules>




Anyone please throw some lights.

Upvotes: 0

Views: 1192

Answers (2)

Soumen Choudhury
Soumen Choudhury

Reputation: 31

Just saw this post and seems you have not accepted any answer yet:

Your item renderer:

override public function set data(value:Object):void
{
    if(value != null)
    {
        super.data = value;
        //chk.selected = value.access;
        validateNow();
    }
}

Uncomment the above line : //chk.selected = value.access;

Flex DataGrid recycles its itemRenderers for better memory performance. When you check a CheckBox on an itemRenderer and start scrolling, that itemRenderer with the checked box is getting reused to display other records with the selected="true" value still set.

So you have to explicitly set the check box value. For this example if value.access is boolean and it is for checkbox it will definitely work.

Thanks.

Upvotes: 0

Bernesto
Bernesto

Reputation: 1436

This is a fun one. I ran into it a while back. Your item renderer is destroyed and reused as it scrolls off screen. Therefore it appears unselected. If I remember right, try binding your controls to a method in the renderer that updates their values to those in the data object. e.g. <s:checkbox selected={myMethod(data.selected)} /> or look for an update event on the renderer and set your values.

Upvotes: 0

Related Questions