display infowindow as click on datagrid when you have multiple infoWindowRenderers

792
2
Jump to solution
02-21-2012 11:03 AM
TracySchloss
Frequent Contributor
I have been successfully using a click event on my datagrid to display an infoWindow.  This works fine as long as I have only one kind of ClassFactory for my infoWindowRenderer.

I define it at the top of the script tag as:

      [Bindable]    public var myCountyWindowRenderer:ClassFactory = new ClassFactory(MyCountyWindowRenderer);


Then I have an item click event as:
private function onDG_ItemClick():void {   mainMap.infoWindow.styleName = "myInfoWindow";   mainMap.infoWindow.closeButtonVisible=true;                var obj:Object = this.selectedItem;   var clickGraphic:Graphic = findGraphicByAttribute(obj);      mainMap.infoWindow.content = myCountyWindowRenderer.newInstance();      mainMap.infoWindow.data = obj;      mainMap.infoWindow.show( MapPoint(clickGraphic.geometry.extent.center) );   }  


Now I am generating my datagrids more dynamically.  From my reading, a ClassFactory isn't something I can easily generate on the fly in Actionscript.  So I created a series of renderers that look something like this:
<?xml version="1.0" encoding="utf-8"?> <mx:VBox 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:supportClasses="com.esri.ags.components.supportClasses.*"         xmlns:esri="http://www.esri.com/2008/ags" >     <fx:Declarations>   <mx:NumberFormatter id="pctFormatter" precision="2" useNegativeSign="true" rounding="nearest"  />     <mx:NumberFormatter id="wholeNumberFormatter" precision="0" useNegativeSign="true" rounding="nearest" />  </fx:Declarations>     <supportClasses:InfoWindowLabel  text="{data.NAME2}" width="150%" />         <s:Label id="lbl1_crop2002" text="Acres Treated: {wholeNumberFormatter.format(data.CROP_2002_ACRES_TREATED)}"/>     <s:Label id="lbl2_crop2002" text="Sq. Miles Treated: {data.CROP_2002_SQMILES_TREATED}"/>    <s:Label id="lbl3_crop2002" text="Percent Area Treated: {pctFormatter.format(data.CROP_2002_PCTAREATREATED)}%"/>    <s:Label id="lbl4_crop2002" text="Percent Inc/Dec 2002-2007: {pctFormatter.format(data.CROP_PCT_INCDEC_2002_2007)}%"/>  </mx:VBox>
On the map, for the graphic's mouse click event, I then ended up checking to see what type of data I was displaying and setting the infoWindowRenderer for each graphic.  Cludgy, but it works:
 switch (category){          case "CROP":           if (yearValue == "2002") {            myGraphic.infoWindowRenderer = new ClassFactory(InfoWindow_crop2002);            //var infoWindowRenderer:ClassFactory = new ClassFactory(InfoWindow_crop2002);                                  }else {            myGraphic.infoWindowRenderer =  new ClassFactory(InfoWindow_crop2007);                      }           break;          case "PAST":           if (yearValue == "2002") {            myGraphic.infoWindowRenderer =  new ClassFactory(InfoWindow_past2002);           }else {            myGraphic.infoWindowRenderer = new ClassFactory(InfoWindow_past2007);           }           break;          case "SOIL":            if (yearValue == "2002") {            myGraphic.infoWindowRenderer = new ClassFactory(InfoWindow_soil2002);           }else {            myGraphic.infoWindowRenderer = new ClassFactory(InfoWindow_soil2007);           }           break;          case "WEED":           if (yearValue == "2002") {            myGraphic.infoWindowRenderer = new ClassFactory(InfoWindow_weed2002);           }else {            myGraphic.infoWindowRenderer = new ClassFactory(InfoWindow_weed2007);           }           break;         }  


Now I want similar behavior for my datagrid items.  First of all, I would think I could get to the infoWindowRenderer of the graphic since it has previously been defined.  But I can't seem to get away from having to continue to create a individual instances of each ClassFactory for the renderer within my datagrid component.  Even after doing a similar 'looping' for determining which map.infowindow.content to use, my infoWindow is still blank.  My datagrid component is attached.  I'm sure there is a much cleaner way to do this!
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
MarkHoyland
Occasional Contributor II
Hi Tracy,
You seem to have requirements similar to mine.

Here is an example of how you can change infowindow contents. You can refernce the UIComponent(infowindow component) directly.

I have a function which can be called from the datagrid's click event or from the graphic's click event.
private function showInfoWindow(mapPoint:MapPoint, data:Object):void {  var infoWindow:LabelDataRenderer;    switch (data.CATEGORY)  {   case "CROP":    infoWindow = new CropInfoWindow;    break;   case "SOIL":     infoWindow = new SoilInfoWindow;    break;   case "WEED":    infoWindow = new WeedInfoWindow;    break;  }      infoWindow.data = data;    myMap.infoWindowContent = infoWindow;  myMap.infoWindow.show(mapPoint); }


In this example all of the infowindow components extend com.esri.ags.components.LabelDataRenderer.
The year logic is in the infowindow component. You could also use States within the infowindow component.
The infowindows also need to override the 'set data' function. The function needs to make sure the infowindow is initialised before any of the  label's text values can be set.

override public function set data(value:Object):void {  super.data = value;    if (this.initialized)  {   //component is initialised.   updateData();  }  else  {   //need to wait for the component to initialise.   //If it is not initialised, all the label controls etc will be null.   this.removeEventListener(FlexEvent.INITIALIZE, init_completeHandler)   this.addEventListener(FlexEvent.INITIALIZE, init_completeHandler);  } }  private function init_completeHandler(event:FlexEvent):void {  //component is now initialised and the label control values can be set.  updateData(); }

View solution in original post

0 Kudos
2 Replies
MarkHoyland
Occasional Contributor II
Hi Tracy,
You seem to have requirements similar to mine.

Here is an example of how you can change infowindow contents. You can refernce the UIComponent(infowindow component) directly.

I have a function which can be called from the datagrid's click event or from the graphic's click event.
private function showInfoWindow(mapPoint:MapPoint, data:Object):void {  var infoWindow:LabelDataRenderer;    switch (data.CATEGORY)  {   case "CROP":    infoWindow = new CropInfoWindow;    break;   case "SOIL":     infoWindow = new SoilInfoWindow;    break;   case "WEED":    infoWindow = new WeedInfoWindow;    break;  }      infoWindow.data = data;    myMap.infoWindowContent = infoWindow;  myMap.infoWindow.show(mapPoint); }


In this example all of the infowindow components extend com.esri.ags.components.LabelDataRenderer.
The year logic is in the infowindow component. You could also use States within the infowindow component.
The infowindows also need to override the 'set data' function. The function needs to make sure the infowindow is initialised before any of the  label's text values can be set.

override public function set data(value:Object):void {  super.data = value;    if (this.initialized)  {   //component is initialised.   updateData();  }  else  {   //need to wait for the component to initialise.   //If it is not initialised, all the label controls etc will be null.   this.removeEventListener(FlexEvent.INITIALIZE, init_completeHandler)   this.addEventListener(FlexEvent.INITIALIZE, init_completeHandler);  } }  private function init_completeHandler(event:FlexEvent):void {  //component is now initialised and the label control values can be set.  updateData(); }
0 Kudos
TracySchloss
Frequent Contributor
Thank you so much.  I'm still fiddling with this because the year isn't really an attribute ( my underlying graphics layer has both years in it), but otherwise it seems to be working for me.  I've been messing with this off and on for a week!
0 Kudos