I found an interesting example of showing markers groups using checkboxes: link
But sometimes one place has several categories (e.g. burgers, pizzeria etc.) and this results in several icons in one place (one for burger, one for pizzeria etc.).
I replaced the checkboxes with radio buttons and only one category can be selected. Unfortunately, clicking on a category does not remove previously shown markers. I tried several methods but nothing worked.
Is it possible to hide all visible markers after clicking on a category and close the (possibly) open information window, and only then show markers only from the clicked category?
Modified code (with radio buttons) here:
$(window).load(function (){
var places={
restaurant:{
label:'restaurants',
//the category may be default-checked when you want to
//uncomment the next line
//checked:true,
icon: 'http://maps.gstatic.com/mapfiles/markers2/marker.png' ,
items: [
['Melt Bar and Grill', 41.485345, -81.799047],
['Sloane Pub', 41.486182, -81.824178],
['Spitfire Salon', 41.479670, -81.768430],
['Mahall\'s', 41.476989, -81.781094],
['Szechwan Garden', 41.485615, -81.787890]
]
},
park:{
label:'parks',
//the category may be default-checked when you want to
//uncomment the next line
checked:true,
icon: 'http://maps.gstatic.com/mapfiles/markers2/boost-marker-mapview.png',
items: [
['Lakewood Park', 41.494457, -81.797605],
['Madison Park', 41.476969, -81.781929],
['Tuland Park', 41.464052, -81.788041]
]
}
},
map = new google.maps.Map(
document.getElementById('map'),
{
zoom: 14,
center: new google.maps.LatLng(41.485345, -81.799047),
}
),
infowindow = new google.maps.InfoWindow(),
// a div where we will place the buttons
ctrl=$('<div/>').css({background:'#fff',
border:'1px solid #000',
padding:'4px',
margin:'2px',
textAlign:'center'
});
//now loop over the categories
$.each(places,function(c,category){
//a checkbox fo the category
var cat=$('<input name="xxx" type="radio">',{type:'radio'}).change(function(){
$(this).data('goo').set('map',(this.checked)?map:null);
})
//create a data-property with a google.maps.MVCObject
//this MVC-object will do all the show/hide for the category
.data('goo',new google.maps.MVCObject)
.prop('checked',!!category.checked)
//this will initialize the map-property of the MVCObject
.trigger('change')
//label for the checkbox
.appendTo($('<div/>').css({whiteSpace:'nowrap',textAlign:'left'}).appendTo(ctrl))
.after(category.label);
//loop over the items(markers)
$.each(category.items,function(m,item){
var marker=new google.maps.Marker({
position:new google.maps.LatLng(item[1],item[2]),
title:item[0],
icon:category.icon
});
//bind the map-property of the marker to the map-property
//of the MVCObject that has been stored as checkbox-data
marker.bindTo('map',cat.data('goo'),'map');
google.maps.event.addListener(marker,'click',function(){
infowindow.setContent(item[0]);
infowindow.open(map,this);
});
});
});
//use the buttons-div as map-control
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(ctrl[0]);
}
);
I'd be tempted to create an Object literal
to store references to every marker added to the map but keyed by category. With the markers so grouped it should be easy to remove a whole category's worth or markers when a new category is selected.
$(window).load(function (){
// global object to store marker references
var markers={};
var places={
restaurant:{
label:'restaurants',
icon:'http://maps.gstatic.com/mapfiles/markers2/marker.png' ,
items:[
['Melt Bar and Grill', 41.485345, -81.799047],
['Sloane Pub', 41.486182, -81.824178],
['Spitfire Salon', 41.479670, -81.768430],
['Mahall\'s', 41.476989, -81.781094],
['Szechwan Garden', 41.485615, -81.787890]
]
},
park:{
label:'parks',
checked:true,
icon:'http://maps.gstatic.com/mapfiles/markers2/boost-marker-mapview.png',
items:[
['Lakewood Park', 41.494457, -81.797605],
['Madison Park', 41.476969, -81.781929],
['Tuland Park', 41.464052, -81.788041]
]
}
},
map = new google.maps.Map(
document.getElementById('map'),
{
zoom: 14,
center: new google.maps.LatLng(41.485345, -81.799047),
}
),
infowindow = new google.maps.InfoWindow(),
ctrl=$('<div/>').css({
background:'#fff',
border:'1px solid #000',
padding:'4px',
margin:'2px',
textAlign:'center'
});
$.each( places, function( c, category ){
if( !markers.hasOwnProperty( category ) ) markers[ category ]=[];
var cat=$('<input name="xxx" type="radio">',{ type:'radio' } ).change( function(e){
// remove markers from all categories prior to adding new
markers[ category ].forEach(mkr=>mkr.setMap(null))
$(this).data('goo').set('map',( this.checked ) ? map : null );
})
.data('goo',new google.maps.MVCObject)
.prop('checked', !!category.checked )
.trigger('change')
.appendTo($('<div/>').css({ whiteSpace:'nowrap', textAlign:'left' } ).appendTo( ctrl ) )
.after( category.label );
//loop over the items(markers)
$.each(category.items,function(m,item){
var marker=new google.maps.Marker({
position:new google.maps.LatLng(item[1],item[2]),
title:item[0],
icon:category.icon
});
marker.bindTo('map',cat.data('goo'),'map');
google.maps.event.addListener( marker,'click',function(){
infowindow.setContent(item[0]);
infowindow.open(map,this);
});
// add marker to global object, keyed by cateogry
markers[ category ].push( marker )
});
});
map.controls[ google.maps.ControlPosition.TOP_RIGHT ].push( ctrl[0] );
});