Select to view content in your preferred language

Access TOC from widget

2681
9
11-02-2011 09:13 AM
RavinHasseea
Emerging Contributor
I would like to change the TOC as follows:
1. Turn on a sub layer automatically from a separate widget
2. Switch off all sub layers when group layer is switched off
3. Switch on group layer automatically when a sub layer is turn on
4. Disable / Enable a TOC node from a separate widget

Is this feasible in the Flex Viewer?
Tags (2)
0 Kudos
9 Replies
FaizanTayyab
Deactivated User
I would like to change the TOC as follows:
1. Turn on a sub layer automatically from a separate widget
2. Switch off all sub layers when group layer is switched off
3. Switch on group layer automatically when a sub layer is turn on
4. Disable / Enable a TOC node from a separate widget

Is this feasible in the Flex Viewer?


Are you using the widget from the gallery for the TOC.

If you search the forums, you should be able to find a way to achieve the above.

I had to do something similar for creating a session save widget (saves user session to a file and allows sharing of sessions).

Code which helped me (again found from the forum search):

var visLayers:ArrayCollection = dmsl.visibleLayers;
var newVisLayer:ArrayCollection=new ArrayCollection(obj.visLyrs.visibleLayer);
for each(var j:int in newVisLayer){
AppEvent.dispatch(AppEvent.LAYER_VISIBILITY_CHANGED,j);
}


In TOCitem
public function TocItem( parentItem:TocItem = null )
{
 _parent = parentItem;
 //ViewerContainer.addEventListener(AppEvent.LAYER_VISIBILITY_CHANGED, updateCB);
 AppEvent.addListener(AppEvent.LAYER_VISIBILITY_CHANGED,updateCB);
}

private function updateCB(event:AppEvent):void
{
 if(this is TocLayerInfoItem)
            {
           var tli:TocLayerInfoItem = this as TocLayerInfoItem;
    
  if(tli.layerInfo.id == event.data){
   setVisibleDirect(_visible ? false : true);
  }
 }
0 Kudos
RavinHasseea
Emerging Contributor
Hi I have tried the suggested above. I turn on a layer from a widget. This works fine.

Then dispatch an event. The code setVisibleDirect(_visible ? false : true); is run
however, when I open the layerList widget, the checkbox for the layer is still not ticked.

Am I missing out something?


Thanks
0 Kudos
FaizanTayyab
Deactivated User
i modified the code as below to make it work but i had to do alot of other custom code in my widget, but this might give you some idea.

public function TocItem( parentItem:TocItem = null )
  {
   _parent = parentItem;
   AppEvent.addListener(AppEvent.LAYER_VISIBILITY_CHANGED,updateCB);
  }
  private function updateCB(event:AppEvent):void
  {
   var disObj:Object=event.data;
   //if(disObj.mainLayer!=null){
   
   if(this is TocLayerInfoItem)
   {
    var tli:TocLayerInfoItem = this as TocLayerInfoItem;
    if(tli.rootInfo.name==disObj.mainLayer || disObj.mainLayer==null){
    //var tmpLayer:ArcGISDynamicMapServiceLayer=disObj.mainLayer;
    if(tli.layerInfo.id == disObj.index){
     //this.preventPropogation=true;
     if(disObj.visibility==false){
      this.setVisibleDirect(false);
      //this.visible=false;
     }
     if(disObj.visibility==true){
      this.setVisibleDirect(true);
      //this.visible=true;
     }
     if(tli.isGroupLayer()){
      AppEvent.dispatch(AppEvent.VISIBLE_LAYERS_RETURNED,tli.layerInfo.id);
     }
    }
    }// end of mainlayer if
   }
   //}
   
  }
0 Kudos
RavinHasseea
Emerging Contributor
I would have thought it would quite common to switch on a layer without using the toc. But the solution isn't obvious. Below doesn't work. Any ideas??

layerlist contains sublayers to switch on..

for (var i:int = 0; i < layerList.length() - 1; i++)
     {
      var servicename:String = layerList.@service;
      var layerno:String = layerList.@layerno;
     
      var vizLayers:Array = new Array();
      vizLayers.push(layerno);
     
      for each (var layer:Layer in map.layers)
      {
       if(layer.name == servicename)
       {       
        var MapLayer: ArcGISDynamicMapServiceLayer = layer as ArcGISDynamicMapServiceLayer;
       
        MapLayer.visibleLayers = new ArrayCollection(vizLayers);
       
        var visLayers:ArrayCollection = MapLayer.visibleLayers;
       
        visLayers.addItem(layerno);
       
        MapLayer.visibleLayers = visLayers;
       
        MapLayer.refresh();
       }
      }
     

      var data:Object =
       {
        layerid: layerno,
        visibility: true
       }
     
      AppEvent.dispatch(AppEvent.LAYER_VISIBILITY_CHANGED,data);
    
     
     }

private function updateCheckBox(event:AppEvent):void
{

  if(this is TocLayerInfoItem)
  {
   var tli:TocLayerInfoItem = this as TocLayerInfoItem;
   var obj:Object=event.data;
  
   if(tli.layerInfo.id == obj.layerid)
   {
    if(obj.visibility == true)
    {
     this.setVisibleDirect(true); 
    }
   } 
  }
}

The required layers are switched on the map. But no change in TOC.
0 Kudos
RavinHasseea
Emerging Contributor
i modified the code as below to make it work but i had to do alot of other custom code in my widget, but this might give you some idea.

public function TocItem( parentItem:TocItem = null )
  {
   _parent = parentItem;
   AppEvent.addListener(AppEvent.LAYER_VISIBILITY_CHANGED,updateCB);
  }
  private function updateCB(event:AppEvent):void
  {
   var disObj:Object=event.data;
   //if(disObj.mainLayer!=null){
   
   if(this is TocLayerInfoItem)
   {
    var tli:TocLayerInfoItem = this as TocLayerInfoItem;
    if(tli.rootInfo.name==disObj.mainLayer || disObj.mainLayer==null){
    //var tmpLayer:ArcGISDynamicMapServiceLayer=disObj.mainLayer;
    if(tli.layerInfo.id == disObj.index){
     //this.preventPropogation=true;
     if(disObj.visibility==false){
      this.setVisibleDirect(false);
      //this.visible=false;
     }
     if(disObj.visibility==true){
      this.setVisibleDirect(true);
      //this.visible=true;
     }
     if(tli.isGroupLayer()){
      AppEvent.dispatch(AppEvent.VISIBLE_LAYERS_RETURNED,tli.layerInfo.id);
     }
    }
    }// end of mainlayer if
   }
   //}
   
  }


rockzZ25, I am trying to follow your suggestion above. How do you obtain rootInfo in
tli.rootInfo.name?
Also disObj.mainLayer?

Thanks
0 Kudos
FaizanTayyab
Deactivated User
I modified tocLayerInfoItem

////////////////////////////////////////////////////////////////////////////////
//
// Copyright � 2008 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
//
////////////////////////////////////////////////////////////////////////////////

package com.esri.viewer.components.toc.tocClasses
{
 
 import com.esri.ags.events.ExtentEvent;
 import com.esri.ags.layers.ArcGISDynamicMapServiceLayer;
 import com.esri.ags.layers.Layer;
 import com.esri.ags.layers.supportClasses.LayerInfo;
 import com.esri.viewer.ViewerContainer;

 /**
  * A TOC item representing a member layer of an ArcGIS or ArcIMS map service.
  * This includes group layers that contain other member layers.
  */
 public class TocLayerInfoItem extends TocItem
 {
  public function TocLayerInfoItem( parentItem:TocItem, layerInfo:LayerInfo,tLayer:Layer)
  {
   super(parentItem);
   // Added line below 
   _rootInfo=tLayer as ArcGISDynamicMapServiceLayer;
   
   _layerInfo = layerInfo;
   
   label = layerInfo.name;
   
   // Set the initial visibility without causing a layer refresh
   setVisible(layerInfo.defaultVisibility, false);
  
   ViewerContainer.getInstance().mapManager.map.addEventListener(ExtentEvent.EXTENT_CHANGE,checkExtent);
  }
  
  internal static const DEFAULT_MAX:Number = 0;
  
  private var _maxScale:Number = DEFAULT_MAX;
  
  public function set maxScale( value:Number ):void
  {
   _maxScale = value;
   this.scaledependant = true;
   
   if (_maxScale > 0 ){
    if ((ViewerContainer.getInstance().mapManager.map.scale >= _maxScale)){
     this.scaledependant = false;
    }
   } else if (_minScale > 0 ) {
    if ((ViewerContainer.getInstance().mapManager.map.scale <= _minScale)){
     this.scaledependant = false;
    }
   } else {
    this.scaledependant = false;
   }
  }
  
  public function get maxScale():Number
  {
   return _maxScale;
  }
  
  private function checkExtent(evt:ExtentEvent):void{
   this.scaledependant = true;
   if (_maxScale > 0 ){
    if ((ViewerContainer.getInstance().mapManager.map.scale >= _maxScale)){
     this.scaledependant = false;
    }
   } else if (_minScale > 0 ) {
    if ((ViewerContainer.getInstance().mapManager.map.scale <= _minScale)){
     this.scaledependant = false;
    }
   } else {
    this.scaledependant = false;
   }
  }
  
  internal static const DEFAULT_MIN:Number = 0;
  
  private var _minScale:Number = DEFAULT_MIN;
  
  public function set minScale( value:Number ):void
  {
   _minScale = value;
   this.scaledependant = true;
   
   if (_maxScale > 0 ){
    if ((ViewerContainer.getInstance().mapManager.map.scale >= _maxScale)){
     this.scaledependant = false;
    }
   } else if (_minScale > 0 ) {
    if ((ViewerContainer.getInstance().mapManager.map.scale <= _minScale)){
     this.scaledependant = false;
    }
   } else {
    this.scaledependant = false;
   }
  }
  
  public function get minScale():Number
  {
   return _minScale;
  }
  
  //--------------------------------------------------------------------------
  //  Property:  layerInfo
  //--------------------------------------------------------------------------
  
  private var _layerInfo:LayerInfo;
  
  /**
   * The map layer info that backs this TOC item.
   */
  public function get layerInfo():LayerInfo
  {
   return _layerInfo;
  }
  
  ///--------------------------------------------------------------------------
  //   Property: _rootNode
  ///--------------------------------------------------------------------------
  private var _rootInfo:ArcGISDynamicMapServiceLayer;
  /**
   * The map layer root behind this TOC item.
   */
  public function get rootInfo():ArcGISDynamicMapServiceLayer
  {
   return _rootInfo;
  }
  
  //--------------------------------------------------------------------------
  //
  //  Methods
  //
  //--------------------------------------------------------------------------
  
  /**
   * @private
   */
  override internal function setVisible( value:Boolean, layerRefresh:Boolean = true ):void
  {
  
   // Set the visible state of all children, but defer the layer refresh
   for each (var item:TocItem in children) {
    
    //if(super.preventPropogation==false){
     item.setVisible(value, false);
    //}
   }
   
   // Set the visible state of this item, but defer the layer refresh
   super.setVisible(value, false);
   
   // Allow the layer refresh now that all changes have been made
   if (layerRefresh) {
    refreshLayer();
   }
  }
 }

}
0 Kudos
FaizanTayyab
Deactivated User
The code below, loads a user session file
var bytes:ByteArray=lfileRef.data;
    this.loadedObj=bytes.readObject();
    
    map.scale=loadedObj.scale;
    map.extent=loadedObj.extent;

    var layerIDsArr:Array = map.layerIds;
    for(var i:Number = 0; i < layerIDsArr.length; i++)
    {
     var tmpLayer:Layer = map.getLayer(layerIDsArr);
     for(var j:Number=0;j<loadedObj.objs.length;j++)
     {
     if(tmpLayer.id==loadedObj.objs.mainLayer.toString()){
      tmpLayer.visible=true;
      this.hideLayerItem=new Array();
      if(tmpLayer is ArcGISDynamicMapServiceLayer){
       var dmsl:ArcGISDynamicMapServiceLayer=tmpLayer as ArcGISDynamicMapServiceLayer;
       this.loadedLayer=null;
       // Remove all checks and also remove any visible sublayers
       for each(var lyrInfo:LayerInfo in dmsl.layerInfos){
        this.hideLayer(dmsl,lyrInfo);
       }
       
       // handle the group layers and call the handler to
       AppEvent.addListener(AppEvent.VISIBLE_LAYERS_RETURNED,handleVisibleLayers);
       this.loadedLayer=dmsl;
       for each(var k:int in loadedObj.objs.visibleLayer){
        var disObj:Object=new Object();
        disObj.index=k;
        disObj.visibility=true;
        disObj.mainLayer=dmsl.name;
        AppEvent.dispatch(AppEvent.LAYER_VISIBILITY_CHANGED,disObj);
       }
       // Code below to make the child of group invisible but maintaining the tick of the group
       var newVisLayer:ArrayCollection=new ArrayCollection(this.loadedObj.objs.visibleLayer);
       for (var x:int=0; x<newVisLayer.length;x++){
        for(var y:int=0;y<this.hideLayerItem.length;y++){
         if(newVisLayer==this.hideLayerItem){
          var idx:int=newVisLayer.getItemIndex(this.hideLayerItem);
          newVisLayer.removeItemAt(idx);
         }
        }
       }
       this.loadedLayer.visibleLayers=newVisLayer;
       
      }
      
     }
     } // end of inner for
    }
0 Kudos
RavinHasseea
Emerging Contributor
Thanks for this. Does it work with the default layerlist widget ?
0 Kudos
FaizanTayyab
Deactivated User
sunsilk10,

I haven't tried it with the default layerlist widget but i think with some tweaking it should work.

As making this work required changes in multiple places within the application, I couldn't create a complete save session widget but with all those changes/additions, the save session code works fine for me.
0 Kudos