Question

I have a grid table that contains ship objects(data provider accepts a array collection of ships objects) and displays just the name of ship and date in the grid table. My ship object has a property called checkList a boolean value, To be used as data binding in my checkbox item renderer.(To make the check box ,tick and untick)

I want to check my checkbox when I add a Image object in to a container. The Image object that is being added to the container has a id. I want to match that Image id to my shipId in the data grid table and check the check box for that particular record.

So my Image object listens to the add event and so when the Image object is added to a container. It calls the addHandler() function where it gets the id of the image and the loops though the data grid table to find the matching id and check the CheckBox. My looping works nicely.Using Alert.show() I can see that it matches the id and sets the boolean value to, true for the check box to be ticked. However the check box is not ticked.

These are my codes. Even though the checkList property for that particular record is set to true. The check box is not ticked. I dont Know whats the problem is. I am a student and new to flex.Can some one pls help me ?

My MXML view: My Grid Table

<s:DataGrid id="arrivalTable" x="-1" y="-1" width="302" height="205" requestedRowCount="4" 
                dataProvider="{myArrivalShips}" >               
        <s:columns>
            <s:ArrayList>                   
                <s:GridColumn dataField="shipName" headerText="Arrival Ships" itemRenderer="DesignItemRenderer.myCustomToolTipRenderer" width="130" ></s:GridColumn>
                <s:GridColumn dataField="ETA" headerText="ETD" itemRenderer="DesignItemRenderer.myCheckBoxRenderer"></s:GridColumn>                                                         
            </s:ArrayList>                  
        </s:columns>                
    </s:DataGrid>

My Image object listens add event.

displayImg.addEventListener(FlexEvent.ADD,addHandler);

This is my addHandler() event Function:

protected function addHandler(event:FlexEvent):void
{
    var ImageShipId:String = Image(event.currentTarget).id;             
    var destination:BorderContainer = Image(event.currentTarget).owner as BorderContainer;
    var destinationId:String = destination.id;          

    if( destinationId == "bct_HoldingArea" ){

        for(var j:int = 0; j<arrivalTable.dataProvider.length; j++){

            var myShip:Ship = arrivalTable.dataProvider.getItemAt(j) as Ship;
            var myShipId:String = myShip.shipID.toString();

            if(StringUtil.trim(myShipId) == StringUtil.trim(ImageShipId)){                          
                myShip.checkList = true;
                Alert.show("The ship name : " + myShip.shipName +"\n" + "The Ship selected : " + myShip.checkList);
            }
        }           
    }               
}

My check Box Item renderer :

<s:GridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                xmlns:s="library://ns.adobe.com/flex/spark" 
                xmlns:mx="library://ns.adobe.com/flex/mx" clipAndEnableScrolling="true">    
<s:HGroup>
    <s:Label text="{data.ETD}"  paddingTop="8"/>        
    <s:CheckBox id="myCheckBox" enabled="false" selected="{data.checkList}"  />
</s:HGroup> 

Was it helpful?

Solution

You should use "refresh" method of the dataprovider after updating an object:

(arrivalTable.dataProvider as ArrayCollection).refresh();

So your function will look like this:

protected function addHandler(event:FlexEvent):void
{
var ImageShipId:String = Image(event.currentTarget).id;             
var destination:BorderContainer = Image(event.currentTarget).owner as BorderContainer;
var destinationId:String = destination.id;          

if( destinationId == "bct_HoldingArea" ){

    for(var j:int = 0; j<arrivalTable.dataProvider.length; j++){

        var myShip:Ship = arrivalTable.dataProvider.getItemAt(j) as Ship;
        var myShipId:String = myShip.shipID.toString();

        if(StringUtil.trim(myShipId) == StringUtil.trim(ImageShipId)){                          
            myShip.checkList = true;

            (arrivalTable.dataProvider as ArrayCollection).refresh();

            Alert.show("The ship name : " + myShip.shipName +"\n" + "The Ship selected : " + myShip.checkList);
        }
    }           
}               
}

//EDIT The issue with the row in the middle seems to be a so called "middle row bug". I have found some info here.

To avoid this strange thing try to change your Renderer code in this way:

<?xml version="1.0" encoding="utf-8"?>
<s:GridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                xmlns:s="library://ns.adobe.com/flex/spark" 
                xmlns:mx="library://ns.adobe.com/flex/mx" clipAndEnableScrolling="true">   
<fx:Script>
    <![CDATA[
        import mx.utils.ObjectUtil;

        [Bindable]override public function get data():Object
        {
            return ObjectUtil.copy(super.data);;
        }

        override public function set data(value:Object):void
        {
            super.data = value;
        }

    ]]>
</fx:Script>

<s:HGroup>
    <s:Label text="{data.ETD}"  paddingTop="8"/>
    <s:CheckBox id="myCheckBox" enabled="false" selected="{data.checkList}"/>
</s:HGroup> 
</s:GridItemRenderer>

//EDIT

A short explanation of this trick: I have found that data update occurs for every row except the middle one. I have tried to follow the source code of the data grid. I think the code line responsible for this action is:

renderer.data = dataItem;

in the GridLayout.as class.

This line causes data update for each row except the middle one. Why? Flex compares both sides of this expression and does nothing if they are equal. In our case they are not equal but it seems to be a real bug. Whatever... We need to wait till Flex team correct the issue.

As a temporary workaround I have changed the left side of the expression brutally by clonning the Object in the "get" function. So the comparison should now return FALSE in any case and the data property should be updated for each row.

The set function could be deleted, but it is a good place for debugging of same issues.

It is not a good approach but it is better than nothing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top