Today I am going to extend the last tutorial that I posted about creating Google Map with Advanced Custom Fields, which had dynamic markers. In this tutorial, I will add an extra feature to the map so that we can filter the markers with simple checkbox.
What We Need to Update?
We will basically need to update two parts of our last code to add the filter feature and some CSS styles as you need.
- The Shortcode function
- The gmaps.js file
The Shortcode
The following code is for the shortcode. It is similar to what we already created, just some parts are added. New added parts are commented for your convenience.
// Locations Map Shortcode - [locations_map_filtered]
function locations_map_filtered (){
$args = array(
'post_type' => 'location',
'posts_per_page' => -1,
);
$locations_query = new WP_QUERY($args);
if ( $locations_query->have_posts() ) {
ob_start(); ?>
<!-- Filter Checkboxes -->
<div class="marker-filter">
<span class="filter-box">
<label for="regular">
<input type="checkbox" name="regular" value="regular" id="regular" checked onchange="filterMarker(this.value);">
Regular
</label>
</span>
<span class="filter-box">
<label for="special">
<input type="checkbox" name="special" value="special" id="special" checked onchange="filterMarker(this.value);">
Special
</label>
</span>
<span class="filter-box">
<label for="upcoming">
<input type="checkbox" name="upcoming" value="upcoming" id="upcoming" checked onchange="filterMarker(this.value);">
Upcoming
</label>
</span>
</div>
<!-- Filter Checkboxes -->
<div class="acf-map" style="overflow: hidden; position: relative;">
<?php while ( $locations_query->have_posts() ) {
$locations_query->the_post();
$address = get_field('address');
$title = get_the_title();
$outlet_type = get_field('outlet_type');
$phone = get_field('phone');
if ($outlet_type == 'regular') {
$type_icon = get_stylesheet_directory_uri().'/images/green-marker.png';
$outlet_text = 'Regular Outlet';
} elseif ($outlet_type == 'special') {
$type_icon = get_stylesheet_directory_uri().'/images/red-marker.png';
$outlet_text = 'Special Outlet';
} else {
$type_icon = get_stylesheet_directory_uri().'/images/gray-marker.png';
$outlet_text = 'Upcoming Outlet';
}
?>
<div class="marker" data-type="<?php echo $outlet_type; ?>" data-lat="<?php echo $address['lat']; ?>" data-lng="<?php echo $address['lng']; ?>" data-img="<?php echo $type_icon; ?>">
<!-- Added data-type New!-->
<div class="inside-marker">
<h5><?php echo $title; ?></h5>
<?php
echo $outlet_text.'<br>';
if($phone) {
echo 'Phone: '.$phone;
}
?>
</div>
</div>
<?php } ?>
</div>
<?php wp_reset_postdata();
}
return ob_get_clean();
}
add_shortcode( 'locations_map_filtered', 'locations_map_filtered' );
Code language: HTML, XML (xml)
The “gmaps.js” File
This file has some significant changes. We are calling a new function filterMarker to trigger the change based on the change of the filter checkboxes. The function takes the passed value from the checkbox and uses that to determine which checkbox was checked/unchecked. Based on that activity, the markers are simply shown & hidden. Here is the full code for the gmaps.js file
(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') );
var icon = $marker.attr('data-img');
var type = $marker.attr('data-type');
// create marker
var marker = new google.maps.Marker({
position : latlng,
map : map,
icon : icon,
type : type
});
// 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 );
});
}
}
/*
* Marker Filter - NEW!
*/
filterMarker = function (id) {
for (i = 0; i < map.markers.length; i++) {
marker = map.markers[i];
if (document.getElementById(id).checked) {
if (marker.type == id) {
marker.setVisible(true);
}
} else {
if (marker.type == id) {
marker.setVisible(false);
}
}
}
}
/*
* 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) );
});
//zoom
google.maps.event.addListener( map, 'zoom_changed', function( e ) {
var zoom = map.getZoom();
if(zoom!= 5)
{
var bounds = map.getBounds();
myLatLngss = [];
$.each( map.markers, function( i, marker ){
var myLatLng = new google.maps.LatLng(marker.position.lat(), marker.position.lng() );
if(bounds.contains(myLatLng)===true) {
myLatLngss.push( myLatLng );
}
else {
}
});
if(myLatLngss.length > 0)
{
document.cookie = "coordn="+myLatLngss;
$("#customzm").load(location.href + " #customzm");
}
}
});
google.maps.event.addListener(map, 'dragend', function() {
//alert('map dragged');
var bounds = map.getBounds();
myLatLngss = [];
$.each( map.markers, function( i, marker ){
var myLatLng = new google.maps.LatLng(marker.position.lat(), marker.position.lng() );
if(bounds.contains(myLatLng)===true) {
myLatLngss.push( myLatLng );
}
else {
}
if(myLatLngss.length > 0)
{
document.cookie = "coordn="+myLatLngss;
$("#customzm").load(location.href + " #customzm");
}
});
} );
});
})(jQuery);
Code language: JavaScript (javascript)
FYI, the updates are made on line 73 and line 104-123.
A Bit of CSS
You will need to add some CSS to make the checkboxes appear nice. Let’s do that.
.filter-box {
padding: 5px 10px;
border: 1px solid #e8e8e8;
margin-right: 10px;
}
Code language: CSS (css)
The Output

Hope you liked this tutorial. Feel free to post your feedback and share with your friends.
12 comments
Mathieu
Hi mate,
Thanks so much for the tutorial, it was a great help for my projet.
Quick question though, maybe you’ll have the answer :
How do I set default visibility of the markers ? I have two filters and I’d like to have one of them unchecked by default (markers hidden). I replaced the tag in the php file (“checked” by “unchecked”), so the checkbox is indeed unchecked but the marker is still showing on default view. Once i click (check) and click again (uncheck) the filter, it disappears, but I don’t find the solution to hide it right at the beginning.
Any idea ?
Cheers
Mark
How to make all markers inactive / invisible at the start? I delete checked from inputs type checkbox. I have inactive checkboxes but markers map are visible.
Arjun Kushwah
HI and how we setup it for dropdown, i mean select options
thank you
Al-Mamun Talukder
Just change the markup to a select field.
Sarah
Thank you so much! This was super helpful! I was wondering if you knew of a way to Filter by having the options in a select dropdown verses individual checkboxes?
Chris
Is there a way to integrate multiple filters for, say, 3 different ACF fields?
Al-Mamun Talukder
Yes possible. If you take a look at the form code, it is executing the “filterMarker” function. You can simply mimic that for your new fields.
Martin
I’m making a site where admins can place markers and draw routes, how would you integrate the drawing tool?
Al-Mamun Talukder
Drawing routes is out of the scope of this tutorial. Please check the Google Maps documentation.
rob w
This is awesome. How do you do this without a shortcode?
Al-Mamun Talukder
If you want to do it without shortcode, you may make a template and use the code there. Please note, you will need to slightly modify the code.
Kenny
These tutorials have been amazing! Thank you. I got the filtering working for one set of checkboxes. Any ideas about filtering for multiple criteria? For example, in addition to Outlet Type, also having a few filters for Outlet Rating or something else. I tried it on my own but couldn’t get the new checkboxes to actually trigger something. The old ones kept working though. Would love your help!