The problem can be described as follows:
We have an ItemRenderer with a Button inside (Column in DataGrid with buttons doing something). We want these buttons to be visible/invisible depending on a specific column value in a row. DataGrid’s dataProvider is a database (mysql).
All we have to do to achieve this behavior is to extend ItemRenderer and override its function set data(value:Object):void;
Source can be downloaded here.
Create new ActionScript class (File->New->Action Script class):
package
{
    import mx.collections.IList;
    import mx.controls.DataGrid;
    import mx.controls.Label;
    import mx.controls.dataGridClasses.DataGridListData;
    import mx.controls.listClasses.BaseListData;
    import mx.controls.listClasses.ListBase;
    
    import spark.components.supportClasses.ItemRenderer;
    
    
    public class RowNumberItemRenderer extends mx.controls.dataGridClasses.MXDataGridItemRenderer
    {
        public var rowNumberFromItemRenderer;
        
        public function RowNumberItemRenderer()
        {
            super();
        }
        
        override public function set data(value:Object):void
        {
            super.data = value;
            
            rowNumberFromItemRenderer = String(IList(ListBase(listData.owner).dataProvider).getItemIndex(data));            
        }
    }
}
Change your ItemRenderer type to local:RowNumberItemRenderer;
<?xml version="1.0" encoding="utf-8"?>
<local:RowNumberItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                          xmlns:s="library://ns.adobe.com/flex/spark" 
                          xmlns:mx="library://ns.adobe.com/flex/mx" 
                          xmlns:local="*"
                          focusEnabled="true" width="70" height="20" initialize="mxdatagriditemrenderer1_initializeHandler(event)" alpha="0.75" toolTip="Force test to end here">
    <fx:Script>
        <![CDATA[
            import mx.controls.*;
            import mx.controls.Alert;
            import mx.controls.DataGrid;
            import mx.controls.dataGridClasses.DataGridListData;
            import mx.controls.listClasses.ListBase;
            import mx.core.Application;
            import mx.core.FlexGlobals;
            import mx.core.UIComponent;
            import mx.effects.*;
            import mx.events.EffectEvent;
            import mx.events.FlexEvent;
            import mx.utils.OnDemandEventDispatcher;
            import mx.utils.object_proxy;
            
            import services.testservice.TestService;
            
            public var buttonEndTest:spark.components.Button = null;
            
            protected function button1_clickHandler(event:MouseEvent):void
            {
                //not relevant here
            }
            
            
            protected function getDataGrid()
            {
                if (FlexGlobals.topLevelApplication.tabNavigator.selectedIndex == 1)
                { //today's tests
                    return FlexGlobals.topLevelApplication.dataGrid_todaysTests;    
                }
                else //running tests 
                {
                    return FlexGlobals.topLevelApplication.dataGrid;
                }
            }
            
            protected function getDataProvider()
            {
                if (FlexGlobals.topLevelApplication.tabNavigator.selectedIndex == 1)
                { //today's tests
                    return FlexGlobals.topLevelApplication.dataGrid_todaysTests.dataProvider;    
                }
                else //running tests 
                {
                    return FlexGlobals.topLevelApplication.dataGrid.dataProvider;
                }
            }
            protected function mxdatagriditemrenderer1_initializeHandler(event:FlexEvent):void
            {
                //not relevant here
            }
            protected function button1_creationCompleteHandler(event:FlexEvent):void
            {
                var buttonFromEvent:spark.components.Button = event.target as spark.components.Button;
                buttonEndTest = buttonFromEvent;
                
                var row_index_current:int = -1;
                row_index_current = int(rowNumberFromItemRenderer);
                
                //dataGrid is the id (name) of our dataGrid table
                var dataGrid = getDataGrid();
                var dataProvider = getDataProvider();
                var item = null;
                item = dataProvider.getItemAt(row_index_current);
                var testSTATUS = item.STATUS;
                if (testSTATUS == -1)
                {//failed
                    buttonFromEvent.visible = false;
                }
                else if (testSTATUS == 1)
                {//ok
                    buttonFromEvent.visible = false;
                }
                else
                {//running
                    //buttonFromEvent.visible = false;
                }   
            }
        ]]>
    </fx:Script>
    <mx:HBox>
        <s:Button x="8" y="-1" label="End test" click="button1_clickHandler(event)" fontWeight="bold" alpha="1" creationComplete="button1_creationCompleteHandler(event)"/>
    </mx:HBox>
</local:RowNumberItemRenderer>
 
i've done this with 100 rows and the buttons go out of their place
ReplyDelete@Anonymous
ReplyDeleteThis piece of code is part of a bigger system. Two weeks ago I had the same problem - didn't find the solution for misplacing buttons :/. In my case it was only when I did a refresh on the grid manually (I had a separate button which did that). No luck with this - sorry.
Why did you have to do this,
ReplyDeleterowNumberFromItemRenderer = String(IList(ListBase(listData.owner).dataProvider).getItemIndex(data));
when the "itemIndex" property in the ItemRenderer can itself give you the row number.