28
May
08

Displaying RadioButton controls using the Repeater in Flex (redux)

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.

View MXML

<?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>

comps/MyComp.as

/**
 * 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.


7 Responses to “Displaying RadioButton controls using the Repeater in Flex (redux)”


  1. 1 Steve Walker May 29th, 2008 at 4:59 am

    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..

  2. 2 peterd May 29th, 2008 at 8:18 am

    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/.

  3. 3 Steve Walker May 29th, 2008 at 11:23 am

    Thank you.

  4. 4 Steve Walker May 29th, 2008 at 4:58 pm

    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?

  5. 5 peterd May 29th, 2008 at 6:06 pm

    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

  6. 6 peterd May 29th, 2008 at 6:12 pm

    You could also do something like the following (using the indexOf() instead of the search() 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 the search() method.

    Peter

  7. 7 Steve Walker May 30th, 2008 at 7:06 am

    Once again, thank you.

Leave a Reply

This blog is terrible at eating HTML tags. If you plan on posting code/XML, please escape your "<" characters as "&lt;" and your ">" characters as "&gt;".