Select to view content in your preferred language

Widgets within an accordion container

701
1
08-19-2011 03:04 PM
mbunambuna
Emerging Contributor
Hi I'm new to Flex / ArcGIS this past month, my experience has been mostly with Actionscript 3 and Flash. I'm trying to modify the viewer so that the widgets themselves open as items within an accordion rather than the default widget container. I've got an accordion built, and using the code in the HeaderController was able to populate each accordion header with the labels that end up in the configData (from config.xml), and when you click the accordion header is triggers the widget to run within the default WidgetContainer (just like the widget menu in the HeaderController), but I am really chasing my tail trying to get the actual widgets to load as content beneath their respective headers.

My goal is for this solution to involve as little tweaking to the stock 2.4.1 app as possible, namely, only having to add my own widgets, and change the index.mxml / config.xml / default.css. I'd rather not get into hacking up WidgetManager.mxml / WidgetContainer.mxml if I don't have to.

Is there a way to take advantage of all tracking and such that WidgetManager does (open/closed/loaded/ready/etc) and yet have the widgets render as accordion items? The best idea I can come up with right now seems to be to let them load within the widgetcontainer, then "steal" them out of it and add them into the accordion.

My messy preliminary code below. Does any of this make sense? 😛

<?xml version="1.0" encoding="utf-8"?>
<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:WidgetAccordion="widgets.GISDirectUI.WidgetAccordion.*"
       xmlns:widgetContainer="widgets.WidgetContainer.*"
       height="100%"
       borderSkin="{null}"
       creationComplete="creationCompleteHandler(event)"
       widgetConfigLoaded="init()">
 
 <fx:Script>
  <![CDATA[
   import com.esri.viewer.ViewerContainer;
   import com.esri.viewer.AppEvent;
   import com.esri.viewer.IBaseWidget;
   import com.esri.viewer.WidgetStates;
   import com.esri.viewer.IWidgetContainer;
   
   import mx.core.IVisualElement;
   import mx.events.FlexEvent;
   import mx.collections.ArrayCollection;
   import mx.controls.Button;
   import mx.effects.easing.*;
   
   [Bindable]
   private var widgetItemAC:ArrayCollection;
   [Bindable]
   private var groupWidgetAC:ArrayCollection;
   
   private function creationCompleteHandler(event:FlexEvent):void
   {
    if (configData)
    {
     widgetItemAC = getWidgetItems(configData.widgets);
     var curHeader:Button;
     for (var i:int = 0; i < widgetBox.numChildren; i++)
     {
      curHeader = Button(widgetBox.getHeaderAt(i));
      curHeader.addEventListener(MouseEvent.CLICK, accordionItemClick);
     }
    }
   }

   
   private function init():void
   {
    if (configXML)
    {
     
    }
   }
   
   private function getWidgetItems(widgetList:Array):ArrayCollection
   {
    var menuItems:ArrayCollection = new ArrayCollection;
    var widgetItem:WidgetItem;
    for (var i:int = 0; i < widgetList.length; )
    {
     if (widgetList.grouped)
     {
      // grouped
      var widgetArray:Array = [];
      var length:Number = widgetList.groupLength;
      for (var k:int = 0; k < length; k++)
      {
       widgetArray.push({ widget: widgetList[i + k], open: (widgetList.preload && (widgetList.preload == "open" || widgetList.preload == "minimized")) ? true : false });
      }
      widgetItem = new WidgetItem;
      widgetItem.isGroup = true;
      widgetItem.label = widgetList.groupLabel;
      widgetItem.icon = widgetList.groupIcon;
      widgetItem.widgets = widgetArray;
      
      menuItems.addItem(widgetItem);
      
      // move to the next group
      i = i + length;
     }
     else
     {
      // upgrouped
      widgetItem = new WidgetItem;
      widgetItem.id = widgetList.id;
      widgetItem.label = widgetList.label;
      widgetItem.icon = widgetList.icon;
      widgetItem.url = widgetList.url;
      widgetItem.open = widgetList.preload && (widgetList.preload == "open" || widgetList.preload == "minimized");
      
      menuItems.addItem(widgetItem);
      
      // move to the next individual widget
      i++;
     }
    }
    
    return menuItems;
   }
   
   private function accordionItemClick(event:Event):void
   {
    ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_RUN, event.target.parent.selectedIndex));
    //event.target.parent.getHeaderAt(event.target.parent.selectedIndex).addChild(configData.widgetContainers[0].widgets[event.target.parent.selectedIndex]);
    //event.target.parent.getHeaderAt(event.target.parent.selectedIndex).addElement(configData.widgetContainers[0].widgets[event.target.parent.selectedIndex]);
    trace(configData.widgetContainers[0].widgets[event.target.parent.selectedIndex].label);
    
   }
   
  ]]>
 </fx:Script>
  
  <s:BorderContainer id="rightPanel"
   width="300" height="100%"
   backgroundAlpha=".95"
   backgroundColor="0x2c2c2c">
   <mx:Accordion id="widgetBox" width="100%" height="300" openDuration="125" openEasingFunction="{Linear.easeOut}">
    <mx:Repeater id="widgets" dataProvider="{widgetItemAC}">
     <mx:VBox id="wrapper" width="100%" height="100%" label="{widgets.currentItem.label}">
      <!-- <s:Label id="theurl" text="{widgets.currentItem.url}"/> -->
     </mx:VBox>
    </mx:Repeater>
   </mx:Accordion>
  </s:BorderContainer>
 
</viewer:BaseWidget>
Tags (2)
0 Kudos
1 Reply
DanielBaternik
Deactivated User
Hi, did you ever find a solution?

I'm trying to do something similar except using a tab container.

I want to embed a number of widgets within separate tabs, without breaking the viewer's widget model.

regards
0 Kudos