Select to view content in your preferred language

Map Resizing across browsers

5187
11
05-24-2010 06:59 AM
AndrewClark
New Contributor III
I'm developing JS libraries for our Corporate Web Team to use (they don't have the time to learn how to do it themselves).

I've hit and solved a few problems along the way, but now I'm stuck. I have 2 sample applications, one with a set-size DIV which is not an issue, but I also have a test app that has the map DIV at 100% Height and Width contained in a dojo content panel.

I've tried connecting to the onresize/resize event on the esri map object and on the map DIV but the event just doesn't fire (tested in IE and FF - latest versions). The only thing that works partially (in IE, not FF) is setting the onResize attribute [onresize="MapResizer();"] of the DIV associated with the esri map object.

To add further complication I cannot necessarily rely on whether the map-DIV is in a dojo container panel, or a plain old DIV.

So - all ideas welcome.

Thank you
0 Kudos
11 Replies
AndrewClark
New Contributor III
Saw that, tried that, didn't work!
0 Kudos
DerekSwingley
Occasional Contributor
Can you post your broken code?

Also, have you tried this way:
var resizeTimer;
dojo.connect(map, 'onLoad', function(theMap) {
  dojo.connect(dijit.byId('map'), 'resize', function() {  //resize the map if the div is resized
    clearTimeout(resizeTimer);
    resizeTimer = setTimeout( function() {
      map.resize();
      map.reposition();
    }, 500);
  });
});
}
0 Kudos
GeoffreyMahase
New Contributor
to resize my map I put an onresize on the body itself which calls a function to recalculate the content div.

HTML
<body class="tundra" onresize="onPageResizeHandler()">
        <form id="form1">
            <div id="header">
            </div>
            <div id="leftcolumn" dojotype="dijit.layout.ContentPane">                
            </div>
            <div id="center" dojotype="dijit.layout.ContentPane">
                <div id="map" style="width:1200px; height:600px; border:1px solid #000;"></div>
            </div>
        </form>
    </body>


JS
function onPageResizeHandler() {
    var _header = dojo.marginBox(dojo.byId("header"));    
    var _leftcolumn = dojo.marginBox(dojo.byId("leftcolumn"));    
    var windowsize = getWindowSize();
    _height = windowsize.h - _header.h;
    _width = windowsize.w - _leftcolumn.w;
    var centerbox = dojo.marginBox(dojo.byId("center"), {
        h: _height,
        w: _width
    });
    var leftcolumnbox = dojo.marginBox(dojo.byId("leftcolumn"), {
        h: _height        
    });
    
    var centerbox2 = dojo.marginBox(dojo.byId("center"));
    centerbox2.l = 0;
    centerbox2.t = 0;
 
    dojo.publish("ResizeMap", [centerbox2]);
};


The publish basically calls a function and passes the center div measurements to it
        var mapDiv = dojo.byId(this.map.id);
   dojo.style(mapDiv, {
       left: contentBox.l + "px",
       top: contentBox.t + "px",
       width: contentBox.w + "px",
       height: contentBox.h + "px"
   });
   this.map.resize();
   this.map.reposition();


Looks kind of cumbersome but it works in all browsers without getting into overly complicated CSS if you just want the map to be 100% height and width in a div tag on the page.
0 Kudos
BrettLord-Castillo
Occasional Contributor
The way I handled it was to put the map -inside- a dijit.layout.ContentPane. I then added the map as the property .mapobj on the ContentPane, overrode layout() on the ContentPane, and added the onMapResize function as below.
(Extra benefit, I now have an event that I can connect to if I want something else to fire when the map is resized.)
Remember to also add .resizetimer as a property on the ContentPane too.

 layout: function () { //Not executed if map is not created yet
  if (this.mapobj) {
   this.onMapResize();
  }
 }, 
 onMapResize: function () {
  if (dojo.coords(this.domNode).w > 2 && dojo.coords(this.domNode).h > 2) {
   window.clearTimeout(this.resizetimer);
   this.resizetimer = window.setTimeout(dojo.hitch(this, function () {
    this.mapobj.resize();
    this.mapobj.reposition();
   }), 200);
  }
  return arguments;
 } 


Now, as for the functions used above, the most likely problem is with the scope of window.setTimeout. window.setTimeout has a weird scope on it, so if you don't hitch to the proper scope, then 'map' might not be visible, and so your resize and reposition never gets called.

Also, notice the part about checking the size of the div before calling resize and reposition. In some browers, if the div is less than 2x2 pixels, map.resize() and map.reposition() break.
0 Kudos
munimelpati
New Contributor III
 layout: function () { //Not executed if map is not created yet
  if (this.mapobj) {
   this.onMapResize();
  }
 }, 
 onMapResize: function () {
  if (dojo.coords(this.domNode).w > 2 && dojo.coords(this.domNode).h > 2) {
   window.clearTimeout(this.resizetimer);
   this.resizetimer = window.setTimeout(dojo.hitch(this, function () {
    this.mapobj.resize();
    this.mapobj.reposition();
   }), 200);
  }
  return arguments;
 } 


Hi lordcasb,
Can u please provide me an example to how to implement the above code. That will help me a lot. Thanks.
0 Kudos
JohnGrayson
Esri Regular Contributor
The important step is to make the div hosting your map a ContentPane and just listen to resize event of the ContentPane dijit as recommended previously. Please note that when connecting the 'resize' event, the line "dijit.byId('map')" refers to the ContentPane as the JS API map is not a dijit and does not contain a 'resize' event. 

<div id="map" dojotype="dijit.layout.ContentPane" style="width:50%; height:50%;">

var resizeTimer;
dojo.connect(map, 'onLoad', function(theMap) {
  dojo.connect(dijit.byId('map'), 'resize', function() {
    clearTimeout(resizeTimer);
    resizeTimer = setTimeout( function() {
      map.resize();
      map.reposition();
    }, 500);
  });
});
0 Kudos
MartinaObermeyer
New Contributor
Hi lordcasb, Hi jgrayson,

can you please explain me how you add the mapobj as a property to the ContentPane and referenzed it to the map.

Thanks a lot.
0 Kudos
RoyJackson1
New Contributor III
dojo.connect(window, 'onresize', function() {
                map.resize();
  map.reposition();
            });

with the map like this:

   <div id="map" style="float: left; border-color: #fff" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'center'">

worked for me.
0 Kudos