Ever wanted icons to appear in the dropdown of a ComboBox? This article shows you how!
The Problem – No iconField/iconFunction support for ComboBox
Unlike the List component and all of its child classes, the ComboBox does *not* natively support an iconField/iconFunction capability to let you dynamically assign an icon for each element that it contains.
For some time I have wanted to display elements in a ComboBox with an associated icon to indicate state, like ‘this element is active’ vs. ‘this element is not active’. Well I invested the time in understanding ComboBox and have a fairly clean way of adding iconField/iconFunction support to ComboBox.
The solution lies in the fact that the actual dropdown you see when opening a ComboBox is really an instance of a List component. Since List supports the iconField/iconFunction property, all I needed to do was get a handle to the dropdown and assign my own iconField/iconFunction values. The best way to demontrate this is to look at the example code.
Example Code – The ComboBoxUtil Class
There are a number of approaches you could take to add icon support behavior to a ComboBox. I opted for a stand-alone utility class thats lets you modify any existing ComboBox instance at runtime. Feel free to glean what you need from my class below to implement your own preferred pattern.
/**
* ComboBoxUtil
*
* Utility class for working with ComboBoxes
* @version $Id: $
* @author Mitch Coopet
*/
class utils.ComboBoxUtil {
/**
* Adds iconField support to a ComboBox
* @param cb The ComboBox reference you want to modify
* @param iconFunction A reference to the icon function you want to use
*/
public static function setIconField(cb:ComboBox, iconField:String) {
_setIcon(cb,iconField);
}
/**
* Adds iconFunction support to a ComboBox
* @param cb The ComboBox reference you want to modify
* @param iconFunction A reference to the icon function you want to use
*/
public static function setIconFunction(cb:ComboBox, iconFunction:Function) : Void {
_setIcon(cb,iconFunction);
}
/**
* Internal helper function to perform actual assignment of icon field/function
* support to a ComboBox
* @param cb The ComboBox reference you want to modify
* @param icon A String representing the icon field OR a Function representing
* the icon function to use.
*/
private static function _setIcon(cb:ComboBox,icon) : Void {
// We use a delegate to perform the assignment of the icon
// functionality because the combobox may/may not be rendering
var delegate = new Object();
delegate.createIcon = function () {
// This is the secret sauce - we get a handle
// to the actual dropdown instance. The dropdown is a
// List that appears when you 'open' a ComboBox.
// Since the List component supports iconField/iconFunction,
// all we need to do is set them on the dropdown instance!
var dropDown = cb.getDropdown();
if (icon instanceof Function) {
dropDown.iconFunction = icon;
} else {
dropDown.iconField = icon;
}
};
// Some bullet-proofing -
// If the ComboBox is 'initializing' the dropdown will be undefined.
// So we code around it by adding the delegate to the stack of
// methods that are called
// after the ComboBox is done initializing.
if (cb.initializing) {
cb.doLater(delegate,delegate.createIcon);
} else {
delegate.createIcon();
}
}
Example – Using ComboBoxUtil
For this code example demonstrating using ComboBoxUtil, assume I already have a ComboBox reference called ‘cb’ and 2 symbols in my library called ‘iconOn’ and ‘iconOff’.
// Set the iconFunction
// You could easily just pass in a String denoting the name of a property
// that contains the icon to use, i.e. utils.ComboBoxUtil.setIconField(cb,"myIcon");
utils.ComboBoxUtil.setIconFunction(cb,getIcon);
// Assign the data provider
cb.dataProvider = [
{ label:"element 1 - off", data:0 },
{ label:"element 2 - on", data:1 }
];
/*
* This icon function returns the appropriate icon based on
* the 'data' property of an object. If data == 0, it returns
* 'iconOff', otherwise it returns 'iconOn'.
*/
function getIcon(item) : String {
return item.data == 0?'iconOff':'iconOn';
}
Posted by mcoopet 