PanicBus
PanicBus

Reputation: 576

Embed a Google Map into a dynamically created div

I'm trying to dynamically generate a Google map when the user submits a form, but the map does not appear in its div when the form is submitted.

I tested to see if the map populates on merely on pageload and it does, but when trying to use a div that displays onclick the map does not show.

<form onsubmit="return false" action="">
  <input type="text" id="addLocation"/>
  <button onclick="findLocation()" id="btnLocation">Find Location</button>
</form>

<div id="mapContainer"></div>

This is the JavaScript:

function findLocation(){
  var inputString = $('#addLocation').val();
  $('#mapContainer').html('<div id="mapCanvas"></div>');

  var apiRequest = $.ajax({
    url: 'http://xxxxx.net/json/'+ inputString,
    dataType: 'json',
    type: 'get',
  });

  apiRequest.done(function(data){
    var lat = data['latitude'];
    var lng = data['longitude'];

    function initialize() {
      var mapOptions = {
        center: new google.maps.LatLng(lat, lng),
        zoom: 8
      };
      map = new google.maps.Map(document.getElementById('mapCanvas'), mapOptions);
    }

    // from GMaps API docs 
    function loadScript() {
      var script = document.createElement('script');
      script.type = 'text/javascript';
      script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp' + '&callback=initialize';
      document.body.appendChild(script);
    }
    window.onload = loadScript;

   }); // ends .done statement 
 } // ends findLocation

It should be that when you click the Find Location button it will generate a map in the mapCanvas div but it does not.

I found out from the Google Maps API documentation that if you want to asynchronously load a map you have to use that loadScript function.

And yes, the map divs have widths and heights in the CSS, so that's not the problem. I think the problem is with the Javascript scopes. I'm doing something wrong with the order or placement of the calls, just not sure what.

Upvotes: 2

Views: 3068

Answers (1)

Michael Geary
Michael Geary

Reputation: 28860

First, it is not true that you have to load the Maps API asynchronously when you want to create a map dynamically. You can load the API either using the asynchronous method or with a conventional <script> tag. Loading the API does not create a map; it merely loads the code. A map is not created until you call new google.maps.Map().

So one easy solution would be to go back to a <script> tag to load the API, and simply call your initialize() function directly inside your ajax callback. (Or pull the code out of the initialize() function and just run it inline inside the callback.)

In fact, in your current code you are already loading the Maps API at page load time, with this line:

window.onload = loadScript;

That causes the loadScript() function to be called at page load time.

So you may as well just use a <script> tag to load the API, it's more or less the same thing you're doing now but simpler.

If you do want to load the Maps API dynamically, @sirfriday's comment is correct: your initialize function is not visible in the global scope, and it needs to be so the asynchronous API load can call it when ready.

You mentioned that "calling initialize didn't do it." - but you shouldn't be calling initialize() in this case, you should set window.initialize to be a reference to the function, e.g.:

window.initialize = initialize;  // note no () so it doesn't call it here

Or change the function like this:

window.initialize = function() {
    ...
};

And also if you want to load the API dynamically, don't do it at onload time. Instead, call your loadScript() function inside your ajax callback. That will give you the right sequence of operations:

  1. Page loads
  2. User interacts with it and the ajax request starts
  3. Ajax request completes
  4. Maps API loads
  5. Your initialize() function gets called

Upvotes: 4

Related Questions