Simple Google Maps object for use with ajax maps

The Google mapping extension by Dos Amigos (link) is really great but there are difficulties with Google maps when you want to manipulate your map object with Ajax.

Thanks to some core code from Dos Amigos, I have fashioned a simpler way to manage ajax manipulation of Google maps.

The method described here enables you to create a map canvas and then update it over time with Ajax calls.

First, create a javascript file with the following code

[javascript]

var myGMap = (function(){
    var gmap0infoWindow;
    var gmap0;
    var gmarker = [];
    var container;
    var mapOptions;
    
    function myGMap(){
        this.canvas = 'gmap0-map-canvas';
        this.lat = 43.7621527000;
        this.long = 2.9246927000;
        this.zoom = 7;
        
        for(var prop in arguments[0])   {
            if(this.hasOwnProperty(prop))   {
                this[prop]=arguments[0][prop];   
            }
        }
        
        mapOptions = {"center":new google.maps.LatLng( this.lat, this.long ),"zoom": this.zoom};
        console.log('set map canvas:' + this.canvas);
        console.log(this);
        
        container = document.getElementById( this.canvas );
        
        if (container)
        {
            container.style.width = '100%';
            container.style.height = '512px';
            gmap0 = new google.maps.Map(container, mapOptions);

            gmap0infoWindow = new google.maps.InfoWindow();
        }
    //    google.maps.event.addDomListener(window, 'load', initialize);
    }

    myGMap.prototype.getMap = function() {
            return gmap0;
    }
    myGMap.prototype.addMarker = function(lat, lng, title, content, iconFile) {
        count = gmarker.length;

        gmarker[count] = new google.maps.Marker({
            "map": gmap0,
            "position": new google.maps.LatLng(lat, lng),
            "title": title,
            "icon": iconFile
        });

        google.maps.event.addListener(gmarker[count], 'click', function(event){

            gmap0infoWindow.setContent( content );

            gmap0infoWindow.open(gmap0, this);
        });
    }

    myGMap.prototype.clearMarkers = function() {
      for (var i = 0; i < gmarker.length; i++) {
        gmarker[i].setMap( null );
      }
      gmarker = [];
    }

    return myGMap;

})();

and then include it in your view, probably using an asset file.

Somewhere in a view, render the map canvas, something like this

<div class="col-md-12">
        <div id="gmap0-map-canvas"></div>
    </div>
                              

Now, you have the choice of initialising the map at the bottom of the same view

$js .= "gmap0 = new myGMap({canvas: 'gmap0-map-canvas'}); ";
    // options include {
    // canvas: "element id of canvas" - defaults to gmap0-map-canvas
    // lat: latitude of center of map,
    // long: longitude of center of map,
    // zoom: zoom factor
    // }
    
    $this->registerJs($js, View::POS_READY, 'map_tab');

and then adding map Markers

$js .= "gmap0.addMarker( 43.308941, 3.346367, 'html for popup box', '/path/to/custom_icon.png');

or, in a more complex scenario, you can return the addMarkers in an Ajax call

[javascript]

        link = 'url/to/action-that-returns-just-javascript';
        gmap0.clearMarkers();
        $.getScript( link  , function( data, textStatus, jqxhr ) {
              // refresh map to get it to display new markers
              // you can also use this. if you need to refresh the map eg: when changing tabs
              setTimeout(function() {map = gmap0.getMap(); var center = map.getCenter(); google.maps.event.trigger(map, 'resize'); map.setCenter(center);}, 500);
        });

example of action-that-returns-just-javascript

public function actionThatReturnsJustJavascript()
{
    $markers = SomeModel::find()->where(some condition)->all();
    foreach($markers as $marker) {
        echo $marker->mapMarker('gmap0');
    }
}

// marker model
public function getMapMarker($gmapId)
{
    $js = $mapId.".addMarker( $this->lat, $this->lng, '{$this->title}', '$this->content', '/images/icons/$this->type.png');";
    return $js;
}

As the map canvas name is configurable, you can easily include more than one map on a page, without any conflicts between the multiple maps. This would also apply to having one map in your main page and then others in pop-ups or overlays.

Happy mapping!

0 0
3 followers
Viewed: 16 391 times
Version: 2.0
Category: How-tos
Written by: Chris Backhouse
Last updated by: Chris Backhouse
Created on: Oct 5, 2015
Last updated: 8 years ago
Update Article

Revisions

View all history

Related Articles