You are here:   GIS Web Map Tutorial > Adding a Popup
  |  Login

Adding a Popup

   Minimize

It is important that the users of your data know what the markers are representing.  To accomplish this we will add a popup which will contain a title and a description.

To add the popup we will need to do a few things which I will outline here.

  1. Create a global variable to hold the popup and a selectFeature control 
  2. Handle onFeatureSelect Event
  3. Handle onFeatureUnselect Event
  4. Handle onPopupClose Event 
  5. Add the marker layer to the selectFeature control
  6. Add the selectFeature control to the map and activate it. 

For the Global variables let's just start off and put them directly under the var map; variable we have at the top of the javascript.  We will call them select and popup to make it easy.

var select;
var popup;

The onFeatureSelect Event is what happens when a user clicks the marker.  So we need to handle this event and tell the page to open a popup with the title and description. In this we will have to handle a couple of browser issues so we will do some checking to see what the browser sent and use the correct syntax for the specific one.  This and all of our event handlers will be new functions similar to the initialize function we already created.  That being the case we will add the function code directly after the closing } of the initialize function which is right above the </script> tag.  Here is the begining of the function.

function onFeatureSelect(evt) 
{

 Next we need to get access to the feature that was clicked so we can get it's title, description, and location. So we will ask the browser if it sent it as a property of the event or if it sent the feature as the event.  Whichever is true we will set to the variable feature so we can work with it.

var feature; 
if(evt.feature)
{
     feature = evt.feature;
}
else
{
     feature = evt;
}

 Now that we have the feature we can get the location and set it to a variable named point.

var point;
try
{
     point = feature.geometry.getBounds().getCenterLonLat();
}
catch(e)
{
     try
     {
          point = evt.geometry.getBounds().getCenterLonLat();
     }
     catch(e2){}
}

 Notice the try catch blocks.  This is due to the different browsers handling the point in their own way.  Next we will go ahead and create the popup, attach it to the marker (remember that is held in the variable feature) then add it to the map.  Finally we will close the function with a }

popup = new OpenLayers.Popup.FramedCloud("featurePopup",
                                 point,
                                 new OpenLayers.Size(100,100),
                                 "<h2>"+feature.attributes.name + "</h2>" +
                                 feature.attributes.description,
                                 null, true, onPopupClose);
popup.maxSize = new OpenLayers.Size(400, 3000);
feature.popup = popup;
popup.feature = feature;
map.addPopup(popup);
}

Recall that we added a name and a description to the marker when we created it.  This is what we are using when we say feature.attributes.name and feature.attributes.description.  That was the meat of the popup but we still need to close the loose ends.  When the marker is unselected we want to remove the popup from the map so we will create a new function under the prior one we just finished.

function onFeatureUnselect(evt) {
     var feature; 
     if(evt.feature)
     {
          feature = evt.feature;
     }
     else
     {
          feature = evt;
     }
     if (feature.popup) 
     {
          popup.feature = null;
          map.removePopup(feature.popup);
          feature.popup.destroy();
          feature.popup = null;
          try{
               map.removePopup(markers.popup);
          }
          catch(e){}
     }    
}

 Now we just have to handle the onPopupClose event which happens when a user clicks the X to close the popup.  We just want to unselect all features at this point so that it will call the onFeatureUnselect and remove the popup.

function onPopupClose(evt) 
{
     select.unselectAll();
}

 Now that the events are handled let's get to adding the popup!  We will go back to the initialize function and between the map.addLayer(bluelayer); and map.setCenter(new OpenLayers.LonLat(-86.57, 34.65), 12);  we will add the following code.

select = new OpenLayers.Control.SelectFeature([bluelayer], 
                                              {
                                                onSelect: onFeatureSelect, 
                                                onUnselect: onFeatureUnselect
                                               }
                                              );
map.addControl(select);
select.activate(); 

 Now let's save the file as webmap5.html and upload it to your server.  It should look like mine. Make sure that a popup opens when you click the marker, closes when u click the X and when u click any spot on the map other than the marker.  Here is my complete code.

<html> 
<head> 
<script src="http://openlayers.org/api/OpenLayers.js"></script>
<style type="text/css">
	html { height: 100% }
 	body { height: 100%; margin: 0px; padding: 0px }
	#map_canvas { height: 100% }
</style>
<script>
var map;
var select;

var popup;

       


// Avoid pink error tiles
OpenLayers.IMAGE_RELOAD_ATTEMPTS = 5;
OpenLayers.Util.onImageLoadErrorColor = "transparent";

  function initialize() {
     map = new OpenLayers.Map("map_canvas");
     var mapbase = new OpenLayers.Layer.WMS('OpenLayers WMS', 
       'http://vmap0.tiles.osgeo.org/wms/vmap0', 
       { layers: 'basic,coastline_01,depthcontour,priroad,secroad,clabel'});

     var nexrad = new OpenLayers.Layer.WMS("Nexrad",
       "http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi?",
       {   layers:"nexrad-n0r-wmst",Time: '2011-12-25T09:45:00Z', 
           transparent:true
        }, {isBaseLayer: false, opacity:.5});

     var kmlLayer = new OpenLayers.Layer.Vector("KML", {
            strategies: [new OpenLayers.Strategy.Fixed()],
            protocol: new OpenLayers.Protocol.HTTP({
                url: "monte-sano-state-park.kml",
                format: new OpenLayers.Format.KML({
                    extractStyles: true, 
                    extractAttributes: true,
                    maxDepth: 2
                })
            })
        })

     map.addLayers([nexrad, mapbase]);
     map.addLayer(kmlLayer);



     var styleMapBlue = new OpenLayers.StyleMap(
		{pointRadius: 15,

                 externalGraphic: 'images/blue-circle.png'

            	});                                                    

     var bluelayer = new OpenLayers.Layer.Vector('blue', 

             	{

               	  styleMap: styleMapBlue 

           	});
     var point = new OpenLayers.Geometry.Point(-86.57, 34.65);
     var marker = new OpenLayers.Feature.Vector(point);

     marker.attributes.name = "Center of our map";

     marker.attributes.description = "This is the center of our map!";
     bluelayer.addFeatures([marker]);
     map.addLayer(bluelayer);

     select = new OpenLayers.Control.SelectFeature([bluelayer], 
                                              {
                                                onSelect: onFeatureSelect, 
                                                onUnselect: onFeatureUnselect
                                               }
                                              );
     map.addControl(select);
     select.activate(); 
     map.setCenter(new OpenLayers.LonLat(-86.57, 34.65), 12); 
 }
 function onFeatureSelect(evt) 
 {
     var feature; 
     if(evt.feature)
     {
          feature = evt.feature;
     }
     else
     {
          feature = evt;
     }
     var point;
     try
     {
          point = feature.geometry.getBounds().getCenterLonLat();
     }
     catch(e)
     {
          try
          {
               point = evt.geometry.getBounds().getCenterLonLat();
          }
          catch(e2) {}
     }
     popup = new OpenLayers.Popup.FramedCloud("featurePopup",
                                  point,
                                  new OpenLayers.Size(100,100),
                                  "<h2>"+feature.attributes.name + "</h2>" +
                                  feature.attributes.description,
                                  null, true, onPopupClose);
     popup.maxSize = new OpenLayers.Size(400, 3000);
     feature.popup = popup;
     popup.feature = feature;
     map.addPopup(popup);
 }

 function onFeatureUnselect(evt) 
{
     var feature; 
     if(evt.feature)
     {
          feature = evt.feature;
     }
     else
     {
          feature = evt;
     }
     if (feature.popup) 
     {
          popup.feature = null;
          map.removePopup(feature.popup);
          feature.popup.destroy();
          feature.popup = null;
          try{
               map.removePopup(markers.popup);
          }
          catch(e){}
     }    

 }

 function onPopupClose(evt) 
 {
     select.unselectAll();
 }

</script>
</head>
<body onload="initialize()">
<div id="map_canvas"></div>
</body>
</html>

 Next up we have Adding an Image Overlay