Search code examples
actionscript-3apache-flexdatagriditemrenderer

Flex: Simulating a click on a button inside an item renderer of a data grid


I'm using a data grid with an item renderer that creates a toggle button. The idea is to have a list of items and only allow one to be selected and pre-select one at start.

I've got the single button selection working, meaning that when I click on on toggle button, the others are deselected.

My problem is to create a way of pre-selecting an element of the data grid or simulate a click on a row and selecting the corresponding toggle button.

If I use the datagrid.selectedIndex the result is a selection but the toggle button doesn't get selected.

Here is the code example

In this example I am using the array value "selected" to define selected button, not my favourite solution but the one that worked first.

The array collection:

public static const ValuesList : ArrayCollection = new ArrayCollection(
    [
    {ID:0, Name:"One", selected:false},
    {ID:1, Name:"Two",       selected:false},
    {ID:2, Name:"Three",         selected:false},
    {ID:3, Name:"Four",  selected:false}
    ]
);

The data grid:

<s:DataGrid id="dataGrid" dataProvider={ValuesList} >
 <s:columns>
    <s:ArrayList>
        <s:GridColumn id="GridCol0" />
        <s:GridColumn id="GridCol1" />
        <s:GridColumn id="GridCol2" itemRenderer = "detail_ItemRenderer" />
    </s:ArrayList>
 </s:columns>
</s:DataGrid>

The column item renderer:

<?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.events.FlexEvent;

        /**
         * Creatioon complete event handler to set toggle button content value.
         * */
        protected function MyToggleButton_creationCompleteHandler(event:FlexEvent) : void
        {
            MyListToggleButton.label = data.Name;
            MyToggleButton.selected = data.selected;
        }

        /**
         * One of the only function that are called on item interaction.
         * */
        override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
        {
            super.updateDisplayList(unscaledWidth,unscaledHeight);
            MyToggleButton.selected = data.selected;
        }
    ]]>
</fx:Script>

<s:ToggleButton id="MyToggleButton" width="100%" height="100%"
                creationComplete="MyToggleButton_creationCompleteHandler(event)" />

</s:GridItemRenderer>

SOLUTION:

Using the data array to pass information into the Toggle button. Setting one value to "true" will display the selected element.

To insure data integrity I advise to set the selected index of the grid to the corresponding index of the value set to "true":

public function SetSelectedIndexByName() : int
{
for (var i : int=0; i < dataGrid.dataProvider.length ; i++)
{
    if (dataGrid.dataProvider[i].toString().toUpperCase() == "TRUE")
    {
        return i;
    }
}
return -1;
 }

Solution

  • In your GridItemRenderer, you should overwrite the setter of data. Your data will contain a variable defining the selection of the ToggleButton. In the setter you will be able to toggle the button based on this variable.

    To have only one button selected, you may use a static variable in your renderer which stores the selected itemrenderer. This one is simpler but not really clean since it's a matter of data, not renderers. So you may listen for any change in the dataProvider from a higher level and ensure there's only one item selected.