Symmetri Developer Blog

June 23, 2009

Nulls in (Advanced)DataGrid column causes a column sort to throw RTE

Flash/Flex - By Shourov Bhattacharya

If an (Advanced)DataGrid has null values in the data provider, then sorting the associated column in the grid throws the following error:

Error: Cannot determine comparator for SortField with name ''XXX''.

Adobe already has a bug report: https://bugs.adobe.com/jira/browse/SDK-13808?actionOrder=desc.

There is a bit of discussion around this, with some people of the opinion that this is not really a bug - that it is the developer’s responsibility to ensure that either a) there are no nulls in the data or b) if there are, write your own sort compare function that handles the nulls. I call it a genuine bug in the Flex SDK; if my grid displays nulls, then it should know how to sort nulls as well - i.e. don’t tell me my data is valid when displaying but then not valid when sorting. Especially as there is an intuitive rule-of-thumb that could be used for sorting nulls of any data type (send them to the top of the ascending sort).

Probably the best workaround is to avoid the nulls in the first place. In my case, I couldn’t do that in the data source, so I did it in the item renderer:

package com.symmetri.skins
{
    import mx.controls.advancedDataGridClasses.*;
	
    public class ReportDataGridItemRenderer extends AdvancedDataGridItemRenderer
    {
        public function ReportDataGridItemRenderer()
        {
            super();
        }
	
         override public function validateNow():void
         {
             if ((listData) && (data))
             {
                  var _fieldName:String = AdvancedDataGridListData(listData).dataField;
                   var _value:String = String(data[AdvancedDataGridListData(listData).dataField]);
	
            //fill out null values with blanks
            if (data[AdvancedDataGridListData(listData).dataField] == null) data[AdvancedDataGridListData(listData).dataField] = ;
             }
	
             super.validateNow();
         }        
	
    }
}

Actually, I just though of something: does this approach have a shortcoming - will it work if not all rows in the data are rendered?

June 22, 2009

Flex bug when rendering AdvancedDataGrid with a small height

Flash/Flex - By Shourov Bhattacharya

I couldn’t find an Adobe bug report for this, so I might go ahead and log one. I have a number of AdvancedDataGrid components in my interface, and I have encountered a run-time error when resizing the interface. It appears to happen whenever one of the AdvancedDataGrid components is resized down to a very small size - less than about 40 pixels height. The error message is:

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at mx.controls::AdvancedDataGridBaseEx/drawColumnBackground()
[C:\work\flex\dmv_automation\projects\datavisualisation\src \mx\controls\AdvancedDataGridBaseEx.as:3483]

For a workaround, I first tried to capture the ResizeEvent.RESIZE event on the AdvancedDataGrid and then test for the height of the grid; I set visible=false and includeInLayout = false whenever the grid was too small:

public function checkGridOnResize(evt:ResizeEvent):void
        {
            var grid:AdvancedDataGrid = AdvancedDataGrid(evt.currentTarget);
	
            grid.visible = (grid.height < 50 ? true: false);
            grid.includeInLayout = grid.visible;
        }

However, I was surprised to see that this didn’t work. The RTE was still being thrown, and the AdvancedDataGridBaseEx.drawColumnBackground() method was still being called, even though the grid was invisible. So I had to extend the AdvancedDataGrid class and catch the error in an overload of the drawColumnBackground method:

package com.symmetri.skins
{
    import mx.controls.AdvancedDataGrid;
    import mx.controls.advancedDataGridClasses.AdvancedDataGridColumn;
    import mx.core.UIComponent;
	
    public class ReportDataGrid extends AdvancedDataGrid
    {
	
        public function ReportDataGrid()
        {
            super();
        }
	
        override protected function drawColumnBackground(s:Sprite, columnIndex:int, color:uint, column:AdvancedDataGridColumn):void
        {
            // this is done to handle a Flex bug
            // RTE thrown when rendering a grid smaller than about 40 pixels in height
            try
            {
                super.drawColumnBackground(s,columnIndex,color,column);
            }
            catch(e:Error) {}
        }
    }
}

Not the ideal solution, but the best we can do at this point. When (if) I get a spare moment, I will post the bug report for Adobe.

Get free blog up and running in minutes with Blogsome
Theme designed by Janis Joseph