If you are updating a map with controls, be careful not to have multiple controls and event handlers (see LAST NOTE at the end of this post).
two different events can close your popup: the CLOSE ('X') field inside the popup and the automatic procedure that closes the popup when the popup loses focus.
this pseudo-code was taken from a functional map with pop-ups that appear when the user clicks on any MARKER.
I create a layer on the map (in this case, from a dynamic KML file analyzed by php):
var urlKML = 'parseKMLTrack07d.php'; var layerKML = new OpenLayers.Layer.Vector("KML1", { strategies: [new OpenLayers.Strategy.Fixed()], protocol: new OpenLayers.Protocol.HTTP({ url: urlKML, format: new OpenLayers.Format.KML({ extractStyles: true, extractAttributes: true, maxDepth: 2 }) }) });
then I create a selection control that I call 'selectStop' and I bind 2 functions to EVENTS (when MARKER is selected and not selected):
var selectStop = new OpenLayers.Control.SelectFeature(layerKML,{onSelect: onFeatureSelect, onUnselect: onFeatureUnselect}); layerKML.events.on({ "featureselected": onFeatureSelect, "featureunselected": onFeatureUnselect }); map.addControl(selectStop); selectStop.activate();
these are two functions when MARKER or UNSELECTED is selected
function onFeatureSelect(event) { var feature = event.feature; var content = feature.attributes.name + '<br/>'+feature.attributes.description; popup = new OpenLayers.Popup.FramedCloud("chicken", feature.geometry.getBounds().getCenterLonLat(), new OpenLayers.Size(100,100), content, null, true, onFeatureUnselect); feature.popup = popup; map.addPopup(popup);
note that in the onFeatureSelect function I create a GLOBAL variable called "lastfeature". the reason i am doing this is because my onFeatureUnselect will be used to destroy the popup in case it is NOT DELETED, or CLOSE BOX CLICKED.
If I did not save the function as a global variable, I would have to handle the unselection and close box, clicking separately, because EVENTS, WHICH CAUSES EVERYONE, are different.
to create a CLOSE BOX inside the popup, I set the second in the last argument (in the popup declaration in the onFeatureSelect function) to TRUE and call onFeatureUnselect as the callback function for the close field:
popup = new OpenLayers.Popup.FramedCloud("chicken", feature.geometry.getBounds().getCenterLonLat(), new OpenLayers.Size(100,100), content, null, true, onFeatureUnselect);
LAST NOTE: if you are using update on a layer, be careful not to duplicate handlers. in this case, when your javascript starts, create the variable 'id1' that will contain the identifier of the selectStop control. check if it exists before creating a new control and handler. eg:
if (id1 == '') { var selectStop = new OpenLayers.Control.SelectFeature(layerKML,{onSelect: onFeatureSelect, onUnselect: onFeatureUnselect}); layerKML.events.on({ "featureselected": onFeatureSelect, "featureunselected": onFeatureUnselect }); map.addControl(selectStop); selectStop.activate(); id1 = selectStop.id; } else { selectStop = OpenLayers.Control.SelectFeature(layerKML,{onSelect: onFeatureSelect, onUnselect: onFeatureUnselect}); }
you can check if you are copying event handlers by adding a warning to your onFeatureSelect. if you click on the marker and you get several warning windows, then you have duplicate handlers. you get the impression that you cannot destroy the pop-up, which is not true. you destroyed ONE popup, but you have N identical pop-ups (with the same identifier, by the way).