Advanced Custom Fields: Google Map Markers with Filters

Advanced Custom Fields: Google Map Markers with Filters

Please Note

This is a follow up article. Please make sure you have already checked the previous article » Create Google Map with Multiple Dynamic Markers Using Advanced Custom Fields

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.

Last Updated: June 7, 2020

Al-Mamun Talukder

About Al-Mamun Talukder

WordPress Developer. Minimalist Designer. Tech Enthusiast. Music & Movie Freak. Loves Cars. Founder of WolfDevs.

Connect with me: Upwork, GitHub, Facebook, Twitter