[GIS] How to add mappanel back to container once removed

geoextlayoutsmapwindowopenlayers-2

I am trying to test following scenario:

  • A Ext.Window has one gx_mappanel item;

  • both Ext.Window and gx_mappanel are stored in variables;

  • One button is to remove gx_mappanel item from Ext.Window container;

  • The other button is to add this gx_mappanel item back to Ext.Window
    container;

However:
Once mappanel is removed, it cannot be added back to its container.

The issue happens in IE browser, and the error is:

SCRIPT5007: Unable to get value of the property 'removeChild': object is null or undefined       

which is in OpenLayers.js, line 825 character 412:

render: function(div) {
    this.div = OpenLayers.Util.getElement(div);
    OpenLayers.Element.addClass(this.div, 'olMap');
    this.viewPortDiv.parentNode.removeChild(this.viewPortDiv);
    this.div.appendChild(this.viewPortDiv);
    this.updateSize();
}

Codes I've tried:

    <! DOCTYPE HTML>
<html>
    <head>
        <title>GeoExt MapPanel Example</title>

    <script type="text/javascript" src="http://extjs.cachefly.net/ext-3.2.1/adapter/ext/ext-base.js"></script>
    <script type="text/javascript" src="http://extjs.cachefly.net/ext-3.2.1/ext-all.js"></script>
    <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-3.2.1/resources/css/ext-all.css" />
    <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-3.2.1/examples/shared/examples.css" />
    <script src="http://www.openlayers.org/api/2.10/OpenLayers.js"></script>
    <script type="text/javascript" src="http://api.geoext.org/1.0/script/GeoExt.js"></script>

    <script type="text/javascript">
    var mapPanel;
    var parentWin;

    Ext.onReady(function() {
        var map = new OpenLayers.Map();
        var layer = new OpenLayers.Layer.WMS(
            "Global Imagery",
            "http://maps.opengeo.org/geowebcache/service/wms",
            {layers: "bluemarble"}
        );
        map.addLayer(layer);

        mapPanel = {
            xtype : 'gx_mappanel',
            id : 'MAP_PANEL',
            map : map,
            zoom: 6
        };

         parentWin = new Ext.Window({
            title: "GeoExt MapPanel Window",
            height: 400,
            width: 600,
            layout: "fit",
            items: [mapPanel]
        }).show();

    });

    function mapGone() {
        parentWin.removeAll();
        parentWin.doLayout();
    }

    function mapBack() {
        parentWin.add(mapPanel);
        parentWin.doLayout();
    }
    </script>
</head>
<body>
    <input type="button" onclick="mapGone()" value="map gone"></input>
    <input type="button" onclick="mapBack()" value="map back"></input>
</body>

I really wish somebody can give me some advice…
appreciate in advance!!

Best Answer

I think it's because removeAll() destroys div that map was rendered in, but OpenLayers still has some references to it.

Try creating new mapPanel every time you want to add it again by extracting creation code to the new function:

function getMapPanel() {        
        var map = new OpenLayers.Map();
        var layer = new OpenLayers.Layer.WMS(
            "Global Imagery",
            "http://maps.opengeo.org/geowebcache/service/wms",
            {layers: "bluemarble"}
        );
        map.addLayer(layer);

        var newMapPanel = {
            xtype : 'gx_mappanel',
            id : 'MAP_PANEL',
            map : map,
            zoom: 6
        };

     return newMapPanel;
}

then change the onReady function to:

Ext.onReady(function() {        
     parentWin = new Ext.Window({
        title: "GeoExt MapPanel Window",
        height: 400,
        width: 600,
        layout: "fit",
        items: [getMapPanel()] //NOTICE HERE IS FUNCTION CALL NOT REFERENCE TO VAR
    }).show();
});

also add handler needs updating:

function mapBack() {
    parentWin.add(getMapPanel()); //FUNCTION CALL
    parentWin.doLayout();
}

Try it, code is untested. Greetz