Reputation: 257
I am attempting to create a filter for some dynamic markers on a Google map. The user selects which markers they would like to filter with various check box selections relating to each marker category.
I would like some advice on my current code as I am hoping that I am quite close. I am aware that there are a number of similar questions on here although they all seem to follow an xml google map tutorial which I am not following and have taken the JSON / $.each route rather than generating XML and for loops to set the markers position.
From reading the related questions, I have tried to create an array that groups the markers by their category and then based on which check boxes are selected should hide or unhide these markers.
Currently when I run the code the checkboxes are frozen on check and do not uncheck. When I remove the onClick from the html the issue is resolved, although this then doesn't call the funtion.
I get a javascript error that the toggleGroup function is not defined. I don't understand why as it is supposed to be defined by the checkbox id.
JS
var customIcons = [];
customIcons["1"] = 'img/32x32/border_edits/Automotive.jpg';
customIcons["2"] = 'img/32x32/border_edits/BarPub.jpg';
customIcons["3"] = 'img/32x32/border_edits/Cinema.jpg';
var markerGroups = {
"1": [],
"2": [],
"3": []
};
$(document).on("pageshow","#map-page",function(){
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(success);
} else {
error('Geo Location is not supported');
}
function success(position) {
var coords = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var options = {
zoom: 16,
center: coords,
mapTypeControl: false,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.SMALL
},
disableDefaultUI:true,
zoomControl:true,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"), options);
var marker = new google.maps.Marker({
position: coords,
icon: 'img/gps_marker.jpg',
map: map,
});
$.post( "getrow.php?getjson", function( data ) {
var data = JSON.parse(data);
console.log(data);
$.each(data, function(index, value){
var id = value.site_id;
var type = value.prime_category;
var point = new google.maps.LatLng(value.lat, value.lon);
var name = value.site_name;
var address = value.site_address;
var icon = customIcons[type] || {};
var marker = createMarker(point, name, address, type, id);
});
});
function createMarker(point, name, address, type, id) {
var marker = new google.maps.Marker({
map: map,
position: point,
icon: customIcons[type],
id: id
});
markerGroups[type].push(marker);
var html = "<b>" + name + "</b> <br/>" + address;
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(html);
infoWindow.open(map, marker);
});
return marker;
}
function toggleGroup(type){
if($('#'+type).is(':checked')){
for(var i=0;i<markerGroups[type].length;i++){
markerGroups[type][i].setVisible(true);
}
}
else{
for(var i=0;i<markerGroups[type].length;i++){
markerGroups[type][i].setVisible(false);
}
}
}
}
});
HTML
I have the checkboxes in a jquery mobile dialog page that is linked in the header of the map page
<div data-role="page" id="map-page">
<div data-role="header" id="appheader" data-position="fixed">
<h1>
<a href="#preferences" data-role="button" class="ui-btn-right" data-rel="dialog" data-icon="gear" data-iconpos="notext" data-inline="true"></a>
</h1>
</div>
<div id="appcontent">
<div id="map">
</div>
</div>
</div>
<div data-role="page" id="preferences">
<div data-role="header">
<h1>Filter</h1>
</div>
<div data-role="content">
<div class="ui-grid-a">
<div class="ui-block-a">
<label for="1">Automotive</label>
<input type="checkbox" id="1" onClick="toggleGroup(this.id)" checked>
<label for="3">Cinema</label>
<input type="checkbox" id="3" onClick="toggleGroup(this.id)" checked>
<label for="5">Dining Out</label>
<input type="checkbox" id="5" onClick="toggleGroup(this.id)" checked>
</div>
</div>
</div>
</div>
CSS
html, body {
margin: 0;
width: 100%;
height: 100%;
}
#appcontent{
width: 100%;
height: 100%;
}
#map{
position: absolute;
top: 40px;
left: 0px;
right: 0px;
bottom: 0px;
}
#appheader{
position: absolute;
top: 0px;
left: 0px;
right: 0px;
height: 40px;
background-color: #00a2e8;
}
Any help and advice would be greatly appreciated.
Upvotes: 0
Views: 3874
Reputation: 257
I managed to resolve this problem. Rather than call the function from the onClick of each checkbox in html. I used $(":checkbox").change to call the function and use this.id to define the marker's type. Thanks to @Clayton Leis for that suggestion.
JS
function createMarker(point, name, address, type, id) {
var marker = new google.maps.Marker({
map: map,
position: point,
icon: customIcons[type],
id: id
});
markerGroups[type].push(marker);
var html = "<b>" + name + "</b> <br/>" + address;
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(html);
infoWindow.open(map, marker);
});
return marker;
}
$(":checkbox").change(function toggleGroup(){
var type = this.id;
if($('#'+type).is(':checked')){
for(var i=0;i<markerGroups[type].length;i++){
markerGroups[type][i].setVisible(true);
}
}
else{
for(var i=0;i<markerGroups[type].length;i++){
markerGroups[type][i].setVisible(false);
}
}
});
One remaining problem I have is that the checkboxes are on a dialog page using jquery mobile in the html. When the page is closed it refreshes the html which resets the checkboxes. It seems like this is a well known problem with dialog pages in jquery mobile but when I put the checkbox code in the map page the code above works perfectly. Thanks for the help everyone.
Upvotes: 1
Reputation: 91
I made a similar checkbox months ago. I think your code is right
You just need something like this in you HTML (your code seems to be good):
<input id="1" type="checkbox" onchange="filterMarkers(this.id)"/>
And the javascript. I used setVisible(bool), this could be your problem:
function filterMarkers(type){
if($('#'+type).is(':checked')){
for(var i=0;i<mapMarkers[type].lenght;i++){
mapMarkers[type][i].setVisible(true);
}
}
else{
for(var i=0;i<mapMarkers[type].lenght;i++){
mapMarkers[type][i].setVisible(false);
}
}
I assume that you obtain correctly the values in your AJAX call. By the console error, you must probably have some problem there.
Have you tried to see which are the values inside this loop?
var data = JSON.parse(data);
console.log(data);
$.each(data, function(index, value){
// Do a console.log(value)
var id = value.site_id;
var type = value.prime_category;
var point = new google.maps.LatLng(value.lat, value.lon);
var name = value.site_name;
var address = value.site_address;
var icon = customIcons[type] || {};
var marker = createMarker(point, name, address, type, id);
});
You're declaring a new var called 'data', same as the variable that comes from the function. It could be a problem.
Upvotes: 0