Tips & Tricks – adding a combobox to a datagrid header as headerRenderer
I am sure many of you would have tried dropping a ComboBox as a headerRenderer to a DataGrid. Well, if you try to directly drop in a ComboBox you will get an RTE and the ComboBox just doesn’t work! I got this request from one of the flex users here that they need to drop a ComboBox on a datagridcolumn to provide a UI for filtering the data in the datagrid.
After looking at the code for a while, I figured out that the set data method of the combobox checks if it is dropped in as an itemRenderer and what’s more, it sets the data irrespective of whether the value recieved in the set data is a datagrid column or not. In the case of dropping the ComboBox, the data setter sets the data to the DataGridColumn and when the program progresses it throws an RTE which says it couldnt find the property name on the headerRenderer instance.
The solution:
I subclassed the ComboBox control to make MyComboBox and wrote an override for the data Setter. I just added the following type check before the data setter in the super is called
if(value is DataGridColumn)
{
//do not call super; that is it!!
}
else
{
super.data = value
}
Thats pretty much it! The ComboBox will now correctly display in the header. I have written a simple example that has a ComboBox on the Datagrid column header which can be used to filter data. Note: I have turned off sortable columns and draggable columns in this example.
Disclaimer: This sample contains a small example of the concept, the application in itself has not been tested for bugs. People copy pasting the whole code and urged to exercise Download Source








June 7, 2007 - 1:24 pm
Wow ! great piece of code. U r my guru FlexGeek !
June 7, 2007 - 1:28 pm
August 1, 2007 - 6:51 pm
Hey, this is cool! Do you have suggestions on how to create a headerRenderer that is a comboBox but also allows the user to sort the columns?
August 17, 2007 - 11:00 am
Hi,
I try your sample using Flex Builder 3 beta and after running it, it spit out the following error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at mx.controls::DataGrid/mx.controls:DataGrid::focusInHandler()
at [focusEvent]
at flash.display::Stage/set focus()
at mx.core::UIComponent/setFocus()
at mx.controls::ComboBase/setFocus()
at mx.managers::FocusManager/setFocus()
at mx.managers::FocusManager/private::mouseDownHandler()
at [mouseEvent]
August 17, 2007 - 11:02 am
Sorry, I forgot to mention when it happened. It happened after I click on “active” from the Filter option. I try to follow the sample by using other controls like LinkButton etc, but so far only Text is working. The rest of the controls will spit out the same error message.
September 17, 2007 - 6:24 am
Just like Bob, I want to create a headerRenderer that is a comboBox but also allows the user to sort the columns. Can you help?
September 18, 2007 - 12:12 pm
There seems to be something missing since dragging the columns around causes errors. Not quite ready yet… But cool, none the less!
October 16, 2007 - 7:22 pm
Is it possible to create a header render for the scrollbar of a datagrid? Thanks!
July 16, 2008 - 3:05 am
The links are broken
Can you update them please?
August 19, 2008 - 8:27 pm
the linsk are all broken ,. can you please update or fix them .. thanks
September 4, 2008 - 9:58 am
please update this entry. I’m not able to view this example.
September 21, 2008 - 6:57 am
I am not able to use the link…its broken. Kindly update the link
October 2, 2008 - 1:29 am
This is the *really* annoying thing about blogs – how often do you see a really good blog spoilt by broken links and authors that never bother to check commentt or feedback. This article is *exactly* what I’m looking for so I’m really disappointed the links are *still* broken.
June 16, 2009 - 4:25 pm
This one worked for me – http://omalraj.com/2009/06/flex-datagrid-header-with-a-combobox-filter/
September 23, 2009 - 1:49 pm
Thanks! I was getting an error trying to use a CheckBox as a headerRenderer in an AdvancedDataGridColumn, and this worked.
December 29, 2009 - 4:54 pm
hello,
i m just not able to solve this error… any help will be highly appreciated.
<![CDATA[
import mx.collections.ArrayCollection;
import mx.controls.dataGridClasses.DataGridColumn;
import mx.events.ListEvent;
import mx.formatters.DateFormatter;
import mx.rpc.events.ResultEvent;
[Bindable]
private var dataFields:ArrayCollection;
[Bindable]
private var dataProvider:ArrayCollection;
[Bindable]
private var selectedViewIndex:int = 0;
[Bindable]
private var _selectedIndex:Number = -1;
[Bindable]
private var addingRecord:Boolean;
private var dateFormatter:DateFormatter;
private const strNEW:String = "New";
private const ADD:String = "Add";
override protected function onResultHttpService(e:ResultEvent):void
{
dateFormatter = new DateFormatter();
dateFormatter.formatString = "MM/DD/YY";
var a:Array = xmlListToObjectArray(e.result.item);
dataProvider = new ArrayCollection(a);
// Get the values from properties XML.
a = properties.@dataFields.toString().split(",");
dataFields = new ArrayCollection(a);
var labels:Array = properties.@labels.toString().split(",");
field0Label.text = labels[0];
field1Label.text = labels[1];
field2Label.text = labels[2];
selectedIndex = 0;
if (properties.@selectedViewIndex.toString() != null&&
Number(properties.@selectedViewIndex) < (viewStack.numChildren – 1)) // Make sure the index is in range.
selectedViewIndex = Number(properties.@selectedViewIndex);
}
private function set selectedIndex(n:Number):void
{
addingRecord = false;
// Make sure we are within range of dataProvider.
if (n (dataProvider.length – 1))
n = 0;
var item:Object = dataProvider.getItemAt(n);
field0Input.text = item[dataFields[0]];
field1Input.selectedDate = item[dataFields[1]];
field2Input.text = item[dataFields[2]];
_selectedIndex = n;
indexInput.text = String(n + 1);
}
private function get selectedIndex():Number
{
return _selectedIndex;
}
private function onClickDeleteButton():void
{
dataProvider.removeItemAt(_selectedIndex);
if (dataProvider.length > 0)
selectedIndex = _selectedIndex;
}
private function saveData():void
{
var selectedItems:Object = dataProvider.getItemAt(_selectedIndex);
selectedItems[dataFields[0]] = field0Input.text;
selectedItems[dataFields[1]] = field1Input.selectedDate;
selectedItems[dataFields[2]] = field2Input.text;
}
private function onClickNewButton(e:MouseEvent):void
{
if (addingRecord) // Add the new record to dataProvider
{
// Generic object since the data field names are dictated by the xml.
var o:Object = new Object();
o[dataFields[0]] = field0Input.text;
o[dataFields[1]] = field1Input.selectedDate;
o[dataFields[2]] = field2Input.text;
dataProvider.addItem(o);
selectedIndex = dataProvider.length – 1;
addingRecord = false;
}
else // Clear out the fields for input.
{
field0Input.text = field1Input.text = field2Input.text = indexInput.text = “”;
addingRecord = true;
}
}
private function formatDate(item:Object, column:DataGridColumn):String
{
return dateFormatter.format(item[column.dataField]);
}
private function onChangeComboBox(e:ListEvent):void
{
saveData();
var index:int = ComboBox(e.target).selectedIndex
selectedViewIndex = index;
dispatchViewStackChange(index);
}
]]>
0}”
styleName=”leftArrowButton”
click=”saveData();selectedIndex-=1;” >
0}”
enter=”saveData();selectedIndex=Number(TextInput(event.currentTarget).text)-1;”
width=”30″/>
0}”
styleName=”rightArrowButton”
click=”saveData();selectedIndex+=1;”>
0}”
label=”Delete”
width = “65″
click=”onClickDeleteButton()”>
and i get the following error… pls help.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at com.esria.samples.dashboard.view::FormContent/saveData()[C:\Documents and Settings\testing\Desktop\flexProjects\dashboard\src\com\esria\samples\dashboard\view\FormContent.mxml:95]
at com.esria.samples.dashboard.view::FormContent/onChangeComboBox()[C:\Documents and Settings\testing\Desktop\flexProjects\dashboard\src\com\esria\samples\dashboard\view\FormContent.mxml:128]
at com.esria.samples.dashboard.view::FormContent/___FormContent_ComboBox1_change()[C:\Documents and Settings\testing\Desktop\flexProjects\dashboard\src\com\esria\samples\dashboard\view\FormContent.mxml:143]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()[E:\dev\gumbo_beta2\frameworks\projects\framework\src\mx\core\UIComponent.as:11749]
at mx.controls::ComboBox/dispatchChangeEvent()[E:\dev\gumbo_beta2\frameworks\projects\framework\src\mx\controls\ComboBox.as:1882]
at mx.controls::ComboBox/close()[E:\dev\gumbo_beta2\frameworks\projects\framework\src\mx\controls\ComboBox.as:1629]
at mx.controls::ComboBox/dropdown_changeHandler()[E:\dev\gumbo_beta2\frameworks\projects\framework\src\mx\controls\ComboBox.as:2140]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()[E:\dev\gumbo_beta2\frameworks\projects\framework\src\mx\core\UIComponent.as:11749]
at mx.controls.listClasses::ListBase/mouseUpHandler()[E:\dev\gumbo_beta2\frameworks\projects\framework\src\mx\controls\listClasses\ListBase.as:10156]
at mx.controls::List/mouseUpHandler()[E:\dev\gumbo_beta2\frameworks\projects\framework\src\mx\controls\List.as:2474]