Vue google maps infowindow custom buttons not working - javascript

Hey vue-ers!
I am using vue2-google-maps with all its glories and so far I have managed a lot except for custom buttons within an info-window. So far I can click on a marker and it shows the related custom info-window with the right info. The only thing I am missing now is making those buttons work. For example the close button: I can click on it and it speaks to the component method but does not close it. The close button works the same as selecting the markers, but at the same time it's not? The values update to false, but not being updated in the maps, while I select a marker it updates like a charm. So I am quite stuck here and fairly confused, any help, ideas and tips are appreciated!
Here is my code for reference:
Template
<gmap-map
id="map"
:center="center"
:zoom=13
:options="{
disableDefaultUI: true,
zoomControl: true,
clickableIcons: true,
}">
<gmap-marker
v-for="(location, index) in locations"
:position="{lat: location.latitude, lng: location.longitude}"
:icon="location.icon"
:zone="location.zone"
:jettyNumber="location.jettyNumber"
:selected="location.selected"
:zIndex="location.zIndex"
#mouseover="mouseOverMarker(index)"
#mouseout="mouseOutMarker(index)"
#click="openInfoWindow(index)"
:label="{
text: location.jettyNumber.toString(),
color: '#fff',
fontSize: '13px',
fontFamily: 'din_round_otbold'
}">
<gmap-info-window
:opened="location.infoBoxOpen">
<div class="infoWindow" style="width: 300px;">
<div id="dock-zone" :class="getZoneClass(location.zone)">{{ getZoneClassText(location.zone) }}</div>
<h2 id="infoWindow-location">{{ location.name }}</h2>
<div id="close-btn" #click="closeInfoWindow(index)"></div>
<a class="btn btn-primary google-maps-infowindow-button">Kies als <b>{{ inputData.label }}</b></a>
<span></span>
</div>
</gmap-info-window>
</gmap-marker>
</gmap-map>
Component Script
import $ from "jquery";
export default {
data: function(){
return {
icons: {
stopInner: {
icon: process.env.VUE_APP_PUBLIC_URL + '/Assets/images/pinpoint_on_map_inner.svg'
},
stopOuter: {
icon: process.env.VUE_APP_PUBLIC_URL + '/Assets/images/pinpoint_on_map_outer.svg'
},
stopOutside: {
icon: process.env.VUE_APP_PUBLIC_URL + '/Assets/images/pinpoint_on_map_outside.svg'
},
stopSelected: {
icon: process.env.VUE_APP_PUBLIC_URL + '/Assets/images/pinpoint_on_map_active.svg'
}
},
locations: [],
center: {lat: 51.9004, lng: 4.46849},
inputData: {}
};
},
methods: {
initMap(locations, inputData) {
// Set maps specific data
for(var i = 0; i < locations.length; i++) {
locations[i].selected = false;
locations[i].infoBoxOpen = false;
locations[i].zIndex = locations[i].jettyNumber;
locations[i].icon = this.getIcon(locations[i].zone);
}
this.inputData = inputData;
this.locations = locations;
},
getIcon(zone) {
switch(zone){
case "centre":
return this.icons.stopInner.icon;
break;
case null:
return this.icons.stopOutside.icon;
break;
default:
return this.icons.stopOuter.icon;
break;
}
},
getZoneClass(zone) {
switch(zone){
case "centre":
return "centrum";
break;
case null:
return "buiten";
break;
default:
return "";
break;
}
},
getZoneClassText(zone) {
if(zone){
return zone;
}else{
return "outside";
}
},
// TODO: Not really setting the zindex, need to dig deeper
mouseOverMarker(locationIndex) {
this.locations[locationIndex].zIndex = 99998;
},
mouseOutMarker(locationIndex) {
this.locations[locationIndex].zIndex = this.locations[locationIndex].jettyNumber;
},
openInfoWindow(location){
this.center = {lat: location.latitude, lng: location.longitude};
this.setSelectedLocation(location);
},
setSelectedLocation(selectedLocationIndex){
this.unselectLocations();
// Set selected
this.locations[selectedLocationIndex].zIndex = 88888;
this.locations[selectedLocationIndex].icon = this.icons.stopSelected.icon;
this.locations[selectedLocationIndex].selected = true;
this.locations[selectedLocationIndex].infoBoxOpen = true;
this.center = {
lat: this.locations[selectedLocationIndex].latitude,
lng: this.locations[selectedLocationIndex].longitude
};
this.alterDefaultInfoWindowStyle();
},
unselectLocations() {
for(var i = 0; i < this.locations.length; i++) {
this.locations[i].icon = this.getIcon(this.locations[i].zone);
this.locations[i].zIndex = this.locations[i].jettyNumber;
this.locations[i].selected = false;
this.locations[i].infoBoxOpen = false;
}
},
alterDefaultInfoWindowStyle() {
// TODO: a very nasty fix, need a better way to handle this
setTimeout(function(){
var iwOuter = $('.gm-style-iw');
iwOuter.parent().parent().css({ top: '20px' });
iwOuter.css({ top: '0px' });
iwOuter.css({ left: '26px' });
var iwBackground = iwOuter.prev();
iwBackground.css({ 'display': 'none' });
var iwCloseBtn = iwOuter.next();
iwCloseBtn.hide();
iwOuter.children().eq(0).css({ overflow: 'visible' });
}, 10);
},
closeInfoWindow(selectedLocationIndex) {
this.unselectLocations();
},
closeMaps() {
this.$emit('close-maps')
}
}
}

Since the appearance of info window is determined by locations[index].infoBoxOpen the standard close handler (#closeclick) needs to be implemented as well, like this:
<gmap-info-window
:opened="location.infoBoxOpen"
#closeclick="location.infoBoxOpen=false">
...
</gmap-info-window>
I would also propose to modify the way how info window is created. Instead of creating info window per marker, to create only a single instance of info window. In addition to performance benefits it would make it more clear to manage info window state, for example:
<gmap-map :center="center" :zoom="zoom" ref="map">
<gmap-marker
:key="index"
v-for="(location,index) in locations"
:position="{lat: location.lat,lng:location.lng}"
:clickable="true"
#click="openInfoWindow(location)"
/>
<gmap-info-window v-if="selectedLocation !== null" :position="{lat: selectedLocation.lat,lng:selectedLocation.lng}" :opened="infoBoxOpen" #closeclick="closeInfoWindow()">
<div class="infoWindow">
<h2 id="infoWindow-location">{{ selectedLocation.name }}</h2>
<button #click="closeInfoWindow()">Close</button>
</div>
</gmap-info-window>
</gmap-map>
export default {
data: () => ({
zoom: 5,
center: { lat: 59.339025, lng: 18.065818 },
selectedLocation: null,
infoBoxOpen: false,
locations: [
{
Id: 1,
name: "Oslo",
lat: 59.923043,
lng: 10.752839
},
{
Id: 2,
name: "Stockholm",
lat: 59.339025,
lng: 18.065818
},
{
Id: 3,
name: "Copenhagen",
lat: 55.675507,
lng: 12.574227
},
{
Id: 4,
name: "Berlin",
lat: 52.521248,
lng: 13.399038
},
{
Id: 5,
name: "Paris",
lat: 48.856127,
lng: 2.346525
}
]
}),
methods: {
openInfoWindow(location) {
this.selectedLocation = location
this.infoBoxOpen = true;
},
closeInfoWindow() {
this.infoBoxOpen = false;
}
}
};
Here is a demo that demonstrates how to manage info window per multiple markers

Related

Showing map markers by location in list outside map

I have a number of markers and I want to show the markers in a list outside of the map. How can this be achieved using javascript? I am new to Javascript so help is appreciated. Code I have currently below, this is all working as expected apart from listing the map marker information.
I idea is that a list will appear depending on the option chosen in the dropdown for counties.
//List of Counties
var counties = [{
name: "Armagh",
code: "am",
zoom : 8,
center: {
lat: 54.274911,
lng: -6.626583
}
}, {
name: "Cork",
code: "c",
zoom : 8,
center: {
lat: 51.904246,
lng: -8.474038
}
}];
//List of Practices
var practice = [{
name: "Cross Veterinary Clinic",
position: {
lat: 54.07531,
lng: -6.60590
},
code: "am",
address: "8 Dundalk Road, Crossmaglen, Co. Armagh",
vet: "Carol Peterson",
programme: ['bvd', 'jd']
}, {
name: "Keltic Veterinary",
position: {
lat: 52.35386,
lng: -8.68204
},
code: "c",
address: "Charleville Town Centre, Bakers Road, Charleville, Co. Cork",
vet: "Gerald Gonzales",
programme: ['cck', 'bvd']
}];
var countyselect = document.getElementById('county')
countyselect.addEventListener("change", onCountySelect);
//render map
function initialize() {
var options = {
center: {
lat: 53.2734,
lng: -7.77832031
},
zoom: 6.5
};
map = new google.maps.Map(document.getElementById('map'), options);
marker = renderMarker();
}
function renderMarker() {
for (var i = 0; i < practice.length; i++) {
var marker = new google.maps.Marker({
position: practice[i].position,
title: practice[i].name,
map: map,
});
inforwindow(marker, map);
}
}
function inforwindow(marker, map) {
var infowindow = new google.maps.InfoWindow(); {
google.maps.event.addListener(marker, 'click', function(renderMarker) {
infowindow.setContent(marker.getTitle());
infowindow.open(map, marker);
});
}
}
function onCountySelect() {
let countySelect = document.getElementById("county");
let selectedCounty = countySelect.options[countySelect.selectedIndex];
let countyFound = (counties.find(({ name }) => name === selectedCounty.value));
if (selectedCounty.value === "all") {
map.setCenter({ lat: 53.2734, lng: -7.77832031 });
map.setZoom(6.5);
} else {
map.setCenter(countyFound.center);
map.setZoom(countyFound.zoom);
}
}
function resultsList() {
if (selectedCounty.value === "all") {
let countySelect = document.write(`<h3>${practice.name}</h3><p>${practice.address}</p><p>${practice.vet}</p>`);
}
}
I'm not sure at all from your code what your plan is with markers, or whether you intend to make items in the list clickable so that they highlight a specific marker on the map. But in any case, here's code to do what you asked - to create a list of relevant practices when a county is selected. I've dropped in some hacky test HTML just as it's easier to test.
Hopefully this will get you on the right path.
A couple of notes - you have used the backtick, ie using ` and ${variable} approach to rendering some content - this may not work on older browsers directly.
Also, please excuse the mix of single and double quotes - that's a matter of taste but I didn't see the point in going back and changing everything you had done. Good luck!
<!doctype html>
<html>
<head>
<title>Map Thing</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
font-family: Helvetica;
min-height: 100vh;
display: flex;
flex-direction: column;
}
#container {
flex: 1;
display: flex;
}
#options {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
#results {
margin-top: 40px;
padding: 40px;
}
.result {
padding: 30px;
border: 1px solid #ddd;
}
#map {
flex: 3;
}
</style>
</head>
<body>
<div id="container">
<div id="options">
<select id="county" name="county" value="">
<option value="">Please choose</option>
<option value="am">Armagh</option>
<option value="c">Cork</option>
</select>
<div id="results"><!-- will be populated --></div>
</div>
<div id="map"></div>
</div>
<script>
//List of Counties
var counties = [{
name: "Armagh",
code: "am",
zoom : 8,
center: {
lat: 54.274911,
lng: -6.626583
}
}, {
name: "Cork",
code: "c",
zoom : 8,
center: {
lat: 51.904246,
lng: -8.474038
}
}];
//List of Practices
var practices = [{
name: "Cross Veterinary Clinic",
position: {
lat: 54.07531,
lng: -6.60590
},
code: "am",
address: "8 Dundalk Road, Crossmaglen, Co. Armagh",
vet: "Carol Peterson",
programme: ['bvd', 'jd']
}, {
name: "Keltic Veterinary",
position: {
lat: 52.35386,
lng: -8.68204
},
code: "c",
address: "Charleville Town Centre, Bakers Road, Charleville, Co. Cork",
vet: "Gerald Gonzales",
programme: ['cck', 'bvd']
}];
function initialize() {
var options = {
center: {
lat: 53.2734,
lng: -7.77832031
},
zoom: 6.5
};
map = new google.maps.Map(document.getElementById('map'), options);
var countyselect = document.getElementById('county');
countyselect.addEventListener('change', onCountySelect);
renderMarkers();
}
function renderMarkers() {
for (var i = 0; i < practices.length; i++) {
var marker = new google.maps.Marker({
position: practices[i].position,
title: practices[i].name,
map: map,
});
}
}
function showInfoWindow(marker, map) {
var infowindow = new google.maps.InfoWindow();
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(marker.getTitle());
infowindow.open(map, marker);
});
}
function onCountySelect() {
var countySelect = document.getElementById("county");
var countiesByCode = counties.map(function(c){
return c.code;
});
var index = countiesByCode.indexOf(countySelect.value)
if (index > -1) {
var selectedCounty = counties[index];
map.setCenter(selectedCounty.center);
map.setZoom(selectedCounty.zoom);
renderResultsList(selectedCounty);
} else {
map.setCenter({ lat: 53.2734, lng: -7.77832031 });
map.setZoom(6.5);
clearResultsList();
}
}
function renderResultsList(selectedCounty) {
var relevantPractices = practices.filter(function(p){
return p.code === selectedCounty.code;
});
var resultsArea = document.getElementById("results");
resultsArea.innerHTML = "";
for(var i = 0; i < relevantPractices.length; i++) {
var practice = relevantPractices[i];
var div = document.createElement("div");
div.className = "result";
div.innerHTML = `<h3>${practice.name}</h3><p>${practice.address}</p><p>${practice.vet}</p>`;
resultsArea.appendChild(div);
}
}
function clearResultsList() {
document.getElementById("results").innerHTML = "";
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY_HERE&callback=initialize"
async defer></script>
</body>
</html>

Filter Google Map markers with a checkbox

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.
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>

Change marker text with button on Leaflet map

I have a map with markers, generated by a json file, that contain a text with numeric value. For markers generation I use the Beaufify Markers Plugin.
This is a part of code that I'm using
var map = L.map('mapid').setView([43.08, 12.34], 9);
for ( var i=0; i < markers.length; ++i ) {
options = {
isAlphaNumericIcon: true,
text: markers[i].temperatura,
iconSize: [28, 28],
borderColor: markers[i].color,
backgroundColor: markers[i].color,
innerIconAnchor: [0, 4],
textColor: '#000;'
};
var popup = L.popup({
pane: 'fixed',
className: 'popup-fixed',
autoPan: false,
}).setContent('my html code');
L.marker( [markers[i].lat, markers[i].lng], {
icon: L.BeautifyIcon.icon(options),
virtual: true
})
.bindPopup(popup)
.addTo( map );
}
I would like the best and cleanest way, to change the variable text on options ('markers[i].temperatura'), with an onclick action on a button.
To update marker icon text:
1) save the list of markers into global variable, for example:
var markerObjects = [];
for (var i=0; i < markers.length; ++i ) {
//...
var markerObject = L.marker( [markers[i].lat, markers[i].lng], {
icon: L.BeautifyIcon.icon(options),
virtual: true
})
.bindPopup(popup)
.addTo( map );
markerObjects.push(markerObject);
}
2) once the button is clicked, update marker icon via Marker.setIcon method:
btn.onclick = () => {
const selectedIndex = ...; //get the selected index of marker
const selectedMarker = markerObjects[selectedIndex];
let iconOptions = selectedMarker.options.icon.options; //get existing icon properties
iconOptions.text = txtName.value; //update icon property
selectedMarker.setIcon(L.BeautifyIcon.icon(iconOptions)); //update marker icon
};
Demo
const map = L.map("map").setView([53.339025, 18.065818], 4);
L.tileLayer("http://{s}.tile.osm.org/{z}/{x}/{y}.png", {
attribution:
'© OpenStreetMap contributors'
}).addTo(map);
const locations = [
{
name: "Oslo",
lat: 59.923043,
lng: 10.752839
},
{
name: "Stockholm",
lat: 59.339025,
lng: 18.065818
},
{
name: "Copenhagen",
lat: 55.675507,
lng: 12.574227
},
{
name: "Berlin",
lat: 52.521248,
lng: 13.399038
},
{
name: "Paris",
lat: 48.856127,
lng: 2.346525
}
];
const markers = locations.map(location => {
let options = {
isAlphaNumericIcon: true,
text: location.name,
iconSize: [98, 28],
textColor: "#000;"
};
let popup = L.popup({
className: "popup-fixed",
autoPan: false
}).setContent(location.name);
return L.marker([location.lat, location.lng], {
icon: L.BeautifyIcon.icon(options),
virtual: true
})
.bindPopup(popup)
.addTo(map);
});
initControl();
function initControl() {
let selectLocations = document.getElementById("selectLocations");
let idx = 0;
for (const marker of markers) {
const option = document.createElement("option");
option.value = idx;
option.text = marker.options.icon.options.text;
selectLocations.appendChild(option);
idx++;
}
let txtName = document.getElementById("txtName");
txtName.value = locations[selectLocations.selectedIndex].name;
selectLocations.onchange = e => {
txtName.value = markers[e.target.value].options.icon.options.text;
};
let btnUpdate = document.getElementById("btnUpdate");
btnUpdate.onclick = () => {
const selectedIndex = selectLocations.selectedIndex;
const selectedMarker = markers[selectedIndex];
let iconOptions = selectedMarker.options.icon.options; //get existing icon properties
iconOptions.text = txtName.value; //update text property
selectedMarker.setIcon(L.BeautifyIcon.icon(iconOptions)); //set icon
};
}
<link
rel="stylesheet"
href="https://unpkg.com/leaflet#1.3.4/dist/leaflet.css"
/>
<link rel="stylesheet" href="style.css" />
<script src="https://unpkg.com/leaflet#1.3.4/dist/leaflet.js"></script>
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css"
/>
<link
rel="stylesheet"
href="https://marslan390.github.io/BeautifyMarker/leaflet-beautify-marker-icon.css"
/>
<script src="https://marslan390.github.io/BeautifyMarker/leaflet-beautify-marker-icon.js"></script>
<select id="selectLocations">
</select>
<input id="txtName" type="text"/>
<button id="btnUpdate">Update</button>
<div id="map" style="height:410px; width:570px;"></div>

JavaScript - leaflet, adding a bunch of markers

Let's say I have a bunch of markers (over 100) I want to add from this:
module.exports = [
{ value: 'Varrock', lng: 22.5, lat: -15.52249812756166, popular: 1 },
{ value: 'Lumbridge', lng: 25.9661865234375, lat: -43.644025847699496, popular: 1 },
{ value: 'Monastery', lng: -4.0924072265625, lat: -5.714379819235291 },
{ value: 'Edgeville', lng: 2.4884033203125, lat: -6.0094592380595495, popular: 1 },
{ value: 'Varrock Palace', lng: 22.412109375, lat: -6.882800241767556 },
{ value: 'Digsite', lng: 46.043701171875, lat: -17.266727823520508 },
{ value: 'River Salve', lng: 54.931640625, lat: -14.083301314706778 },
{ value: 'Morytania', lng: 64.610595703125, lat: -13.501814172428656 },
{ value: 'Mort Myre Swamp', lng: 59.820556640625, lat: -22.740723091194727 }
];
It uses browserify to get it. So, I do this:
var locations = require('./locations');
What would be the best way to add all of those into LayerGroup()? I mean, because doing var fairy = L.layerGroup([One, Two, Three...]); by hand would get tiresome.
So how would I go about adding all of those markers into a new layer (so I can toggle them on/off)
How about adding an empty L.LayerGroup, looping over your array and adding them to that layer?
var locations = [];
var layer = L.layerGroup().addTo(map);
locations.forEach(function (location) {
L.marker([location.lat, location.lng])
.bindPopup(location.value)
.addTo(layer);
});
Working example on Plunker: http://plnkr.co/edit/Q0DGqs?p=preview

Angular maps: Unable to get gMarker from markersScope

I'm getting Unable to get gMarker from markersScope! (in angular maps: https://github.com/angular-ui/angular-google-maps/blob/master/src/coffee/directives/api/models/parent/windows-parent-model.coffee#L146) when trying to add infoWindows. The windows do display, but behave erratically when updated.
Each time the user clicks on a movie the infoWindows should update with information about that movie at that cinema marker. It sometimes works, sometimes the infoWindows disappear and sometimes the markers disappear as well. The only error I get is the one above.
Controller and view code:
var createCinemaMarkers = function(cinemas) {
$scope.cinemaMarkers = [];
$scope.cinemaWindows = [];
for (var i = 0; i < cinemas.length; i++) {
getMoviesForCinema(cinemas[i].venue_id);
var map_coords = {
id: cinemas[i].venue_id,
title: cinemas[i].title,
options: {
title: cinemas[i].title,
random: 'blah blah blah'
},
clickable: true,
latitude: cinemas[i].coords.lat,
longitude: cinemas[i].coords.lng,
icon: 'images/cinema_icons/cinema.png'
}
if (!cinemas[i].movieTitle) {
cinemas[i].movieTitle = '';
}
var parameters = {
movieTitle: cinemas[i].movieTitle,
movieTimes: cinemas[i].movieTimes,
stuff: 'from props'
}
var infoWindow = {
id: cinemas[i].venue_id,
coords: {
latitude: cinemas[i].coords.lat,
longitude: cinemas[i].coords.lng
},
options: {
title: "I AM TITLE"
},
show: true,
templateUrl: 'views/info-window.html',
templateParameter: parameters,
isIconVisibleOnClick: true,
closeClick: 'none'
}
$scope.cinemaWindows.push(infoWindow);
$scope.cinemaMarkers.push(map_coords);
};
};
<ui-gmap-google-map center="map.center" zoom="map.zoom" events="mapEvents">
<ui-gmap-markers models="cinemaMarkers" events="events" options="'options'" coords="'self'" icon="'icon'" fit="'true'" popover-placement="top" popover="On the Top!">
<ui-gmap-windows models="cinemaWindows" templateUrl="'templateUrl'" templateParameter="'templateParameter'" options="'options'">
</ui-gmap-windows>
</ui-gmap-markers>
</ui-gmap-google-map>
I had a similar problem where in the directive coords="'self'" but markers were set to coords: {latitude:xxxx,longitude:xxxxx}
Because your ui-gmap-markers is set to coords="'self'" so try remove coords in infoWindow:
var infoWindow = {
id: cinemas[i].venue_id,
latitude: cinemas[i].coords.lat,
longitude: cinemas[i].coords.lng,
options: {
title: "I AM TITLE"
},
show: true,
templateUrl: 'views/info-window.html',
templateParameter: parameters,
isIconVisibleOnClick: true,
closeClick: 'none'
}

Categories