In a previous example, “Displaying RadioButton controls using the Repeater in Flex”, we saw how you could use a Repeater in MXML to display a series of Flex RadioButton controls based on a data provider.
The following example shows how you can create a Repeater using ActionScript to accomplish the same thing.
Full code after the jump.
I’m not saying that creating a Repeater using ActionScript is the best/preferred/pretty way of doing this, but it is just one of many solutions.
<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2008/05/28/displaying-radiobutton-controls-using-the-repeater-in-flex-redux/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:comps="comps.*"
layout="vertical"
verticalAlign="middle"
backgroundColor="white">
<comps:MyComp />
</mx:Application>
/**
* http://blog.flexexamples.com/2008/05/28/displaying-radiobutton-controls-using-the-repeater-in-flex-redux/
*/
package comps {
import flash.events.Event;
import mx.containers.ApplicationControlBar;
import mx.containers.Canvas;
import mx.containers.Form;
import mx.containers.FormItem;
import mx.containers.HBox;
import mx.controls.Alert;
import mx.controls.Label;
import mx.controls.RadioButton;
import mx.controls.RadioButtonGroup;
import mx.core.Application;
import mx.core.Repeater;
import mx.core.UIComponentDescriptor;
import mx.styles.CSSStyleDeclaration;
import mx.styles.StyleManager;
public class MyComp extends Canvas {
private var arr:Array;
private var appControlBar:ApplicationControlBar;
private var form:Form;
private var formItem:FormItem;
private var lbl:Label;
private var hBox:HBox;
private var radioGroup:RadioButtonGroup;
private var radioRepeater:Repeater;
public function MyComp() {
super();
init();
}
private function init():void {
var alertCSS:CSSStyleDeclaration;
alertCSS = StyleManager.getStyleDeclaration("Alert");
alertCSS.setStyle("backgroundAlpha", 0.8);
alertCSS.setStyle("backgroundColor", "black");
alertCSS.setStyle("borderAlpha", 0.8);
alertCSS.setStyle("borderColor", "black");
arr = [];
arr.push({label:"Red", data:"red"});
arr.push({label:"Orange", data:"haloOrange"});
arr.push({label:"Yellow", data:"yellow"});
arr.push({label:"Green", data:"haloGreen"});
arr.push({label:"Blue", data:"haloBlue"});
radioGroup = new RadioButtonGroup();
lbl = new Label();
formItem = new FormItem();
formItem.label = "selectedValue:";
formItem.addChild(lbl);
form = new Form();
form.styleName = "plain";
form.addChild(formItem);
appControlBar = new ApplicationControlBar();
appControlBar.dock = true;
appControlBar.addChild(form);
Application.application.addChildAt(appControlBar, 0);
hBox = new HBox();
hBox.setStyle("horizontalGap", 60);
addChild(hBox);
var descriptorProps:Object = {};
descriptorProps.type = RadioButton;
descriptorProps.document = this;
descriptorProps.propertiesFactory = radioPropFac;
descriptorProps.events = {change:"radioButton_change"};
var radioDescriptor:UIComponentDescriptor = new UIComponentDescriptor(descriptorProps);
radioRepeater = new Repeater();
radioRepeater.dataProvider = arr;
radioRepeater.childDescriptors = [radioDescriptor];
radioRepeater.initializeRepeater(hBox, true);
}
private function radioPropFac():Object {
var obj:Object = {};
obj.label = radioRepeater.currentItem.label;
obj.group = radioGroup;
return obj;
}
public function radioButton_change(evt:Event):void {
var radio:RadioButton = RadioButton(evt.currentTarget);
var item:Object = radio.getRepeaterItem();
var cssObj:CSSStyleDeclaration;
cssObj = StyleManager.getStyleDeclaration("Alert");
cssObj.setStyle("modalTransparencyColor", item.data);
cssObj.setStyle("themeColor", item.data);
Alert.show(item.label, "getRepeaterItem()");
callLater(updateSelectedValue, [evt]);
}
private function updateSelectedValue(evt:Event):void {
lbl.text = radioGroup.selectedValue.toString();
}
}
}
View source is enabled in the following example.





Completely unrelated to this post, but desperately needed. How can I build an item renderer for a dataGrid that evaluates a text string in a cell and changes the background color. If it is blank/null/undefined make it red, if else it has the text N/A, NA, or N\A make it amber, etc..
Steve Walker,
Perhaps a little crude, but this should work:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" verticalAlign="middle" backgroundColor="white"> <mx:Array id="arr"> <mx:Object label="San Francisco" population="776733" year="2000" /> <mx:Object label="San Jose" population="894943" year="2000" /> <mx:Object label="San Mateo" population="92482" year="2000" /> <mx:Object label="Daly City" year="2000" /> <mx:Object label="Pacifica" population="N/A" year="2000" /> <mx:Object label="Foster City" population="NA" year="2000" /> <mx:Object label="Redwood City" population="NA" year="2000" /> <mx:Object label="Fremont" population="" year="2000" /> </mx:Array> <mx:DataGrid id="dataGrid" dataProvider="{arr}"> <mx:columns> <mx:DataGridColumn dataField="label" /> <mx:DataGridColumn dataField="year" /> <mx:DataGridColumn dataField="population" itemRenderer="comps.CustomItemRenderer" /> </mx:columns> </mx:DataGrid> </mx:Application>comps/CustomItemRenderer.as:
package comps { import mx.controls.dataGridClasses.DataGridItemRenderer; public class CustomItemRenderer extends DataGridItemRenderer { override public function validateNow():void { super.validateNow(); if (data) { switch(data.population) { case undefined: case null: data.population = ""; case "": background = true; backgroundColor = 0xFF0000; break; case "N/A": case "N\A": case "NA": background = true; backgroundColor = 0xFFFF00; break; default: background = false; backgroundColor = 0xFFFFFF; break; } } } } }Peter
For more great posts on item renderers, check out Alex Harui’s blog at http://blogs.adobe.com/aharui/, and more specifically, http://blogs.adobe.com/aharui/item_renderers/.
Thank you.
I combined the example you placed above with the one from the site you referenced and it works like a charm. I really appreciate all your assistance. I have one more problem related to this and it is how to use a wildcard in the evaluation of the string. Thanks to the ingenuity of lazy people, the data that I have has 30 or more variations of UNKNOWN (e.g. UNK, UNK101, UNK2, UNKOWN, etc) and I would like the renderer to match anything that starts with UNK. Is it possible?
Steve Walker,
Not sure if this would work with the switch statement, but it may give you a starting point:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" verticalAlign="middle" backgroundColor="white"> <mx:Array id="arr"> <mx:Object label="UNKNOWN" /> <mx:Object label="UNK" /> <mx:Object label="UnK101" /> <mx:Object label="Porridge" /> <mx:Object label="UNK2" /> <mx:Object label="Pineapples" /> </mx:Array> <mx:Script> <![CDATA[ import mx.controls.dataGridClasses.DataGridColumn; private function isUnknown(value:String):Boolean { return value.search(/UNK/i) == 0; } private function labelFunc(item:Object, col:DataGridColumn):String { if (isUnknown(item.label)) { return "yes"; } else { return "no"; } } ]]> </mx:Script> <mx:DataGrid id="dataGrid" dataProvider="{arr}"> <mx:columns> <mx:DataGridColumn dataField="label" headerText="label:" /> <mx:DataGridColumn labelFunction="labelFunc" headerText="UNKNOWN:" /> </mx:columns> </mx:DataGrid> </mx:Application>Peter
You could also do something like the following (using the
indexOf()instead of thesearch()method):private function isUnknown(value:String):Boolean { return value.indexOf("UNK") == 0; }Although the
indexOf()method would perform a case sensitive search instead of our clever case insensitive search using thesearch()method.Peter
Once again, thank you.