Select to view content in your preferred language

Make feature flash when popup is viewed

3410
20
Jump to solution
02-23-2012 08:51 AM
philippschnetzer
Frequent Contributor
You know what would be nice......if when you clicked on a feature that has popups enabled the feature was highlighted somehow on the map.  Even just a brief flash/halo that disappeared right away.  I have a specific case where this would really be helpful!

Thanks 🙂
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
MattiasEkström
Frequent Contributor
Yes that would be nice, and it's doable.
You can get the PopUpRendererSkin.mxml from downloading the API and make some addition there to accomplish this.
My solution is probably not the best one, but it works for me. Basically I'm adding the feature to a new graphiclayer and put a glow filter on it.
Here's my customPopUpRendererSkin, my additions are commented so you can see what I've done and change to your own customizations. For example make it flash insted of beeing highlighted or whatever you want.
Copy the skin to for example src/com/esri/viewer/skins
and then point it out in the defaults.css, something like this:
esri|PopUpRenderer {  skin-class: ClassReference("com.esri.viewer.skins.customPopUpRendererSkin"); }

I'm still in version 2.4, and my customPopUpRendererSkin is based on the one from API 2.4. If you have 2.5, download that new skin and make the changes to that one...

View solution in original post

0 Kudos
20 Replies
MattiasEkström
Frequent Contributor
Yes that would be nice, and it's doable.
You can get the PopUpRendererSkin.mxml from downloading the API and make some addition there to accomplish this.
My solution is probably not the best one, but it works for me. Basically I'm adding the feature to a new graphiclayer and put a glow filter on it.
Here's my customPopUpRendererSkin, my additions are commented so you can see what I've done and change to your own customizations. For example make it flash insted of beeing highlighted or whatever you want.
Copy the skin to for example src/com/esri/viewer/skins
and then point it out in the defaults.css, something like this:
esri|PopUpRenderer {  skin-class: ClassReference("com.esri.viewer.skins.customPopUpRendererSkin"); }

I'm still in version 2.4, and my customPopUpRendererSkin is based on the one from API 2.4. If you have 2.5, download that new skin and make the changes to that one...
0 Kudos
philippschnetzer
Frequent Contributor
Mattias,

Looking forward to trying this out!  Thanks so much for your post!  This will be useful!
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
Mattias,

   Thanks for sharing your code it is great. Here is your code reworked a bit, if you are interested. It does the same thing just less code and the way I would do it.

            override protected function commitProperties():void
            {
                super.commitProperties();

                var featureLayer:FeatureLayer = hostComponent.featureLayer;
                var formattedAttributes:Object = hostComponent.formattedAttributes;
                var graphic:Graphic = hostComponent.graphic;
                var map:Map = hostComponent.map;
                var popUpInfo:PopUpInfo = hostComponent.popUpInfo;
                var validMediaInfos:Array = hostComponent.validPopUpMediaInfos;
                var geometry:Geometry = graphic ? graphic.geometry : null;
                var layerDetails:LayerDetails = featureLayer ? featureLayer.layerDetails : null;

                //Make sure there is a graphic
                if(graphic){
                    var gf:spark.filters.GlowFilter = new spark.filters.GlowFilter();
                    gf.color = 0xFF0000;
                    gf.alpha = 1;
                    gf.strength = 2;
                    gf.blurX = 8;
                    gf.blurY = 8;
                    var hlGraphicLayer:GraphicsLayer;
                    //Attempt to retieve the highlightGraphics layer
                    hlGraphicLayer = map.getLayer("highlightGraphics") as GraphicsLayer;
                    //If it does not exist create it.
                    if(!hlGraphicLayer){
                        hlGraphicLayer = new GraphicsLayer();
                        hlGraphicLayer.id = "highlightGraphics";
                        map.addLayer(hlGraphicLayer);
                    }
                    hlGraphicLayer.clear();
                    //Create the new highlight graphic
                    const hlGraphic:Graphic = new Graphic(graphic.geometry, graphic.symbol,graphic.attributes);
                    switch(graphic.geometry.type){
                        case Geometry.MAPPOINT:{
                            hlGraphic.symbol = new SimpleMarkerSymbol("circle",22,0x000000,0,0,0,0,new SimpleLineSymbol("solid",0xFF0000,0.5,2));
                            break;
                        }
                        case Geometry.POLYLINE:{
                            hlGraphic.symbol = new SimpleLineSymbol("solid",0xFF0000,0.3,8);
                            break;
                        }
                        default:{
                            hlGraphic.symbol = new SimpleFillSymbol("solid",0x000000,0,new SimpleLineSymbol("solid",0xFF0000,0.4,3));
                            break;
                        }
                    }
                    hlGraphic.filters = [gf];
                    hlGraphicLayer.add(hlGraphic);
                    
                    //Add inline event listener functions for removing the highlight graphic
                    map.infoWindow.closeButton.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void{infoWindowClose(event, hlGraphicLayer)});
                    function infoWindowClose(evt:Event, graphicLay:GraphicsLayer):void{
                        graphicLay.clear();
                        graphicLay.refresh();
                        graphicLay.map.infoWindow.closeButton.removeEventListener(MouseEvent.CLICK, infoWindowClose);
                    }

                    map.addEventListener(MapMouseEvent.MAP_CLICK, function(event:MouseEvent):void{onMapClick(event, hlGraphicLayer)});
                    function onMapClick(evt:Event, graphicLay:GraphicsLayer):void{
                        graphicLay.clear();
                        graphicLay.refresh();
                        graphicLay.map.removeEventListener(MapMouseEvent.MAP_CLICK, onMapClick);
                    }
                }

                vGroup.removeAllElements();
                //vGroup.addElement(ToggleLayers);
                if (popUpInfo)
                {
                    if (popUpInfo.title)
                    {
                        titleText.text = StringUtil.substitute(popUpInfo.title, formattedAttributes);
                        if (titleText.text)
                        {
                            vGroup.addElement(titleText);
                            vGroup.addElement(titleLine);
                        }
                    }

                    var htmlText:String;
                    if (popUpInfo.description)
                    {
                        htmlText = StringUtil.substitute(popUpInfo.description, formattedAttributes);
                        if (htmlText)
                        {
                            var descriptionText:Text = new PopUpText();
                            descriptionText.percentWidth = 100;
                            descriptionText.styleSheet = textStyleSheet;
                            
                            cleanAndSetHtmlText(descriptionText, htmlText);
                            //trace(descriptionText.htmlText);
                            vGroup.addElement(descriptionText);
                        }
                    }
                    else
                    {
                        var descriptionForm:Form;
                        for each (var fieldInfo:PopUpFieldInfo in popUpInfo.popUpFieldInfos)
                        {
                            if (fieldInfo.visible)
                            {
                                var formItem:FormItem = new FormItem();
                                formItem.label = fieldInfo.label || fieldInfo.fieldName;
                                
                                var label:Label;
                                htmlText = formattedAttributes[fieldInfo.fieldName];
                                if (htmlText)
                                {
                                    // convert attribute field values that just contain URLs into links 
                                    var match:Array = htmlText.match(/^\s*((https?|ftp):\/\/\S+)\s*$/i);
                                    if (match && match.length > 0)
                                    {
                                        label = new Label();
                                        htmlText = '<a href="' + match[1] + '" target="_blank">' + match[1] + "</a>";
                                    }
                                    else
                                    {
                                        label = new PopUpText();
                                    }
                                    cleanAndSetHtmlText(label, htmlText);
                                    label.selectable = true;
                                    label.styleSheet = this.textStyleSheet;
                                    label.width = 150;
                                    formItem.addChild(label);
                                }
                                if (!descriptionForm)
                                {
                                    descriptionForm = new Form();
                                    descriptionForm.percentWidth = 100;
                                    descriptionForm.horizontalScrollPolicy = ScrollPolicy.OFF;
                                    descriptionForm.verticalScrollPolicy = ScrollPolicy.OFF;
                                    descriptionForm.styleName = "formStyle";
                                }
                                descriptionForm.addChild(formItem);
                            }
                        }
                        if (descriptionForm)
                        {
                            vGroup.addElement(descriptionForm);
                        }
                    }

                    if (validMediaInfos && validMediaInfos.length > 0)
                    {
                        vGroup.addElement(mediaBrowser);
                        mediaBrowser.attributes = graphic.attributes;
                        mediaBrowser.formattedAttributes = formattedAttributes;
                        mediaBrowser.popUpFieldInfos = popUpInfo.popUpFieldInfos;
                        mediaBrowser.popUpMediaInfos = validMediaInfos;
                    }

                    if (popUpInfo.showAttachments && graphic && featureLayer
                        && layerDetails && layerDetails.hasAttachments && layerDetails.objectIdField)
                    {
                        vGroup.addElement(attachmentInspector);
                        attachmentInspector.showAttachments(graphic, featureLayer);
                    }

                    if (map && geometry)
                    {
                        vGroup.addElement(zoomToButton);
                    }
                }
            }
0 Kudos
AlexSanders
Frequent Contributor
Robert,

I get a warning error 3596 - Duplicate Variable Definition for

var gf:spark.filters.GlowFilter = new spark.filters.GlowFilter();

const hlGraphic:Graphic = new Graphic(graphic.geometry, graphic.symbol,graphic.attributes);

override protected function commitProperties():void
   {
    super.commitProperties();
    
    var featureLayer:FeatureLayer = hostComponent.featureLayer;
    var formattedAttributes:Object = hostComponent.formattedAttributes;
    var graphic:Graphic = hostComponent.graphic;
    var map:Map = hostComponent.map;
    var popUpInfo:PopUpInfo = hostComponent.popUpInfo;
    var validMediaInfos:Array = hostComponent.validPopUpMediaInfos;
    var geometry:Geometry = graphic ? graphic.geometry : null;
    var layerDetails:LayerDetails = featureLayer ? featureLayer.layerDetails : null;
    
    //Make sure there is a graphic
    if(graphic){
     var gf:spark.filters.GlowFilter = new spark.filters.GlowFilter();
     gf.color = 0xFF0000;
     gf.alpha = 1;
     gf.strength = 2;
     gf.blurX = 8;
     gf.blurY = 8;
     var hlGraphicLayer:GraphicsLayer;
     //Attempt to retieve the highlightGraphics layer
     hlGraphicLayer = map.getLayer("highlightGraphics") as GraphicsLayer;
     //If it does not exist create it.
     if(!hlGraphicLayer){
      hlGraphicLayer = new GraphicsLayer();
      hlGraphicLayer.id = "highlightGraphics";
      map.addLayer(hlGraphicLayer);
     }
     hlGraphicLayer.clear();
     //Create the new highlight graphic
     /* const hlGraphic:Graphic = new Graphic(graphic.geometry, graphic.symbol,graphic.attributes); */
     const hlGraphic:Graphic = new Graphic(graphic.geometry, graphic.symbol,graphic.attributes);
     switch(graphic.geometry.type){
      case Geometry.MAPPOINT:{
       hlGraphic.symbol = new SimpleMarkerSymbol("circle",22,0x000000,0,0,0,0,new SimpleLineSymbol("solid",0xFF0000,0.5,2));
       break;
      }
      case Geometry.POLYLINE:{
       hlGraphic.symbol = new SimpleLineSymbol("solid",0xFF0000,0.3,8);
       break;
      }
      default:{
       hlGraphic.symbol = new SimpleFillSymbol("solid",0x000000,0,new SimpleLineSymbol("solid",0xFF0000,0.4,3));
       break;
      }
     }
     hlGraphic.filters = [gf];
     hlGraphicLayer.add(hlGraphic);
     
     //Add inline event listener functions for removing the highlight graphic
     map.infoWindow.closeButton.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void{infoWindowClose(event, hlGraphicLayer)});
     function infoWindowClose(evt:Event, graphicLay:GraphicsLayer):void{
      graphicLay.clear();
      graphicLay.refresh();
      graphicLay.map.infoWindow.closeButton.removeEventListener(MouseEvent.CLICK, infoWindowClose);
     }
     
     map.addEventListener(MapMouseEvent.MAP_CLICK, function(event:MouseEvent):void{onMapClick(event, hlGraphicLayer)});
     function onMapClick(evt:Event, graphicLay:GraphicsLayer):void{
      graphicLay.clear();
      graphicLay.refresh();
      graphicLay.map.removeEventListener(MapMouseEvent.MAP_CLICK, onMapClick);
     }
    }
    
    vGroup.removeAllElements();
    //vGroup.addElement(ToggleLayers);
    if (popUpInfo)
    {
     if (popUpInfo.title)
     {
      titleText.text = StringUtil.substitute(popUpInfo.title, formattedAttributes);
      if (titleText.text)
      {
       vGroup.addElement(titleText);
       vGroup.addElement(titleLine);
      }
     }
     
     var htmlText:String;
     if (popUpInfo.description)
     {
      htmlText = StringUtil.substitute(popUpInfo.description, formattedAttributes);
      if (htmlText)
      {
       var descriptionText:Text = new PopUpText();
       descriptionText.percentWidth = 100;
       descriptionText.styleSheet = textStyleSheet;
       
       cleanAndSetHtmlText(descriptionText, htmlText);
       //trace(descriptionText.htmlText);
       vGroup.addElement(descriptionText);
      }
     }
     else
     {
      var descriptionForm:Form;
      for each (var fieldInfo:PopUpFieldInfo in popUpInfo.popUpFieldInfos)
      {
       if (fieldInfo.visible)
       {
        var formItem:FormItem = new FormItem();
        formItem.label = fieldInfo.label || fieldInfo.fieldName;
        
        var label:Label;
        htmlText = formattedAttributes[fieldInfo.fieldName];
        if (htmlText)
        {
         // convert attribute field values that just contain URLs into links 
         var match:Array = htmlText.match(/^\s*((https?|ftp):\/\/\S+)\s*$/i);
         if (match && match.length > 0)
         {
          label = new Label();
          htmlText = '<a href="' + match[1] + '" target="_blank">' + match[1] + "</a>";
         }
         else
         {
          label = new PopUpText();
         }
         cleanAndSetHtmlText(label, htmlText);
         label.selectable = true;
         label.styleSheet = this.textStyleSheet;
         label.width = 150;
         formItem.addChild(label);
        }
        if (!descriptionForm)
        {
         descriptionForm = new Form();
         descriptionForm.percentWidth = 100;
         descriptionForm.horizontalScrollPolicy = ScrollPolicy.OFF;
         descriptionForm.verticalScrollPolicy = ScrollPolicy.OFF;
         descriptionForm.styleName = "formStyle";
        }
        descriptionForm.addChild(formItem);
       }
      }
      if (descriptionForm)
      {
       vGroup.addElement(descriptionForm);
      }
     }
     
     if (validMediaInfos && validMediaInfos.length > 0)
     {
      vGroup.addElement(mediaBrowser);
      mediaBrowser.attributes = graphic.attributes;
      mediaBrowser.formattedAttributes = formattedAttributes;
      mediaBrowser.popUpFieldInfos = popUpInfo.popUpFieldInfos;
      mediaBrowser.popUpMediaInfos = validMediaInfos;
     }
     
     if (popUpInfo.showAttachments && graphic && featureLayer
      && layerDetails && layerDetails.hasAttachments && layerDetails.objectIdField)
     {
      vGroup.addElement(attachmentInspector);
      attachmentInspector.showAttachments(graphic, featureLayer);
     }
     
     if (map && geometry)
     {
      vGroup.addElement(zoomToButton);
     }
    }
0 Kudos
MLowry
by
Frequent Contributor
Robert,

I get a warning error 3596 - Duplicate Variable Definition for

var gf:spark.filters.GlowFilter = new spark.filters.GlowFilter();

const hlGraphic:Graphic = new Graphic(graphic.geometry, graphic.symbol,graphic.attributes);


Which SDK are you running? I'm running 4.5.1a and it works very well for me. Oh, and here's the imports for anyone that wants to use Robert's code and not download Mattias' file.
                        import com.esri.ags.Graphic;
   import com.esri.ags.layers.GraphicsLayer;
   import com.esri.ags.Map;
   import com.esri.ags.geometry.Extent;
   import com.esri.ags.geometry.Geometry;
   import com.esri.ags.geometry.MapPoint;
   import com.esri.ags.geometry.Multipoint;
   import com.esri.ags.layers.FeatureLayer;
   import com.esri.ags.layers.supportClasses.LayerDetails;
   import com.esri.ags.skins.supportClasses.AttachmentMouseEvent;
   import com.esri.ags.skins.supportClasses.PopUpText;
   import com.esri.ags.utils.StringUtil;
   import com.esri.ags.webmap.supportClasses.PopUpFieldInfo;
   import com.esri.ags.webmap.supportClasses.PopUpInfo;
   import com.esri.ags.events.MapMouseEvent;


   //Added for popup customization
   import com.esri.ags.symbols.SimpleFillSymbol;
   import com.esri.ags.symbols.SimpleLineSymbol;
   import com.esri.ags.symbols.SimpleMarkerSymbol;
   import com.esri.ags.symbols.PictureMarkerSymbol;
   import spark.filters.GlowFilter;
   
   
   
   
   
   import mx.containers.Form;
   import mx.containers.FormItem;
   import mx.controls.Label;
   import mx.core.ScrollPolicy;
   import mx.events.FlexEvent;
0 Kudos
AlexSanders
Frequent Contributor
Good catch, I'm still on 4.1A.
0 Kudos
MattiasEkström
Frequent Contributor
Robert,
Thanks for contributing to a cleaner and more efficient code. I had a feeling it could be done a bit more efficient, but I often try some stuff out until it works, and then I don't take the time to see if it could be done differently.
I was just missing one line to make it do exactly what my code was doing.
When clicking outside a feature I also want the PopUp to hide, if anyone else wants that as well add this line to Roberts code:
...
...
map.addEventListener(MapMouseEvent.MAP_CLICK, function(event:MouseEvent):void{onMapClick(event, hlGraphicLayer)});
function onMapClick(evt:Event, graphicLay:GraphicsLayer):void{
 graphicLay.clear();
 graphicLay.refresh();
 graphicLay.map.removeEventListener(MapMouseEvent.MAP_CLICK, onMapClick);
 graphicLay.map.infoWindow.hide();
}
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
All,

   So here is the full file with Mattias last addition and a new private var at the top where you can set the highlight color (if you don't want Red).
0 Kudos
DilsonKitoko
Emerging Contributor
All,

   So here is the full file with Mattias last addition and a new private var at the top where you can set the highlight color (if you don't want Red).


Hi Robert,

I know its old, but i would like to know if this code works on Flex 2.5? I'm looking for this customization to eSearch 2.5.

Many Thanks,
0 Kudos