Creating widgets
http://resources.arcgis.com/en/help/flex-viewer/concepts/
Requirements
- Knowledge about ArcGIS Viewer for Flex
- Good knowledge of Adobe Flex SDK and preferable experience with Flex modules
- Source code for ArcGIS Viewer for Flex
- Adobe Adobe Flash Builder
- Existing project in Flash Builder setup with the code as per instructions in Getting Started - Developers.
You can modify an existing widget or create a new widget. In addition to the source code for all the main widgets, there is also three example widgets in the src\widgets\Samples folder (that is, HelloWorld, TestOpenClose, and ThematicQuery). The HelloWorld widget is a bare-bones widget that is a good start for understanding how a widget works. The TestOpenClose widget was added in version 2.4 and contains sample code for opening and closing widgets.
Basic steps for creating widgets
- Use the HelloWorld widget as a starting point.
- Copy the HelloWorld widget into a new location and rename it.
In Flash Builder, with the Flex Viewer project open, in the tree (Package Explorer), open FlexViewer > src > widgets > Samples. Right-click the "HelloWorld" package and select Copy. Assuming that you want the new widget to also be in the Samples folder, right-click the "Samples" directory and select Paste. A dialog box appears asking you to enter the name for the new widget. Type the new name and click OK. You should also rename the actual widget (not just the package name). Right-click the .mxml file and rename it (do the same for the .xml file).
- Add your code as appropriate.
- Compile your widget, like any other Flex module.
In Flash Builder, with the Flex Viewer project open, go to Project > Properties > Flex modules. Click Add, click Browse, then navigate to your new widget .mxml file. Click OK three times.
- Make sure the SWF [and optionally your widget configuration file if you use that]) file is copied into your bin-debug folder, for example, C:\inetpub\wwwroot\flexviewer\widgets\samples\MyWidget.
If your widget adds its own layers
As a viewer standard, the widget should hide any layers it created when users close the widget. When the widget is minimized, the layers should normally remain. To do this, make sure you use the open and closed events of the viewer:WidgetTemplate:
<viewer:WidgetTemplate id="wTemplate"
height="100%" width="100%"
minHeight="190"
minWidth="220"
closed="widgetClosedHandler(event)"
open="widgetOpenedHandler(event)">
In your Script section use code similar to the following:
private function widgetClosedHandler(event:Event):void
{
if (graphicsLayer)
{
graphicsLayer.visible = false;
}
}
private function widgetOpenedHandler(event:Event):void
{
if (graphicsLayer)
{
graphicsLayer.visible = false;
}
}
If your widget needs to get hold of the map
Any widget that extends BaseWidget will have access to the main map as "map."
The following is a code example from the Bookmark widget:
var ext:Extent = map.extent;
The following is a code example from the Coordinate widget:
if (map.loaded)
...
map.addEventListener(MapEvent.LOAD, map_loadHandler);
...
map.addEventListener(MouseEvent.MOUSE_MOVE, map_mouseMoveHandler);
The following is a code example from the Data Extract widget:
map.addLayer(graphicsLayer);
...
gp.processSpatialReference = map.spatialReference;
gp.outSpatialReference = map.spatialReference;
If your widget wants to add a graphics layer
Wait for widgetConfigLoaded, then proceed like the GeoRSS widget:
graphicsLayer = new GraphicsLayer();
graphicsLayer.name = "GeoRSS Feed";
graphicsLayer.symbol = resultMarkerSymbol;
graphicsLayer.addEventListener(FlexEvent.HIDE, graphicsLayer_hideHandler);
map.addLayer(graphicsLayer);
<viewer:WidgetTemplate
....
closed="wTemplate_closeHandler(event)"
...
open="wTemplate_openHandler(event)">
...
private function wTemplate_widgetClosedHandler(event:Event):void
{
if (graphicsLayer)
{
graphicsLayer.visible = false;
hideInfoWindow();
}
}
...
private function wTemplate_widgetOpenedHandler(event:Event):void
{
if (graphicsLayer)
{
graphicsLayer.visible = true;
}
}
If your widget needs to get hold of the layers in the map
Review the layers property of the map.
for each (var layer:Layer in map.layers)
{
// Loops through all layers in the main map.
}
If your widget needs to know when the basemap changes
Add an event listener for BASEMAP_SWITCH.
If you want to access other widgets
The WidgetManager has four useful functions for working with other widgets. See the TestOpenClose widget in the samples folder for an example.
- getWidget
public function getWidget(widgetId:Number, openWidgetIfNot:Boolean = false):IBaseWidget
- Gets the widget by the widget ID. Returns the widget by ID if the widget has been loaded, or null if the widget has not been loaded. The openWidgetIfNot option indicates whether to open the widget if it is not already in the open state.
- getAllLoadedWidgetIds
public function getAllLoadedWidgetIds():Array
- Returns an array of the widget IDs that have already been loaded.
- getNumWidgets
public function getNumWidgets():Number
- Returns the total number of widgets.
- getWidgetId
public function getWidgetId(widgetLabel:String):Number
- Returns the widget ID for a specific widget based on the widget label.