2 Replies Latest reply on Nov 18, 2010 10:35 AM by alinator11

    Access inline RadioButton within itemRenderer in a DataGrid

    glen08

      I have a RadioButton column in a DataGrid. I added the RadioButtons in this way:

       

      <mx:DataGrid id="dg" x="0" y="25" width="510" height="260" selectedIndex="0" dataProvider="{department.prof}" showHeaders="false" itemClick="handleClick(event);" >
            <mx:columns>
                <mx:DataGridColumn headerText="Selection" dataField="selection" width="75" >
                     <mx:itemRenderer>
                            <mx:Component>
                                   <mx:VBox>
                                       <mx:RadioButton id="rb" />
                                   </mx:VBox>
                            </mx:Component >
                     </mx:itemRenderer>
                </mx:DataGridColumn>

       

                //Other <mx:DataGridColumn> go here. Their inline components' contents are provided with the dataProvider="{department.prof}"

           </mx:columns>

      </mx:DataGrid>

       

      I want the RadioButton in the clicked row is selected and others are unselected using the handleClick(event) function:

       

      private function handleClick(event:ListEvent):void {

              var s:Object = event.itemRenderer.data['name']; // dataProvider is a mx:Model in XML form and there is a <name> sub element under <prof>
              Alert.show(event.rowIndex + " clicked "+s['last']); // I can access the String content in <last>
             
              // How do I access all the RadioButton in the DataGrid? I do not have a key

              // (event.itemRenderer.data['Selection'] as RadioButton).selected = true; this is NOT working as 'Selection' is just a Column title, not a key.
              // the RadioButton id 'rb' is also NOT working: rb[event.rowIndex].selected = true;
          }

       

      <?xml version="1.0"?>
      <department>
        <prof>
          <name>
            <first>Mike</first>
            <last>Smith</last>
          </name>

         </prof>

          .....

      </department>

       

      I also tried a RadioButtonGroup for all the RadioButton's in different rows, but it does not work.

      Thanks for any suggestions...

        • 1. Re: Access inline RadioButton within itemRenderer in a DataGrid
          alinator11 Level 2

          For these kinds of things, I separate the code out more. You could create another object where you create all your radio buttons as the DataGrid needs them. Add a method to the Object that allows you to retrieve the correct radio button from the List and then set it as selected or not selected based on what row you have identified that should change.

           

          I do this with DataGroups a lot. For instance, if I have a scroller where I have a bunch of items that have custom renderers, I build all custom items individually in AS (or MXML and AS), store them in ArrayLists and then I tell the object that created them to update them whenever I need to. This will cause for some more coding, but it solves the problem and once you've done it once, you should be able to reuse.

           

          Here is an example of an item renderer where I do what you are trying to do:

          <?xml version="1.0" encoding="utf-8"?>
          <s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
                          xmlns:s="library://ns.adobe.com/flex/spark"
                          xmlns:mx="library://ns.adobe.com/flex/mx"
                          autoDrawBackground="true">
             
              <fx:Script>
                  <![CDATA[
                      private var isChecked:Boolean = false;
                      private var imageHeight:uint = 75;
                      private var imageWidth:uint = 100;
                      private var videoID:String;
                      private var cbLabel:String;
                     
                     
                      public function getIsChecked():Boolean {
                          return isChecked;
                      }
                      /**
                       * You can use this if need to from outside. This
                       * object also checks and unchecks itself.
                       * **/
                      public function setIsChecked(isChecked:Boolean):void {
                          this.isChecked = isChecked;
                          fcvCheckBox.selected = isChecked;               
                      }
                     
                      public function setVidImage(vidImage:Image):void {
                          vidImage.height = getImageHeight();
                          vidImage.width = getImageWidth();
                      }
                     
                      public function getImageHeight():uint {
                          return imageHeight;
                      }
                     
                      public function getImageWidth():uint {
                          return imageWidth;
                      }
                     
                      public function setVideoID(videoID:String):void {
                          this.videoID = videoID;
                      }
                     
                      public function getVideoID():String {
                          return videoID;
                      }
                     
                      public function setCBLabel(cbLabel:String):void {
                          this.cbLabel = cbLabel;
                          fcvCheckBox.label = cbLabel;
                      }
                      public function getCBLabel():String {
                          return cbLabel;
                      }
                     
                      public function setVidTitle(vidTitle:String):void {
                          fcvVidTitle.text = vidTitle;
                          fcvVidTitle.toolTip = vidTitle;
                      }
                     
                      public function setVidDescription(vidDescript:String):void {
                          fcvVidDescript.text = vidDescript;
                          fcvVidDescript.toolTip = vidDescript;
                      }
                     
                      private function updateChecked():void {
                          this.isChecked = fcvCheckBox.selected;
                      }
                  ]]>
              </fx:Script>
             
              <s:HGroup>
                  <mx:Image id="fcvVidImage"
                             height="{getImageHeight()}"
                             width="{getImageWidth()}"/>
                  <s:Label id="fcvVidTitle"
                           text=""
                           width = "80"/>
                  <s:TextArea id="fcvVidDescript"
                              editable="false"
                              width="80"
                              height="{getImageHeight()}"
                              />
                  <s:CheckBox id="fcvCheckBox"
                              label="{getCBLabel()}"
                              click="{updateChecked()}"/>
                 
              </s:HGroup>
             
          </s:ItemRenderer>

           

          Here is me adding the renderer to a Scroller:

           

                  public function setPanelData(panelData:ArrayList,
                                               checkBoxLabel:String                                    
                                               ):FeedConfigVideoScroller{           
                      videoScroller = new FeedConfigVideoScroller();
                      for(var i:uint = 0; i < panelData.length; i++) {
                          var o:Object = panelData.getItemAt(i);
                          var videoID:String = String(o.videoId);
                          var videoTitle:String = String (o.videoTitle);
                          var videoDescript:String = String(o.descript);
                          var posterURL:String = String(o.posterURL);
                         
                          var fcvLayout:FeedConfigVidLayout = new FeedConfigVidLayout();
                          fcvLayout.setVideoID(videoID);
                          var image:Image = new Image();
                          image.source = posterURL;
                          fcvLayout.setVidImage(image);
                          fcvLayout.setCBLabel(checkBoxLabel);
                          fcvLayout.setIsChecked(false);
                          fcvLayout.setVidTitle(videoTitle);
                          fcvLayout.setVidDescription(videoDescript);
                          videoScroller.addFCVLayoutComp(fcvLayout);
                      }           
                      return videoScroller;
                  }

           

          Now, because I've used OO and I've added all renderers to an ArrayList, I can get down to the individual components any time I like and do anything to them that I want.

          • 2. Re: Access inline RadioButton within itemRenderer in a DataGrid
            alinator11 Level 2

            BTW, here is the code where I add the data to the ArrrayList which I am then able to get into later. One of the things you could do as well is to pass the parent object to the custom renderer. Then if someone clicks the item in the renderer, call back to the parent and tell the parent which item was clicked. Like so:

             

            class Parent() {

             

            var child:Child = new Child();

            child.setParent(this);

             

            public function registerClick(itemID:int):void {

            //do whatever

            }

             

            }

             

            class Child() {

             

            var parent:Parent;

             

            public function setParent(parent:Parnet):void {

            this.parent = parent;

            }

             

            private function clickListener(event:Event):void {

            parent.registerClick(this.customIntID);

            }

            }

             

            Of course you can make your ID's anything you like. I generally make mine the position of the component within the ArrayList.