Advanced Google Maps with JavaScript: Filtering and Displaying Information

Follow us on LinkedIn for our latest data and tips!

In our previous post about building interactive maps with Python and Javascript we learned how to create a GeoJSON dataset of campgrounds and display information on a Google Map with markers, using the Google Maps JavaScript API. We’re going to build on that foundation in today’s post by showing you how to use some more advanced techniques that are not discussed in Google’s documentation. To create a more customized user experience, we are going to learn how to filter markers and how to display marker GeoJSON outside of the Google Maps object.

We will be building out this Yelp-like interface for finding campgrounds. Similar to Yelp, you can filter your results, and when you click a marker on the map the information for that campground will be displayed below the map. Try it out!

See the Pen Map with Buttons and Display by Sev (@sevleonard) on CodePen.

Filtering Markers

In the previous post we used the loadGeoJson method to populate the markers on our map. For this example, we are going to use the jQuery getJson method.

$.getJSON(geojson_url, function(result) {
   // get the features array from the FeatureCollection 
   data = result['features']
   $.each(data, function(key, val) {
      // create markers

We’ve made a modification to the GeoJSON file we were previously using to include specific properties for the amenity fields. These properties are what we will use to filter the markers.


To keep track of what amenities the user wants to filter on lets create a list of possible filters, using the same names as we have for the new property fields:

// start out with filter features set to false, so no filtering happens by default
var filters = {shower:false, vault:false, flush:false}

Now, whenever we want to set marker visibility based on filter settings, we simply iterate through the array of markers and compare the properties field to the filters that are set to ‘true’:

// get a subset of the filters that are set to true
var get_set_options = function() {
  ret_array = []
  for (option in filters) {
    if (filters[option]) {
  return ret_array;

var filter_markers = function() {  
  set_filters = get_set_options()
  // for each marker, check to see if all required options are set
  for (i = 0; i < markers.length; i++) {
    marker = markers[i];

    // start the filter check assuming the marker will be displayed
    // if any of the required features are missing, set 'keep' to false
    // to discard this marker
    for (opt=0; opt<set_filters.length; opt++) {
      if (![set_filters[opt]]) {
        keep = false;

Since we only want to check the properties that are set to ‘true’ in the filters list, we first call ‘get_set_options’ to return that subset of filters. We then iterate through the markers and check that the filtered value is ‘true’ in the GeoJSON, and if not we set ‘keep’ to ‘false’ to make the marker invisible, thus filtering it out of the current map view.

Because we matched the values in the ‘properties’ field to the names in the ‘filters’ list we simply have to check using the name from the ‘filters’ list. A single iteration of the above would look like[filters[opt]]

// for opt = 0
// set_filters[0] -> 'shower'
// -> 'flush':true, 'shower':true, 'vault':false
//['shower'] evaluates to true

Setting the Filters

Now that we’ve seen how to filter markers, we need to connect the filter selection the UI so users can set and unset filter options. First, we need to provide a way for the user to select different features to filter on.

See the Pen Map with Buttons by Sev (@sevleonard) on CodePen.

Instead of using buttons, we will use checkboxes styled as buttons using a ‘label’ entity. This gives the UI a clean look while providing boolean functionality to use for setting the filters. We’ll use CSS as detailed in this StackOverflow post to style the checkboxes as buttons.

 <input type="checkbox" name="filter" id="shower" class='chk-btn'>
 <label for='shower'>Shower</label>

<input type="checkbox" name="filter" id="flush" class='chk-btn'>
 <label for='flush'>Flush Toilet</label>
 <input type="checkbox" name="filter" id="vault" class='chk-btn'>
 <label for='vault'>Vault Toilet</label>

Notice that we have set the name to ‘filter’ for the checkbox inputs. By using a uniform ‘name’ attribute for all of our filter checkboxes we can use a single function to handle all of their change events:

$('input[name=filter]').change(function (e) {
      // update filters list

On the ‘change’ event, we can get the ‘id’ attribute of the current checkbox to set the filter, noticing that we used the same value in ‘id’ as we did for our ‘filters’ list. Because we matched these values, we can query the ‘filters’ list for the ‘id’ value of the current checkbox (accessed via ‘this’) and toggle the value of the filter.

// filters list: var filters = {shower:false, vault:false, flush:false}
var map_filter = function(id_val) {
   if (filters[id_val]) 
      filters[id_val] = false
      filters[id_val] = true

$('input[name=filter]').change(function (e) {

We now have a way for the user to set the filters via button-styled checkboxes, and for the filters to be applied to the markers using the ‘filter_markers’ function. We just need a connection between the two to perform the filtering.

<button class="btn btn-blue" id="search_campgrounds">Find Campgrounds</button>

When the user clicks ‘Find Campgrounds’ we execute the ‘filter_markers’ function.

$('#search_campgrounds').on('click', function() {

Try it out!

See the Pen Map with Buttons by Sev (@sevleonard) on CodePen.

Displaying Marker Info

Info windows are helpful for showing details for a point on the map, but they also hide the surrounding area. Since our users probably want to see the area around the campground it would be better to display the marker ‘description’ in a different place that doesn’t obscure the map.

To do this, lets revisit the ‘loadMarkers’ function from the previous codepen, in particular the ‘addListener’ function:

function loadMarkers() {
   var descriptionText = feature.getProperty('description')
   var titleText = feature.getProperty('title')
   var markerInfo = "<div><h3>" + titleText + "</h3>Amenities: " + descriptionText + "</div>"
   marker.addListener('click', function() {
      infoWindow.setContent(markerInfo), marker)

Instead of setting an infoWindow when we click a marker, we want to display the markerInfo in another part of the DOM. First lets provide a home for that information:

 <div id="campground_info"></div>

Since we’ve already created the HTML formatting for the markerInfo, we can simply set the html attribute of the campground_info div in the ‘click’ listener, instead of creating the infoWindow:

marker.addListener('click', function() {

Now, when we click on each campground we will see the ‘description’ information displayed below the map in the campground_info div:

See the Pen Map with Buttons and Display by Sev (@sevleonard) on CodePen.


We’ve learned how to add filtering to Google Maps markers and display marker information outside of the map. By using GeoJSON properties in the ‘id’ fields of our filter checkboxes and for the values in our ‘filters’ list we were able to quickly put together this prototype.  Standardizing values in this way really simplifies the coding process, and results in code that reads easily. We can leverage this because we own the entire stack from GeoJSON generation to the front end – be careful about using these techniques if someone else is providing the source information, as fields in the GeoJSON could change. In that case you would want to provide a translation function to provide a consistent interface to your UI regardless of changes in the underlying GeoJSON.

Some fun extras you could try out with the code we developed in this post:

  • Change the marker, the marker label, or animate the marker on click. This will help the user keep track of which campground’s information they are seeing in the campground_info div.
  • What if we couldn’t change the GeoJSON? What are other ways you could filter based on amenities without the ‘flush’,’shower’,and ‘vault’ properties? (hint: consider the other ‘properties’ fields).
  • Add a button to clear the filters so the user doesn’t have to un-check filters.