3

i m working on a university project, and i m quite new to JS coding and i faced an issue, i am implementing my application using w3 libraries, and there is modal window which is shown when user click on the button, and this modal contains a Leaflet map, which isnt rendering properly, so I found a solution of this problem on Stackoverflow: Leaflet map not showing properly in bootstrap 3.0 modal so i tryied the proposed solution in that thread and put this in my JS code:

$('#comparator_modal').on('show.w3.modal', function(){
    setTimeout(function() {
        mymap.invalidateSize();
    }, 400);
});

but i faced another problem which i cant find a solution to. My map still renders badly, but when i resize browser window it seems to work fine(re-renders whole map, and shows a map properly), so i thought this problem might be time related, because modal might take too long to load and map invalidateSize() is executed before modal is loaded, and i tried to use different timeouts(4, 40, 400, 4000), but this doesnt resolve anything, so i m bit lost here, any ideas would be appreciated,guys here is my modal body:

<div id="comparator_modal" class="  w3-modal">
                <div  class="w3-modal-content  w3-animate-left w3-card-4">
                    <header class="w3-container w3-blue">
                        <span onclick="document.getElementById('comparator_modal').style.display='none'"
                              class="w3-btn w3-red w3-round w3-display-topright" style="font-size:16px; text-shadow:2px 1px 0 #444;">&times;</span>
                        <h3 class="w3-center" style="text-shadow:2px 1px 0 #444;">Comparator</h3>
                    </header>
                    <body>
                        <div id="comparator_modal_body">
                            <div class=w3-row">
                                <div id="map01_comparator"></div>
                                <!--<div id=map01_comparator class="w3-half w3-text-black">Map#1</div>
                                <div id=map02_comparator class="w3-half w3-text-black">Map#2</div>-->
                                <div class="w3-row">
                                    <div class="w3-half w3-center w3-text-black">
                                        <div id="time_stamp1">Time_stamp</div>
                                    </div>
                                    <div class="w3-half w3-center w3-text-black">
                                        <div id = "time_stamp2">Time_stamp</div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </body>
                    <footer class="w3-container w3-light-grey">

                    </footer>
                </div>
            </div>

And my JS which loads map:

<head>
    <!-- Load Leaflet from CDN-->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" >
    <script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet.js"></script>
    <!-- Load Esri Leaflet from CDN -->
    <script src="https://unpkg.com/esri-leaflet@2.0.8/dist/esri-leaflet.js"></script>

    <style>
        #basemaps-wrapper {
            position: absolute;
            top: 10px;
            right: 10px;
            z-index: 900;
            background: white;
            padding: 10px;
        }
        #basemaps {
            margin-bottom: 5px;
        }
    </style>
    </head>

    <script language="javascript" type="text/javascript">

    // initialize the map
    var mymap = L.map('map01_comparator').setView([42.35, -71.08], 13);
    // load a tile layer
    L.tileLayer('http://tiles.mapc.org/basemap/{z}/{x}/{y}.png',
        {
            attribution: 'Tiles by <a href="http://mapc.org">MAPC</a>, Data by <a href="http://mass.gov/mgis">MassGIS</a>',
            maxZoom: 17,
            minZoom: 9
        }).addTo(mymap);

    $('#comparator_modal').on('show.w3.modal', function(){
        setTimeout(function() {
            mymap.invalidateSize();
        }, 4000);
    });

</script>

1 Answers1

6

W3CSS is a CSS only framework, so it does not have events like bootstrap modal. You need to invalidate the map's size inside the function you are using to open the modal:

document.getElementById("mybutton").onclick = function () {
    document.getElementById('mymodal').style.display = 'block';
    setTimeout(function() {
        mymap.invalidateSize();
    }, 100);
}
iH8
  • 27,722
  • 4
  • 67
  • 76
  • thanks, man, i got it now, the secret was, like you said, to invalidatesize(), at the right time. So for those of you who have same problem, you should invoke invalidatesize() right after you load modal, you could do it right ot the button which shows modal, or, if you dont want to have php/js in your view do it in separate script and this separate script file will recognize mymap.invalidatesize() without any additional info needed. – Nikita Khudyakov Jun 25 '17 at 16:17