Google Map

Overview

The Google Map field creates an interactive map with the ability to place a marker. This field features a search input, location finder button and click/drag events to place the marker. The data saved and returned is an array containing the markers lat, lng, and address.

The Google Maps API has a daily limit on the number of sites able to use this free service. To lift this restriction, please register a Google API key following the steps documented later in this article.

Changelog

  • ‘acf/fields/google_map/api’ filter added in version 4.3.9 (ACF) and 5.3.10 (ACF PRO)

Screenshots

Settings

Name Description
Center Enter a default lat and lng value to center the map on a desired location when no marker has been saved
Zoom Set the zoom level for this map
Height Set a custom height for the map. This is useful for making a smaller sized map for use as a sub field

Google Map API

It may be necessary to register a Google API key in order to allow the Google API to load correctly. Please follow this link to get a Google API key.

To register your Google API key, please use the ‘acf/fields/google_map/api’ filter like so:

functions.php

function my_acf_google_map_api( $api ){
	
	$api['key'] = 'xxx';
	
	return $api;
	
}

add_filter('acf/fields/google_map/api', 'my_acf_google_map_api');

If using ACF PRO, you may find it easier to update the ‘google_api_key’ setting instead:

functions.php

function my_acf_init() {
	
	acf_update_setting('google_api_key', 'xxx');
}

add_action('acf/init', 'my_acf_init');

Template usage

The following code examples show how to display saved values onto a map.

Please also note that the Google API is required for this to work and is included in the required JS below. The Google Map API is a great library to render a map, however, it is not the only API available. Please consult Google for any other API’s and tutorials.

Helpers

Both examples below require the following CSS and JS to be available to the page template. Please note that both the CSS and JS can be modified to your liking, however they are a good starting point to understand how the PHP data can be translated through HTML into the JS Google Map API.

<style type="text/css">

.acf-map {
	width: 100%;
	height: 400px;
	border: #ccc solid 1px;
	margin: 20px 0;
}

/* fixes potential theme css conflict */
.acf-map img {
   max-width: inherit !important;
}

</style>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
<script type="text/javascript">
(function($) {

/*
*  new_map
*
*  This function will render a Google Map onto the selected jQuery element
*
*  @type	function
*  @date	8/11/2013
*  @since	4.3.0
*
*  @param	$el (jQuery element)
*  @return	n/a
*/

function new_map( $el ) {
	
	// var
	var $markers = $el.find('.marker');
	
	
	// vars
	var args = {
		zoom		: 16,
		center		: new google.maps.LatLng(0, 0),
		mapTypeId	: google.maps.MapTypeId.ROADMAP
	};
	
	
	// create map	        	
	var map = new google.maps.Map( $el[0], args);
	
	
	// add a markers reference
	map.markers = [];
	
	
	// add markers
	$markers.each(function(){
		
    	add_marker( $(this), map );
		
	});
	
	
	// center map
	center_map( map );
	
	
	// return
	return map;
	
}

/*
*  add_marker
*
*  This function will add a marker to the selected Google Map
*
*  @type	function
*  @date	8/11/2013
*  @since	4.3.0
*
*  @param	$marker (jQuery element)
*  @param	map (Google Map object)
*  @return	n/a
*/

function add_marker( $marker, map ) {

	// var
	var latlng = new google.maps.LatLng( $marker.attr('data-lat'), $marker.attr('data-lng') );

	// create marker
	var marker = new google.maps.Marker({
		position	: latlng,
		map			: map
	});

	// add to array
	map.markers.push( marker );

	// if marker contains HTML, add it to an infoWindow
	if( $marker.html() )
	{
		// create info window
		var infowindow = new google.maps.InfoWindow({
			content		: $marker.html()
		});

		// show info window when marker is clicked
		google.maps.event.addListener(marker, 'click', function() {

			infowindow.open( map, marker );

		});
	}

}

/*
*  center_map
*
*  This function will center the map, showing all markers attached to this map
*
*  @type	function
*  @date	8/11/2013
*  @since	4.3.0
*
*  @param	map (Google Map object)
*  @return	n/a
*/

function center_map( map ) {

	// vars
	var bounds = new google.maps.LatLngBounds();

	// loop through all markers and create bounds
	$.each( map.markers, function( i, marker ){

		var latlng = new google.maps.LatLng( marker.position.lat(), marker.position.lng() );

		bounds.extend( latlng );

	});

	// only 1 marker?
	if( map.markers.length == 1 )
	{
		// set center of map
	    map.setCenter( bounds.getCenter() );
	    map.setZoom( 16 );
	}
	else
	{
		// fit to bounds
		map.fitBounds( bounds );
	}

}

/*
*  document ready
*
*  This function will render each map when the document is ready (page has loaded)
*
*  @type	function
*  @date	8/11/2013
*  @since	5.0.0
*
*  @param	n/a
*  @return	n/a
*/
// global var
var map = null;

$(document).ready(function(){

	$('.acf-map').each(function(){

		// create map
		map = new_map( $(this) );

	});

});

})(jQuery);
</script>

Render a single marker onto a map

This example shows how to use a single Google Map field to render out a map and marker onto the page.Each marker contains no inner HTML, so no infoWindow will be created (using the above JS)

<?php 

$location = get_field('location');

if( !empty($location) ):
?>
<div class="acf-map">
	<div class="marker" data-lat="<?php echo $location['lat']; ?>" data-lng="<?php echo $location['lng']; ?>"></div>
</div>
<?php endif; ?>

Render multiple markers onto a map

This example shows a repeater field (called ‘locations’) with 3 sub fields; title (text), description (textarea) and location (Google Map).

Each marker does contain inner HTML, so an infoWindow will be created (using the above JS)

<?php if( have_rows('locations') ): ?>
	<div class="acf-map">
		<?php while ( have_rows('locations') ) : the_row(); 

			$location = get_sub_field('location');

			?>
			<div class="marker" data-lat="<?php echo $location['lat']; ?>" data-lng="<?php echo $location['lng']; ?>">
				<h4><?php the_sub_field('title'); ?></h4>
				<p class="address"><?php echo $location['address']; ?></p>
				<p><?php the_sub_field('description'); ?></p>
			</div>
	<?php endwhile; ?>
	</div>
<?php endif; ?>

Solving the hidden map issue

The Google map API will not work as expected if initialized on a hidden element. When the element is show, the map will not display. This scenario is most likely when using a popup modal.

To solve this problem, simply trigger the ‘resize’ event on the map variable after the map element is visible.

// popup is shown and map is not visible
google.maps.event.trigger(map, 'resize');

Related