Google Maps Marker Filtering

I have the following jsfiddle:

http://jsfiddle.net/inkedraskal/zeLon7cs/2/

You'll notice when the map loads all the points are showing, and filtering on its own seems to work correctly. However, when you click a filter, (project for example), it will show only projects, but if you click it again, it wont reset the markers. As well as, if you say click News and then Stuff, then click Stuff again, it wont show the markers only applying to news again (still shows markers that apply to both News and Stuff, instead of just News).

Any tips would greatly be appreciated.

I have create a list-items to filter the markers on click

<div class="filters">
  <ul>
      <li>
          <a href="#" data-filterby="type" data-filtervalue="project">Projects</a>
      </li>
      <li>
          <a href="#" data-filterby="type" data-filtervalue="news">News</a>
      </li>
      <li>
          <a href="#" data-filterby="type" data-filtervalue="stuff">stuff</a>
      </li>
  </ul>
  <ul>
      <li>
          <a href="#" data-filterby="date" data-filtervalue="201401">Jan</a>
      </li>
      <li>
          <a href="#" data-filterby="date" data-filtervalue="201402">Feb</a>
      </li>
      <li>
          <a href="#" data-filterby="date" data-filtervalue="201403">Mar</a>
      </li>
  </ul>
</div>
<div class="clear"></div>

at the bottom my JS you'll see the following:

$(document).on('click', '.filters a', function (event) {
     event.preventDefault();
     var $target = $(event.target);
     var type = $target.data('filterby');
     var value = $target.data('filtervalue');
     $(this).toggleClass('active');
     $.each(map.markers, function () {
         if (this.filter[type] && this.filter[type].indexOf(value.toString()) >= 0) {
             if (this.map == null) {
                  this.setMap(map);
             }
         } else {
             this.setMap(null);
         }
     });
});

Answers 1

  • In your loop to hide/show each marker, for each individual marker you are only checking if that marker has the clicked on filter value. You need to check each marker against every active filter.

     $(document).on('click', '.filters a', function(event) {
      event.preventDefault();
    
      $(this).toggleClass('active');
    
      // create an array of active filters
      var activeFilters = [];
      $(".filters a.active").each(function() {
        activeFilters.push({
          by: $(this).data("filterby"),
          value: $(this).data("filtervalue").toString()
        });
      });
    
      if (activeFilters.length === 0) { // if there are no active filters, show all markers
        for (var i = 0; i < map.markers.length; i++) {
          map.markers[i].setMap(map);
        }
      } else {
        for (var i = 0; i < map.markers.length; i++) { // for each marker
          var marker = map.markers[i]; // just to make the next code easier
    
          var missingActiveFilter = false;
          // check if marker has every active filter
          for (var j = 0; j < activeFilters.length; j++) {
            var filter = activeFilters[j];
            if (filter.by === "type" && marker.filter.type.indexOf(filter.value) === -1 || filter.by === "date" && marker.filter.date.indexOf(filter.value) === -1) {
              missingActiveFilter = true;
              break;
            }
          }
    
          if (missingActiveFilter) {
            marker.setMap(null);
          } else {
            marker.setMap(map);
          }
    
        }
      }
    });
    

    });

    Updated JSFiddle


Related Articles