Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google map render issue after asynchronous AJAX call

- Introduction

Hello, i have an individual project for my course where i have to put all events of a festival on a single page. It is a javascript course, so most tasks should be handled with javascript.

The problem is, to provide a good website, that i am using a loading gif file with a message that the user has to wait until the data from AJAX got taken and handled.

This is my HTML snippet

<!-- showing loading screen -->
<div id="startup">
    <h3>Please wait until the data is done with loading</h3>
    <img src="images/ajax_load.gif" alt="loading icon" id="load_icon" />
</div>
<!-- actual content (will be displayed after loading phase) -->
<div id="siteContent">
    <div id="top">
        <label><input type="checkbox" name="cbDisabilities" id="cbDisabilities">Accessible for disabilities</label>
        <label><input type="checkbox" name="cbFree" id="cbFree">for free</label>
        <select id="selectCat">
            <option selected="selected">&nbsp;</option>
        </select>
    </div>
    <div id="mapBox"></div>
    <div id="dateBox" class="layout"></div>
    <div id="eventBox" class="layout borders"></div>
</div>
<footer>
    <p>Gentse Feesten Infos &ndash; &copy; name here TODO</p>
</footer>

With the above, i have also the next CSS for both divs,

div#siteContent {
    display: none;
}
/* style google map box */
div#mapBox {
    display: block;
    height : 500px;
    width : 500px;
    margin-top : 5px;
}

As you can see, the actual content is hidden so that the load image with the h3 text is only visible. Now, when the AJAX call is done, i have to add the markers of the event locations to the map. In meanwhile i also handle the obtained JSON data. Once this is done, i want to remove the div with the loading.gif animation and display the actual content.

Here is also an image how the data is being handled (initalize map = read GPS location + place current location marker + load map); enter image description here

I have to initialize the map BEFORE the AJAX call is done because i have to add multiple markers to the map when i'm handling the data. Without the map, there will be an error when adding google map markers.

Here is a javascript snippet at the load. There are two methods, loadData() that calls AJAX and placeMap(currentLocation) to initialize the google map.

window.addEventListener('load', function() {

    // get json data - going to call AJAX
    loadData();

    // getting current location by geocoder
    var getGeoLocation = new google.maps.Geocoder();
    var currentPosition;

    if(navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function(position) {
            currentPosition = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); 
            placeMap(currentPosition);
        }, function() {
            handleError(100);
        });
    }
    else {
    handleError(200);
    }
    // other tasks omitted
});

This is how the map is being initialized and rendered (currentMap is a global variable to hold the reference to the google map object),

var placeMap = function(location) {
    var mapOptions = {
        zoom : 18,
        center : location,
        disableDefaultUI : true, // remove UI
        scaleControl : true,
        zoomControl : true,
        panControl : true,
        mapTypeId : google.maps.MapTypeId.ROADMAP
    };
    currentMap = new google.maps.Map($("mapBox"), mapOptions);
    // current position
    var mapMarker = new google.maps.Marker({
        position : location,
        map : currentMap,
        zIndex : 255
    });
    google.maps.event.addListenerOnce(currentMap, 'idle', setActive);
}

- My problem

But my problem is, that the map window doesn't render well if i use the display:none at the load. When i toggle it to inline (default browser display style), there is a gray area in the box and the map is rendering partially.

- Already tried solutions

I have already tried the solutions found on this site ;

  1. here - result : i'm getting same display result as this questioner, that gray area. But it didn't solved my problem.
  2. here - result : no rendering (box got collapsed).
  3. here - result : same as (2).

- Best solution so far BUT

So far, i have the best result with the next command

// display content
$("startup").style.display = "none";
$("siteContent").style.display = "inline";
google.maps.event.trigger(currentMap, 'resize');

(startup = div with the loading gif image and siteContent = actual content).

This renders the map correctly after displaying visible. BUT here, the map is - sadly enough - not centered on the GPS position. The GPS marker is at the left upper corner.

If i am displaying the site without using the display="none" on the div#siteContent, then everything works as intended (The google map displays correctly with the GPS position centered on the map).

Does someone know how to solve this small rendering problem ? Preferably without use of jQuery.

like image 343
KarelG Avatar asked Aug 06 '13 12:08

KarelG


People also ask

Does Google Maps use AJAX?

Designed to compete with well-established mapping sites, Google Maps uses Ajax to avoid reloading its main page at all (see Figure 1-4). Unlike other mapping web applications, Google Maps enables you to drag the map to move it in various directions.

How are Google maps rendered?

Instead of trying to render a single image, Google breaks down the map into smaller tiles, and then places them next to each other to make up a single bigger picture — just like a mosaic. The primary reason for this is image size.

Why can't I call new Google Maps map from the API?

We omitted the async attribute from the script tag that loads the API, and we also omitted the callback parameter. When the API is loaded synchronously, subsequent script tags will not execute until the API is fully loaded. Because of this, the final script tag can call new google.maps.Map and assume that google.maps.Map has been defined.

Is the Maps API loaded synchronously or asynchronous?

In this example, the Maps API is loaded synchronously. We omitted the async attribute from the script tag that loads the API, and we also omitted the callback parameter.

What is Ajax async in jQuery?

The jQuery Ajax async is handling Asynchronous HTTP requests in the element. It is a procedure to send a request to the server without interruption. It is an Asynchronous method to send HTTP requests without waiting response. It is a function to working on a server without associating more than on request.

Can the final script tag call new Google Maps?

Because of this, the final script tag can call new google.maps.Map and assume that google.maps.Map has been defined. Read the documentation. Note: Read the guide on using TypeScript and Google Maps.


1 Answers

// display content
$("startup").style.display = "none";
$("siteContent").style.display = "inline";
google.maps.event.trigger(currentMap, 'resize');

(startup = div with the loading gif image and siteContent = actual content).

It seems your only problem now is?:

BUT here, the map is - sadly enough - not centered on the GPS position. The GPS marker is at the left upper corner.

so then you should:

google.maps.event.trigger(currentMap, 'resize');
currentMap.setCenter(location);

Google Maps API

Most likely, you are setting the point center before the map has resized. When it resizes it simply fills the space to the right and down, the center does not change as the map resizes.

like image 167
Erik Philips Avatar answered Oct 20 '22 00:10

Erik Philips