What specifically do I have to wait for before initializing an esri/map so that it won't assign 400 for the width and height?

3958
14
09-02-2014 06:13 PM
DavidElies
New Contributor III

I have a map that displays in a Bootstrap modal.  The map is set to 100% of its container.  Since it loads before the modal is made visible, the map assigns its containing div a css width and height of 400px. Since I am creating the map (but NOT the modal), I need to know what event or set of circumstances I need to wait for in order to properly initialize the map.  If it is possible to re-initialize or have the map reset its values after an improper initialization I would like to know how to do that, too.  To be clear, I cannot use the Bootstrap shown.bs.modal event, since the map cannot know about how it is shown (but it can, of course, inspect the DOM, so it might know something about where it is displayed).  Any insights at all would be helpful.

0 Kudos
14 Replies
RiyasDeen
Occasional Contributor III

Hi David,

Try setting autoresize property when initializing the map.  map | API Reference | ArcGIS API for JavaScript

0 Kudos
DavidElies
New Contributor III

Riyas Deen,

Thanks for your response.  According to the API Reference documentation you mention, autoResize is set to true by default.  I tried explicitly setting it as you suggested, but unfortunately, it doesn't change the behavior.

I did notice that even when I set the style width and height explicitly, it was replaced upon map creation by the default 400px when the map's container was not visible when the map was created. This is a serious problem, since calling resize() after the fact never actually resizes again, since the width and height of the container have been explicitly set (on the element itself, not using classes, ids or stylesheets) without checking if the size was already set, in fact, overwriting any explicitly set values.  Do you know what check for size or visibility the map makes in order to determine whether to set default width and height?

0 Kudos
KenBuja
MVP Esteemed Contributor

Take a look at this post which resizes the map whenever its div emits a resize event.

Here's how I have it written for AMD

map.on("load", function () {

    registry.byId("divMap").on("resize", function () {

        clearTimeout(resizeTimer);

        resizeTimer = setTimeout(function () {

            map.resize();

            map.reposition();

        }, 500);

    });

})

0 Kudos
JohnGrayson
Esri Regular Contributor

If the map node is being created in a dijit/layout/* node then you can listen once to the 'resize' event so you can call map.reposition() and map.resize().  This might not help depending on the css rules so you might have to reset the node size back to 100% and then call reposition and resize.  Alternatively you could use dom-geometry.position(...) to get the current node size.  However, listening to the 'resize' event won't help if you're creating the map in just a div node as it won't have a resize event.  To find the parent dijit you can use registry.getEnclosingWidget(...) and pass in the map.root node.  This will traverse up the parent dom nodes until it finds a dijit.  Then hopefully it will be a dijit with a 'resize' event you can listen to once.

0 Kudos
DavidElies
New Contributor III

Thanks for your input Ken Buja and John Grayson,

You're right John, I don't have a resize event to listen to.  I'm not controlling the container the other team is using at all.  From what they tell me, it is not a resize, but a (Bootstrap custom) show event.  I tried exposing the map.resize() event to them, so they could handle when they want the map to be resized, but once the map is sized (correctly or incorrectly), only an actual change in size of the containing div will allow the map.resize() to do anything, since the resize event actually checks for a change.

Maybe I'm looking at this wrong.  The way I see it, I either need to control when the map loads (so i need to know without relying on the library used to display the map, when it is safe to load), or have a function that the other team can call which will "reload" the map when, (they should know), it is safe to do so.  Please let me know if I'm not seeing something or looking at this completely the wrong way. 

0 Kudos
KevinMacLeod1
Occasional Contributor III

This might be a solution.  We are also making a site with Bootstrap 3 in a MS MVC 5 template with the JS API 3.10.  We have jQuery loaded.  We also have a modal (our "disclaimer") slide down so the users have to click "Agree" to use the site. We are liking Bootstrap!  If I am understanding right, does this sound like your use case?

We found this solution gave us a full screen map div. It grabs viewport width and height and sets the map div CSS to this. Plain vanilla JS could do it but jQuery makes it concise.

<script>

        $(document).ready(function () {

            $('#disclaimer').modal('show');

            resizeDiv();

        });

        window.onresize = function (e) {

            resizeDiv();

        }

        function resizeDiv() {

            var vpw = $(window).width();

            var vph = $(window).height();

            $('#mapDiv').css({

                'height': vph + 'px',

                'width': vpw + 'px'

            });

        }

    </script>

0 Kudos
DavidElies
New Contributor III

Thanks for the response K M‌,

It is similar to what I wanted to do, but the map itself is in the modal.  The modal isn't shown by the time the map is created, so the map can't confirm that it has an actual screen position to draw to, this causes it to have trouble drawing itself, and it automatically resizes itself to 400px x 400px.  I'm trying to figure out from the map's point of view when it does have the ability to draw itself, or how the map can be reset (repositioned, resized, redrawn, etc) on demand, when an external library or somesuch requests it.

0 Kudos
KevinMacLeod1
Occasional Contributor III

This might be a solution.  We are also making a site with Bootstrap 3 in a MS MVC 5 template with the JS API 3.10.  We have jQuery loaded.  We also have a modal (our "disclaimer") slide down so the users have to click "Agree" to use the site. We are liking Bootstrap!  If I am understanding right, does this sound like your use case?

We found this solution gave us a full screen map div. It grabs viewport width and height and sets the map div CSS to this. Plain vanilla JS could do it but jQuery makes it concise.

<script>

        $(document).ready(function () {

            $('#disclaimer').modal('show');

            resizeDiv();

        });

        window.onresize = function (e) {

            resizeDiv();

        }

        function resizeDiv() {

            var vpw = $(window).width();

            var vph = $(window).height();

            $('#mapDiv').css({

                'height': vph + 'px',

                'width': vpw + 'px'

            });

        }

    </script>

0 Kudos
JohnGrayson
Esri Regular Contributor

You are correct, it seems to me that the simplest solution would be to provide the other team with the function that creates the map, and they can call it when the parent container is ready in the show event.  Basically don't create the map until it can be created correctly, especially since the other team won't give you an event to listen to.

0 Kudos