Skip to content Skip to sidebar Skip to footer

How To Edit Popup Using Openlayers Text Layer

I am creating a map with about 1000+ points using Openlayers. Currently when I click on one point's icon, the description for the point shows up in a popup, and to exit the popup I

Solution 1:

if you are refreshing a map that has controls, be careful not to have multiple controls and event handlers (see LAST NOTE at the end of this post).

two distinct events can close your popup: a CLOSE ('X') box inside the popup AND an automatic procedure that closes the popup when the popup loses focus.

this pseudo-code was taken from a functional map with popup windows that appear when the user clicks on a any MARKER.

i create a layer on the map (in this case from a dynamic KML file, parsed 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 which i call 'selectStop' and i associate 2 functions to EVENTS (when the MARKER is selected and unselected):

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 the two functions for when the MARKER is selected or UNSELECTED

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);
    // GLOBAL variable, in case popup is destroyed by clicking CLOSE box
    lastfeature = feature;
}
function onFeatureUnselect(event) {
    var feature = lastfeature;  
    if(feature.popup) {
        map.removePopup(feature.popup);
        feature.popup.destroy();
        delete feature.popup;
    }
}

please note that in the onFeatureSelect function, i create a GLOBAL variable called 'lastfeature'. the reason i do this is so that my onFeatureUnselect will be used to destroy the popup in case it it is UNSELECTED or the CLOSE BOX IS CLICKED.

if i did not save the feature as a global variable i would have to treat unselection and close box clicking separately, because the EVENTS THAT CAUSE EACH are different.

to create the CLOSE BOX inside the popup, i set the second to last argument (in the popup declaration in the onFeatureSelect function) to TRUE and name onFeatureUnselect as the callback function for the close box:

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 refresh on a layer, be careful not to duplicate your handlers. in that case, when your javascript starts, create a variable 'id1' which will hold your selectStop control id. check if it exists before creating a new control and handler. like this:

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 duplicating your event handlers, by puting an alert in your onFeatureSelect. if you click on a marker and you get multiple alert windows, then you have duplicate handlers. you get the impression that you cannot destroy a popup, which is untrue. you destroyed ONE popup, but you have N identical popups (with the same id, by the way).

Solution 2:

In the constructor call to the Popup, you can specify that a close box should be present.

From OpenLayers documentation: http://dev.openlayers.org/apidocs/files/OpenLayers/Popup-js.html

Parameters
...
closeBox    {Boolean} Whether todisplaya close box inside the popup.
closeBoxCallback    {Function} Function to be called on closeBox click.

and if you use the layer event featureselected to display the popup, you can use the featureunselected event to close the popup.

Post a Comment for "How To Edit Popup Using Openlayers Text Layer"