Select to view content in your preferred language

Change ESRI flex sample from checkboxes into radiobuttons

1301
8
04-29-2010 07:37 AM
FranciscoDomingues
New Contributor
Hi all,
Trying to change the ESRI flex sample from checkboxes into radiobuttons I reach the point where I select the radiobutton layers and the layers activate correctly, but when I select another layer the previous checked one do not de-select.
Any tips where and what to change in the code?
Thanks!
Tags (2)
0 Kudos
8 Replies
PrashanthSukumaran
Emerging Contributor
It is treating the radio buttons as separate/individual radio buttons.  You need to assign a group name to the radio button.
By doing so you will have only one radiobutton selected at a time.

http://livedocs.adobe.com/flex/3/langref/mx/controls/RadioButtonGroup.html#includeExamplesSummary
0 Kudos
SebastianRoberts
Frequent Contributor
Did you get this to work?  I am trying to change the check boxes to radio buttons on one of my live maps widgets (sample LiveMapsWidgets).  Can you provide the code if you were able to do this?
0 Kudos
SebastianRoberts
Frequent Contributor
I was able to updatet the live maps widget to use radio buttons instead of checkboxes, and have one slider on the same pane as the radio buttons. This slider controls the currently chosen layer (images in my case). The one minor problem that I still have, is that I cannot format the radio button label text. It shows up transparent and faint. I tried setting the stlye to widget text radioBtn.setStyle ("textFormat","WidgetText"). I also tried creating my own TextFormat and applying that to the radio buttons. Anyone have any ideas? Below is my LiveMapsWidget.mxml.

(Note: if you try to use this code, I also added a setter function called layerToNone to the LayerAlpha.mxml that just sets the slider text to "none").

Sebastian Roberts
Nevada County, CA GIS

<?xml version="1.0" encoding="utf-8"?>
<!--
////////////////////////////////////////////////////////////////////////////////
//
// Copyright © 2008 - 2009 ESRI
//
// All rights reserved under the copyright laws of the United States.
// You may freely redistribute and use this software, with or
// without modification, provided you include the original copyright
// and use restrictions.  See use restrictions in the file:
// <install location>/FlexViewer/License.txt
//
////////////////////////////////////////////////////////////////////////////////
-->
<BaseWidget xmlns    ="com.esri.solutions.flexviewer.*" 
   xmlns:mx   ="http://www.adobe.com/2006/mxml" 
   xmlns:toccomp  ="com.esri.solutions.flexviewer.components.toc.*" 
   xmlns:widgets  ="com.esri.solutions.flexviewer.widgets.*"
   x     ="600" 
   y     ="300" 
   widgetConfigLoaded ="init()">
 
 
 <mx:Script>
  <![CDATA[
   import com.esri.ags.Map;
   import com.esri.ags.layers.GraphicsLayer;
   import com.esri.ags.layers.Layer;
   import com.esri.solutions.flexviewer.AppEvent;
   import com.esri.solutions.flexviewer.ConfigData;
   import com.esri.solutions.flexviewer.SiteContainer;
   import com.esri.solutions.flexviewer.components.toc.tocClasses.TocItem;
   import com.esri.solutions.flexviewer.utils.WidgetEffects;
   
   import mx.collections.*;
   import mx.controls.Alert;
   import mx.controls.RadioButton;
   import mx.events.ItemClickEvent;
   import mx.events.ListEvent;
   import mx.events.StateChangeEvent;

   
   //labels
   [Bindable]
   private var visibilityLabel:String;
   
   [Bindable]
   private var transparencyLabel:String;
   
   private var lArr:Array;
   
   private const ICON_URL:String = "com/esri/solutions/flexviewer/assets/images/icons/";
   
   private function init():void
   {
    if (configXML)
    {
     //labels
     visibilityLabel = configXML.labels.visibilitylabel || "Layer Visibility";
     transparencyLabel = configXML.labels.transparencylabel || "Layer Transparency";
    }
    
    lArr = getLayers();
    aLayerSlider.layerToNone = "Select an image, then this slider will adjust transparency";
    wTemplate.addTitlebarButton(ICON_URL + "i_folder.png", "Radio Buttons", showStateToggleLayers);
    var rBFormat:TextFormat = new TextFormat;
    rBFormat.font = "Arial";
    rBFormat.size = "11";
    rBFormat.color = "#FFFFFF";
    rBFormat.bold = true;
    for(var i:uint = 0; i < lArr.length; i++) 
    {
     var radioBtn:RadioButton = new RadioButton;
     radioBtn.groupName = "radioBtnGroup";
     radioBtn.label = lArr.name;
     radioBtn.setStyle("textFormat","rBFormat");
     radioBtn.value = i;
     radioBtn.alpha = 1
     radioBtn.height = 14
     vBoxRadio.addChild(radioBtn);
     
    }
    //add a button for "none", ie no layer to be displayed
    var radioBtn:RadioButton = new RadioButton;
    radioBtn.groupName = "radioBtnGroup";
    radioBtn.value = lArr.length;
    radioBtn.label = "None";
    vBoxRadio.addChild(radioBtn);
    radioBtn.setStyle("textFormat","rBFormat");
    
    //set the current selection to the "none" button
    radioBtnGroup.selectedValue = lArr.length;
   }  
   
   private function getLayers():Array
   {
    var basemapCount:Number = configData.configBasemaps.length;
    var layerArray:Array = [];
    for (var i:Number = map.layerIds.length -1; i >= basemapCount; i--)
    {
     var layer:Layer = map.getLayer(map.layerIds);
     //change this to exclude any layers from the live map widgets.
     if (!(layer is GraphicsLayer) && (layer.name!= "Supervisor Districts") && (layer.name!= "Schools & Fire Stations"))
      layerArray.push(layer);
    }
    return layerArray;
   }
   
   private function showStateToggleLayers(event:MouseEvent):void
   {
    WidgetEffects.flipWidget(this, viewStack, "selectedIndex", 0, 400);
   }
   
   private function radioClickHandler(event:ItemClickEvent):void
   {
    //if no layer is selected, then set the slider text appropriately.
    if (event.index == lArr.length){
     aLayerSlider.layerToNone = "Select an image, then this slider will adjust transparency"; 
    }
    // update the visible layers to only show the layer selected
    for(var i:uint = 0; i < lArr.length; i++) 
    {
     if (lArr.name == event.label){
      map.getLayer(lArr.name).visible = true;
      var lay:Layer = map.getLayer(lArr.name);
      aLayerSlider.layer = lay;
      
     }else{
      map.getLayer(lArr.name).visible = false;
     }  
    }
   }
   
  ]]>
 </mx:Script>
 
 <WidgetTemplate id="wTemplate">
  <mx:ViewStack id="viewStack" width="100%" height="200%" creationPolicy="all">
   <mx:VBox id="vBoxRadio" width="100%" height="200%" horizontalScrollPolicy="off" verticalScrollPolicy="off">
    <mx:Label text="Choose an Image" styleName="WidgetText" width="100%"/>
     <mx:RadioButtonGroup id="radioBtnGroup" itemClick="radioClickHandler(event)"/>
     <widgets:LayerAlpha id="aLayerSlider"/>
   </mx:VBox>
  </mx:ViewStack>
 </WidgetTemplate>
</BaseWidget>
0 Kudos
SandeepTalasila
Occasional Contributor
Hi,
Have any one tried to implement this in flex viewer 2.1? If so could you help me. I was trying to figure out but no luck yet.
Thanks,
0 Kudos
SandeepTalasila
Occasional Contributor
Hi,
I was trying to implement radio buttons in the layer list instead of check boxes in Flex Viewer 2.1. I have made some changes in my LayerListWidget.mxml. I am not getting any results(see image). Probably my code is a blunder. could anyone please let me know how to make this work. Thanks for the help.
<?xml version="1.0" encoding="utf-8"?>
<!--
     ////////////////////////////////////////////////////////////////////////////////
     //
     // Copyright (c) 2010 ESRI
     //
     // All rights reserved under the copyright laws of the United States.
     // You may freely redistribute and use this software, with or
     // without modification, provided you include the original copyright
     // and use restrictions.  See use restrictions in the file:
     // <install location>/License.txt
     //
     ////////////////////////////////////////////////////////////////////////////////
-->
<viewer:BaseWidget xmlns:fx="http://ns.adobe.com/mxml/2009"
                   xmlns:s="library://ns.adobe.com/flex/spark"
                   xmlns:mx="library://ns.adobe.com/flex/mx"
                   xmlns:viewer="com.esri.viewer.*"
                   xmlns:toc="com.esri.viewer.components.toc.*"
                   x="600" y="400"
                   widgetConfigLoaded="init()">
    <fx:Script>
        <![CDATA[
   import com.esri.ags.layers.Layer;
   import mx.collections.ArrayCollection;
   import mx.events.StateChangeEvent;
   import spark.components.RadioButton;
   

            [Bindable]
            private var title:String;
     private var layers:ArrayCollection;
  
     private function init():void
            {
             toc.map = map;
                toc.isMapServiceOnly = false; //gotta get this from the config file
                toc.excludeLayers = getExcludeLayers();
                toc.excludeGraphicsLayers = true;

                if (configXML)
                {
                    title = configXML.labels.title || "Map Layer List";
                }
    var rBFormat:TextFormat = new TextFormat;
    rBFormat.font = "Arial";
    rBFormat.size = "11";
    rBFormat.color = "#000000";
    rBFormat.bold = true;
    for (var i:uint = 0; i < layers.length; i++)
    {
                                        radioBtn.groupName = "radioBtnGroup";
     radioBtn.label = layers.name;
     radioBtn.setStyle("textFormat","rBFormat");
     radioBtn.value = i;
     radioBtn.alpha = 1
     radioBtn.height = 14
    }
    var radioBtn:RadioButton = new RadioButton;
    radioBtn.groupName = "radioBtnGroup";
    radioBtn.value = layers.length;
    radioBtn.label = "None";
    radioBtn.setStyle("textFormat","rBFormat");
    
    //set the current selection to the "none" button
    radioBtnGroup.selected = layers.length;
    
            }

            private function getExcludeLayers():ArrayCollection
            {
                var result:ArrayCollection = new ArrayCollection();

                if (configData && configData.basemaps)
                {
                    // exclude basemaps
                    for (var i:int = 0; i < configData.basemaps.length; i++)
                    {
                        result.addItem(configData.basemaps.label);
                    }
                }

                if (configXML)
                {
                    // exclude these layers
                    var layers:XMLList = configXML.excludelayer as XMLList;
                    for (var j:Number = 0; j < layers.length(); j++)
                    {
                        result.addItem(layers.toString());
                    }
                }

                return result;
            }
   
     private function showStateToggleLayers(event:MouseEvent):void
     {
  viewStack.selectedIndex = 0;
     }
   
     private function radioClickHandler(event:ItemClickEvent):void
     {
  // update the visible layers to only show the layer selected
  for(var i:uint = 0; i < layers.length; i++) 
  {
   if (layers.name == event.label){
    map.getLayer(layers.name).visible = true;
    var lay:Layer = map.getLayer(layers.name);
            
   }else{
    map.getLayer(layers.name).visible = false;
   }  
  }
     }
   
    ]]>
    </fx:Script>
    <viewer:WidgetTemplate id="wTemplate" width="300" height="300">
  <viewer:layout>
            <s:VerticalLayout gap="8" paddingTop="15"/>
        </viewer:layout>
        <s:Label text="{title}"/>
  <toc:TOC id="toc" width="100%" height="100%"/>
  <s:RadioButton id="radioBtnGroup" />
  <mx:ViewStack id="viewStack" width="100%" height="100%" creationPolicy="all" paddingTop="4" />
    </viewer:WidgetTemplate>
</viewer:BaseWidget>

0 Kudos
SarahBell
Esri Contributor
Hey! I was able to change the appearance of the buttons to be radio buttons. At the end of this solution, I also have a big question/need for help.

How to make radio buttons in the TOC:

First I switched out any of the checkbox icons, skins, imports, and extensions in the "CheckBoxScaleDependantIcon.as" and the "CheckBoxScaleDependant.as" to RadioButton elements. This turned all the buttons into radio buttons.

So in "CheckBoxScaleDependantIcon.as" I deleted
import mx.skins.halo.CheckBoxIcon;

and replaced it with
import mx.skins.halo.RadioButtonIcon;

And in "CheckBoxScaleDependant.as" I replaced the Checkbox imported items with:

import mx.controls.RadioButton;
import mx.skins.halo.RadioButtonIcon;


It's important that you remove any imports of checkbox items.

Last Change: change the following in "CheckBoxScaleDependant.as":

setStyle("icon", CheckBoxIcon);
to

setStyle("icon", RadioButtonIcon);

The radio buttons needed two clicks to appear "on", even though their data was rendered on the map. To fix this, I located the if (data is Tocitem() statement in the "TocItemRenderer.as" file. Here I deleted the
_checkbox.selected = item.visible; property. Great! Now the radio buttons themselves are acting like radio buttons. But I have a huge problem.

The map layers that each radio button turns on will stay on even when I click another radio button. If you have any suggestions to fix this, please reply! Thanks!
0 Kudos
SebastianRoberts
Frequent Contributor
Sarah,
  I haven't used the TOC, so I am not sure how it manages the layers, but in my widget that uses radio buttons, I just put the layers in an array, and then in the radio click handler I turn all layers off that don't correspond to the click event.

Putting all the operational layers that exist in the main config.xml file into an array:
   private function getLayers():void
   {
    if (configData && configData.opLayers){
     for (var i:int=0; i< configData.opLayers.length; i++)
     {
     layerArray.addItem(configData.opLayers.label);
     } 
    }

  
excluding any layers listed as exclude in the widget's config file
private function excludeLayers(): void
   {
    if (configXML){
     // exclude these layers
     var layers:XMLList = configXML..excludelayer as XMLList;
     for (var j:Number = 0; j < layers.length(); j++){
      for(var i:int=0; i< layerArray.length; i++){
       if(layerArray == layers){
        layerArray.removeItemAt(i);
       }
      }
     }
    }
   }



create radio buttons:
for(var i:uint = 0; i < layerArray.length; i++) 
    {
     radioBtn = new RadioButton;
     radioBtn.groupName = "radioBtnGroup";
     radioBtn.label = layerArray;
     radioBtn.styleName = "WidgetText";
     radioBtn.value = i;
     radioBtn.height = 18
     radioBtn.setStyle("textRollOverColor","#D0D0D0 ")
     vBoxRadio.addChild(radioBtn);
     
    }

radio click handler:
   private function radioClickHandler(event:ItemClickEvent):void
   {
    // update the visible layers to only show the layer selected
    for(var i:uint = 0; i < layerArray.length; i++) 
    {
     if (layerArray == event.label){
      map.getLayer(layerArray).visible = true;
     }else{
      map.getLayer(layerArray).visible = false;
     }  
    }
   }
0 Kudos
SarahBell
Esri Contributor
Thanks for the reply, Sebastian. I will give it a try!

Sarah
0 Kudos