Reputation: 23
I'm trying to show certain markers when a user selects a checkbox and clicks "show on map". It should show 2 markers when the "Gaudi Tour" is selected and two different markers when the "Gothic Tour" is selected. However, it isn't filtering the results in the createMarkers() function and is instead showing all the markers when the button is clicked.
I can't figure out why it's not filtering the results and I'm not getting any errors.
<section>
<div class="container">
<h2>Choose your tour:</h2>
<div class="container" id="selectTour">
<div class="form-check-inline">
<label class="form-check-label">
<input type="checkbox" class="form-check-input" id="one">Gaudi Tour
</label>
</div>
<div class="form-check-inline">
<label class="form-check-label">
<input type="checkbox" class="form-check-input" id="two">Gothic Tour
</label>
</div>
</div>
<div class="container">
<button onclick="updateMarkers();">Show on Map</button>
</div>
<!--The Map-->
<div class="container">
<div id="map"></div>
</div>
</div>
</section>
var map;
var markers = [];
//---------------------Data of Locations-----------------
let locations = [{
name: 'one',
tour: 'gaudi',
coords: { lat: 41.403706, lng: 2.173504 },
content: 'google',
},
{
name: 'one',
tour: 'gaudi',
coords: { lat: 41.4145, lng: 2.1527 },
content: 'maps',
},
{
name: 'two',
tour: 'gothic',
coords: { lat: 41.3839, lng: 2.1821 },
content: 'are'
},
{
name: 'two',
tour: 'gothic',
coords: { lat: 41.3840, lng: 2.1762 },
content: 'annoying'
}
];
//---------------------Initializing Map-----------------
function initMap() {
var mapOptions = {
center: new google.maps.LatLng(41.3851, 2.1734),
zoom: 12
};
map = new google.maps.Map(document.getElementById("map"), mapOptions);
}
//---------------------Markers-----------------
function addMarker(props) {
var marker = new google.maps.Marker({
position: props.coords,
map: map,
icon: props.iconImage
});
//checking for icon
if (props.iconImage) {
marker.setIcon(props.iconImage);
}
//checking for infowindow
if (props.content) {
var infoWindow = new google.maps.InfoWindow({
content: props.content
});
marker.addListener('click', function() {
infoWindow.open(map, marker);
});
}
}
function updateMarkers() {
createMarkers();
for (var i = 0; i < locations.length; i++) {
addMarker(locations[i]);
}
}
//---------------------Select Tour-----------------
function createMarkers() {
let selectedLocations = locations.filter(function(obj) {
var selectedTour = document.getElementById("selectTour").value;
return obj.tour === selectedTour;
});
let resultlist = [];
if (document.getElementById("one").checked) {
let one = selectedLocations.filter(function(obj) {
return obj.name === 'one';
});
resultlist = resultlist.concat(one);
}
if (document.getElementById("two").checked) {
let two = selectedLocations.filter(function(obj) {
return obj.name === 'two';
});
resultlist = resultlist.concat(two);
}
for (var i = 0; i < resultlist.length;) {
markers.push({
coords: {
lat: resultlist[i].lat,
lng: resultlist[i].lng
},
content: resultlist[i].name
});
}
}
Any advice would be a massive help.
Upvotes: 2
Views: 1582
Reputation: 33823
Based upon your original code but modified - I hope this will help you towards finding google maps a little less "annoying" '-)
<!doctype html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>Google Maps: </title>
<style>
#map{
width:100%;
height:80vh;
float:none;
margin:auto;
}
</style>
<script>
let map;
let markers=[];
let infoWindow;
let locations = [
{
name: 'one',
tour: 'gaudi',
latlng: { lat: 41.403706, lng: 2.173504 },
content: 'google',
},
{
name: 'one',
tour: 'gaudi',
latlng: { lat: 41.4145, lng: 2.1527 },
content: 'maps',
},
{
name: 'two',
tour: 'gothic',
latlng: { lat: 41.3839, lng: 2.1821 },
content: 'are'
},
{
name: 'two',
tour: 'gothic',
latlng: { lat: 41.3840, lng: 2.1762 },
content: 'annoying'
}
];
function initMap(){
let options = {
center: new google.maps.LatLng(41.3851, 2.1734),
zoom: 12
};
map = new google.maps.Map( document.getElementById('map'), options );
infoWindow = new google.maps.InfoWindow();
const addmarker=function(args){
let mkr=new google.maps.Marker({
position: args.latlng,
map: map
});
if( args.hasOwnProperty('icon') ) mkr.setIcon( args.icon );
if( args.hasOwnProperty('name') ) mkr.name=args.name;
if( args.hasOwnProperty('content') ) mkr.content=args.content;
google.maps.event.addListener( mkr, 'click', clickhandler );
return mkr;
};
const clickhandler=function(e){
infoWindow.open( map, this );
infoWindow.setContent( this.content );
};
const clearmarkers=function(){
markers.forEach( mkr=>{
mkr.setMap( null );
});
};
Array.prototype.slice.call( document.querySelectorAll('input[type="radio"][name="tour"]') ).forEach(function(input){
input.addEventListener('click', function(e){
if( this.value ){
/* clear any markers added to the map already */
clearmarkers();
/* only show those that qualify based upon selected tour */
locations.forEach( obj=>{
if( obj.tour==this.value ) markers.push( addmarker.call( this, obj ) );
});
}
});
});
}
</script>
<script async defer src='//maps.googleapis.com/maps/api/js?key=APIKEY&callback=initMap'></script>
</head>
<body>
<form>
<!--
if you use `radio` buttons instead of checkboxes then you ensure
that only 1 tour type can be selected at once.
You may note that there is also a hidden field with the same
name before the radio buttons - not strictly necessary in this
case but is a useful trick in some circumstances.
-->
<section>
<div class='container'>
<h2>Choose your tour:</h2>
<input type='hidden' name='tour' value=false />
<div class='container'>
<div class='form-check-inline'>
<label class='form-check-label'>
<input name='tour' value='gaudi' type='radio' class='form-check-input' />Gaudi Tour
</label>
</div>
<div class='form-check-inline'>
<label class='form-check-label'>
<input name='tour' value='gothic' type='radio' class='form-check-input' />Gothic Tour
</label>
</div>
</div>
<!--The Map-->
<div class='container'>
<div id='map'></div>
</div>
</div>
</section>
</form>
</body>
</html>
Upvotes: 2