[Users] Possible Bug concerning Popups in a Window from Grid Selection

Horne, Ryan rmhorne at email.unc.edu
Fri Apr 6 19:52:43 CEST 2012


Hello List,

I seem to have run into a possible bug regarding a feature popup when a feature is selected in a grid. 

To try and isolate the issue I have combined the feature-grid and popup examples to show this behavior. When a feature grid is combined with popups in a rendered element in the page everything works fine- the popups are generated just as they should be when you click on the grid.

The problem is when the "main" panel of the map and the grid are placed in a new Ext window. Popups when a feature is selected on the map work fine, but when a feature is selected through clicking on the grid the popups no longer appear.

Stepping through the code in firebug I can see that the popoup window is intact initially created, anchored correctly, and shown on the map. However the popup is eventually hidden (I think after a call to ext-all.js). I tried this with a plain Ext.Window instead of the GeoExt.Popup and it exhibited the same behavior.

Is this a bug or am I missing a configuration option somewhere? I have pasted the code for what I think is the bug followed by a "working" example that is not in a new Ext window.

Thanks,
Ryan




Code (This is the error, a main window containing everything else):

<?xml version="1.0" encoding="UTF-8"?>


<html>
<head>
   <script src="http://openlayers.org/api/OpenLayers.js"></script>
   <script src="/includes/extjs/3.4.0/adapter/ext/ext-base.js" type="text/javascript"></script>
<script src="/includes/extjs/3.4.0/ext-all.js"  type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="/includes/extjs/3.4.0/resources/css/ext-all.css"></link>
<script src="/includes/geoext/1.1/lib/GeoExt.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="/includes/geoext/1.1/resources/css/geoext-all-debug.css"></link>
<script type="text/javascript">



var mapPanel, store, gridPanel, mainPanel;

Ext.onReady(function() {


    // create map instance
    var map = new OpenLayers.Map();
var coast = new OpenLayers.Layer.WMS(
        "vmap0",
        "http://vmap0.tiles.osgeo.org/wms/vmap0",
        {layers: 'basic'}
    );

    // create vector layer
    var context = {
        getColor: function(feature) {
            if (feature.attributes.elevation < 2000) {
                return 'green';
            }
            if (feature.attributes.elevation < 2300) {
                return 'orange';
            }
            return 'red';
        }
    };
    var template = {
        fillOpacity: 0.5,
        fillColor: "${getColor}",
        pointRadius: 5,
        strokeWidth: 1,
        strokeOpacity: 1,
        strokeColor: "${getColor}",
        graphicName: "triangle"
    };
    var style = new OpenLayers.Style(template, {context: context});
    var vecLayer = new OpenLayers.Layer.Vector("vector", {
        styleMap: new OpenLayers.StyleMap({
            'default': style
        })
    });
    map.addLayers([coast, vecLayer]);

    // create map panel
    mapPanel = new GeoExt.MapPanel({
        title: "Map",
        region: "center",
        height: 400,
        width: 600,
        map: map,
        center: new OpenLayers.LonLat(5, 45),
        zoom: 6
    });
 
    // create feature store, binding it to the vector layer
    store = new GeoExt.data.FeatureStore({
        layer: vecLayer,
        fields: [
            {name: 'name', type: 'string'},
            {name: 'elevation', type: 'float'}
        ],
        proxy: new GeoExt.data.ProtocolProxy({
            protocol: new OpenLayers.Protocol.HTTP({
                url: "summits.json",
                format: new OpenLayers.Format.GeoJSON()
            })
        }),
        autoLoad: true
    });

    function getSymbolTypeFromFeature(feature){
        var type;
        switch (feature.geometry.CLASS_NAME) {
            case "OpenLayers.Geometry.MultiLineString":
            case "OpenLayers.Geometry.LineString":
                type = 'Line';
                break;
            case "OpenLayers.Geometry.Point":
                type = 'Point';
                break;
            case "OpenLayers.Geometry.Polygon":
                type = 'Polygon';
                break;
        }
        return type;
    }

    function renderFeature(value, p, r) {
        var id = Ext.id(),
            feature = r.get('feature');

        (function() {
            var symbolizer = r.store.layer.styleMap.createSymbolizer(feature, 'default');
            var renderer = new GeoExt.FeatureRenderer({
                renderTo: id,
                width: 12,
                height: 12,
                symbolType: getSymbolTypeFromFeature(feature),
                symbolizers: [symbolizer]
            });
        }).defer(25);
        return (String.format('<div id="{0}"></div>', id));
    }

    // create grid panel configured with feature store
    gridPanel = new Ext.grid.GridPanel({
        title: "Feature Grid",
        region: "east",
        store: store,
        width: 320,
        columns: [{
            header: "",
            width: 30,
            renderer: renderFeature,
            dataIndex: 'fid'
        },{
            header: "Name",
            width: 200,
            dataIndex: "name"
        }, {
            header: "Elevation",
            width: 100,
            dataIndex: "elevation"
        }],
        sm: new GeoExt.grid.FeatureSelectionModel() 
    });


  var selectCtrl = new OpenLayers.Control.SelectFeature(vecLayer);

    // define "createPopup" function
    var bogusMarkup = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit.";
    function createPopup(feature) {
        popup = new GeoExt.Popup({
            title: 'My Popup',
            location: feature,
            width:200,
            html: bogusMarkup,
            maximizable: true,
            collapsible: true
        });
        // unselect feature when the popup
        // is closed
        popup.on({
            close: function() {
                if(OpenLayers.Util.indexOf(vecLayer.selectedFeatures,
                                           this.feature) > -1) {
                    selectCtrl.unselect(this.feature);
                }
            }
        });
        popup.show();
    }

    // create popup on "featureselected"
    vecLayer.events.on({
        featureselected: function(e) {
            createPopup(e.feature);
        }
    });


    // create a panel and add the map panel and grid panel
    // inside it
    mainPanel = new Ext.Panel({
        layout: "border",
        height: 400,
        width: 920,
                region: "center",
        items: [mapPanel, gridPanel]
    });

var mainwin = new Ext.Window({
        title: "Popuptest",
             resizable: true,
             id: "mainwin",
        maximizable: true,
        constrain: true,
        height: 800,
        width: 1200,
        layout: "border",
        items: [mainPanel]
    });
    
    mainwin.show()
    


});


</script>


</head>
</body>
</html>






Working Code (The popups work here but the main panel is not in a window):

<?xml version="1.0" encoding="UTF-8"?>


<html>
<head>
   <script src="http://openlayers.org/api/OpenLayers.js"></script>
   <script src="/includes/extjs/3.4.0/adapter/ext/ext-base.js" type="text/javascript"></script>
<script src="/includes/extjs/3.4.0/ext-all.js"  type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="/includes/extjs/3.4.0/resources/css/ext-all.css"></link>
<script src="/includes/geoext/1.1/lib/GeoExt.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="/includes/geoext/1.1/resources/css/geoext-all-debug.css"></link>
<script type="text/javascript">



var mapPanel, store, gridPanel, mainPanel;

Ext.onReady(function() {


    // create map instance
    var map = new OpenLayers.Map();
var coast = new OpenLayers.Layer.WMS(
        "vmap0",
        "http://vmap0.tiles.osgeo.org/wms/vmap0",
        {layers: 'basic'}
    );

    // create vector layer
    var context = {
        getColor: function(feature) {
            if (feature.attributes.elevation < 2000) {
                return 'green';
            }
            if (feature.attributes.elevation < 2300) {
                return 'orange';
            }
            return 'red';
        }
    };
    var template = {
        fillOpacity: 0.5,
        fillColor: "${getColor}",
        pointRadius: 5,
        strokeWidth: 1,
        strokeOpacity: 1,
        strokeColor: "${getColor}",
        graphicName: "triangle"
    };
    var style = new OpenLayers.Style(template, {context: context});
    var vecLayer = new OpenLayers.Layer.Vector("vector", {
        styleMap: new OpenLayers.StyleMap({
            'default': style
        })
    });
    map.addLayers([coast, vecLayer]);

    // create map panel
    mapPanel = new GeoExt.MapPanel({
        title: "Map",
        region: "center",
        height: 400,
        width: 600,
        map: map,
        center: new OpenLayers.LonLat(5, 45),
        zoom: 6
    });
 
    // create feature store, binding it to the vector layer
    store = new GeoExt.data.FeatureStore({
        layer: vecLayer,
        fields: [
            {name: 'name', type: 'string'},
            {name: 'elevation', type: 'float'}
        ],
        proxy: new GeoExt.data.ProtocolProxy({
            protocol: new OpenLayers.Protocol.HTTP({
                url: "summits.json",
                format: new OpenLayers.Format.GeoJSON()
            })
        }),
        autoLoad: true
    });

    function getSymbolTypeFromFeature(feature){
        var type;
        switch (feature.geometry.CLASS_NAME) {
            case "OpenLayers.Geometry.MultiLineString":
            case "OpenLayers.Geometry.LineString":
                type = 'Line';
                break;
            case "OpenLayers.Geometry.Point":
                type = 'Point';
                break;
            case "OpenLayers.Geometry.Polygon":
                type = 'Polygon';
                break;
        }
        return type;
    }

    function renderFeature(value, p, r) {
        var id = Ext.id(),
            feature = r.get('feature');

        (function() {
            var symbolizer = r.store.layer.styleMap.createSymbolizer(feature, 'default');
            var renderer = new GeoExt.FeatureRenderer({
                renderTo: id,
                width: 12,
                height: 12,
                symbolType: getSymbolTypeFromFeature(feature),
                symbolizers: [symbolizer]
            });
        }).defer(25);
        return (String.format('<div id="{0}"></div>', id));
    }

    // create grid panel configured with feature store
    gridPanel = new Ext.grid.GridPanel({
        title: "Feature Grid",
        region: "east",
        store: store,
        width: 320,
        columns: [{
            header: "",
            width: 30,
            renderer: renderFeature,
            dataIndex: 'fid'
        },{
            header: "Name",
            width: 200,
            dataIndex: "name"
        }, {
            header: "Elevation",
            width: 100,
            dataIndex: "elevation"
        }],
        sm: new GeoExt.grid.FeatureSelectionModel() 
    });


  var selectCtrl = new OpenLayers.Control.SelectFeature(vecLayer);

    // define "createPopup" function
    var bogusMarkup = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit.";
    function createPopup(feature) {
        popup = new GeoExt.Popup({
            title: 'My Popup',
            location: feature,
            width:200,
            html: bogusMarkup,
            maximizable: true,
            collapsible: true
        });
        // unselect feature when the popup
        // is closed
        popup.on({
            close: function() {
                if(OpenLayers.Util.indexOf(vecLayer.selectedFeatures,
                                           this.feature) > -1) {
                    selectCtrl.unselect(this.feature);
                }
            }
        });
        popup.show();
    }

    // create popup on "featureselected"
    vecLayer.events.on({
        featureselected: function(e) {
            createPopup(e.feature);
        }
    });


    // create a panel and add the map panel and grid panel
    // inside it
    mainPanel = new Ext.Panel({
        layout: "border",
                renderTo: "mainpanel",
        height: 400,
        width: 920,
                region: "center",
        items: [mapPanel, gridPanel]
    });



});


</script>


</head>
        <div id="mainpanel"></div>

</body>
</html>



More information about the Users mailing list