Search code examples
actionscript-3apache-flexflex3mxml

Using RadioButton with RadioButtonGroup in a DataGridColumn (in a quiz application)


I am having some issues to properly use several RadioButton components along with a RadioButtonGroup in my quiz application (when they are rendered via ItemRenderer under DataGridColumn).

The quiz page displays a question along with 4 possible answers which represented by RadioButton components (tied with a unique RadioButtonGroup). A quiz usually contains many multiple choice questions.

Everything works fine until I navigate to the next question and return to the previous question; then I could see my former answer selection in the radio button although when I change my answer and select a different radio button it keeps my old selection and add the new one, which is entirely unreasonable (since RadioButtonGroup should enforce selection of one option only).

Here is how I define the DataGridColumn:

<mx:DataGrid y="141" height="373" dataProvider="{currentQuestion.answers}" id="answersGrid" visible="false"  styleName="NoStyleDataGrid" useRollOver="false" headerHeight="0" width="381" x="461" variableRowHeight="true">           
          <mx:columns>                                
            <mx:DataGridColumn  width="20" dataField="key">
                <mx:itemRenderer>
                      <mx:Component>
                        <mx:Canvas width="100%" height="100%" verticalScrollPolicy="off" horizontalScrollPolicy="off" top="0">
                            <mx:Script>
                                <![CDATA[
                                    import mx.core.Application;
                                ]]>
                            </mx:Script>

                            <mx:RadioButton id="rb" value="{data.number}" selected="{outerDocument.isSelected(data.number,rb)}"  group="{outerDocument.getGroup()}" click="outerDocument.setAnswerState(event,data.number)" width="100%" height="30" x="12" y="0" />                                

                        </mx:Canvas>                                    
                      </mx:Component>
                </mx:itemRenderer>
            </mx:DataGridColumn>

I make sure each question has its own unique Group to contain the RadioButton components (as answers) using this code:

        public function getGroup():RadioButtonGroup{                
            if(radioGroupMap[currentQuestion.key]!=null){                                       
                return radioGroupMap[currentQuestion.key] as RadioButtonGroup;                                      
            }                               
            radioGroupMap[currentQuestion.key] = new RadioButtonGroup();
            return radioGroupMap[currentQuestion.key] as RadioButtonGroup;
        }

This code works fine as long as I do not go to the next question and return to the previous one.

Appreciate any help on this issue.

Thanks!


Solution

  • After doing some research, it appears that item renderers containing RadioButtons along with RadioButtonGroup on data grid column are not a good design choice. Apparently more item renderers are created than actually needed due to performance reasons which makes the UI act in an unpredictable manner.

    I used VBOX instead and created the RadioButton along with the RadioButtonGroup dynamically using ActionScript. Here is some code example:

                function populateAnswers(){
                    var rbg:RadioButtonGroup = new RadioButtonGroup();
                    for each ( var ans:Answer in currentQuestion.answers){
                        var row:HBox = new HBox();
                        var rb:RadioButton = new RadioButton();
                        rb.group = rbg;
                        rb.id = ""+ans.number;
                        var num:int = ans.number;
                            rb.addEventListener(MouseEvent.CLICK,setAnswerState);
                    rb.selected = isSelected(ans.number);                       
                            row.addChild(rb);                       
    
                        var answerBoby:Text = new Text();
                        answerBoby.enabled = false;
                        answerBoby.styleName = "readOnlyTA";
                        answerBoby.selectable = false;
                        answerBoby.htmlText = ans.body;
                        row.addChild(answerBoby);
                        quizAnswersPanel.addChild(row);                     
    
                    }