I am currently creating a bit of a Google Maps application using Javascript API v3. It's a map of results from a wordpress database, which dynamically populates the map, creating markers on the map, and on a sidebar the list of wordpress articles.
What I'm trying to do is the following :
when clicking on the link of the wordpress article on the sidebar, instead of going immediately on the article, it have to open the corresponding infowindow on the map. I tried to do it with JQuery, binding a click event on the link to open the infowindow, but unfortunately, it keeps opening the last infowindow created.
I do understand the issue here : JQuery evaluates the 'marker' variable only when the event is fired, thus using the last known value of the variable.
What I want to do is actually evaluates the 'marker' variable WHILE IN THE LOOP. And there I'm stuck. If anyone can help me on this one, I'll be really grateful.
Thanks for the time you'll take to answer me.
Here's a link to the app : http://88.191.128.36/buddypress/carte/
and here the function itself :
function setMarkers(map, markers) {
for (var i = 0; i < markers.length; i++) {
var sites = markers[i];
var siteLatLng = new google.maps.LatLng(sites[1], sites[2]);
if( sites[4] == '10'){
var MarkerImage = new google.maps.MarkerImage('http://dediope.inovawork.net/buddypress/wp-content/themes/TheSource/images/marker-hotel.png');
} else if (sites[4] == '9') {
var MarkerImage = new google.maps.MarkerImage('http://dediope.inovawork.net/buddypress/wp-content/themes/TheSource/images/marker-golf.png');
}
var marker = new google.maps.Marker({
position: siteLatLng,
map: map,
icon: MarkerImage,
title: sites[0],
html: '<div><b>' + sites[0] + '</b> <br /> Voir la fiche de ce lieu </div>'
});
marker_array[i] = marker ;
// THIS IS WHERE I NEED HELP :)
$j('#results_entry li .title:contains("' + sites[0] + '")').bind('click', function(){ infowindow.setContent( marker.html ); infowindow.open( map, marker ); }) ;
var contentString = '<div><b>' + sites[0] + '</b> <br /> Voir la fiche de ce lieu </div>';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
google.maps.event.addListener(marker, "click", function () {
infowindow.setContent(this.html);
infowindow.open(map, this);
});
}
}
PS : Sorry if I didn't explain very well, I'm french so my english isn't perfect :)
I finally found the solution thanks to this post :
Google Maps v3 opens the last infoWindow when a marker is clicked
The way to make it is to actually pass the object 'marker' and 'infowindow' to an external function and THEN bind the event. That way it binds the right marker and infowindow to the link.
Here the bit of code to show you how I did it, in case other people have the same issue as me:
// I REPLACED THAT
$j('#results_entry li .title:contains("' + sites[0] + '")').bind('click', function(){ infowindow.setContent( marker.html ); infowindow.open( map, marker ); }) ;
// BY THAT
BindLink(marker, sites[0], infowindow);
And i created a BindLink function OUTSIDE the function setmarkers() I had :
function BindLink( bmarker, titre, binfowindow ){
$j('#results_entry li .title:contains("' + titre + '")').bind('click', function(){
binfowindow.setContent( bmarker.html );
binfowindow.open( map, bmarker );
}) ;
}
Now it works perfectly fine ( except that I can't figure out to close the previously opened infowindow but that's another story ! )
Related
so I have a project that's working with Google Maps, using KnockoutJS. I define the markers like so:
for (i = 0; i < markerData.length; i++) {
// Grab marker data so we only have to call it once
var m = markerData[i];
// Define everything
var position = new google.maps.LatLng(m.location.lat, m.location.lng);
var title = m.title;
// etc etc
// Push all this info to the google maps marker
var marker = new google.maps.Marker({
map: map,
position: position,
title: title
// etc with rest
});
And then in the same for loop, I try to define an info window, simplified for reading:
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(this.title + '<br>' + this.address + '<br><a target="_blank" href="' + this.directions + '">Get Directions</a>');
infoWindow.open(map, this);
map.setCenter(this);
});
While it works exactly as I like it, linters are saying not to make a function inside the for loop. With that being said - is there a way I can move this outside the for loop and still get it to work effectively? Everything I've tried thus far has essentially turned into another for loop in one way or another, which still fires up the linter.
I feel like I'm missing something blatantly apparent here. Any thoughts or ideas to how I can properly apply this?
As a side note - all markers are in the KO vm viewModel.gMarkers(). Greatly appreciate any help, thanks!
Specifically the linter is complaining about the anonymous function google.maps.event.addListener(marker, 'click', function() {}; within the for loop. You could try putting it into its own function and calling it within the loop with the marker passed in.
var m, position, title, marker;
for (i = 0; i < markerData.length; i++) {
// Grab marker data so we only have to call it once
m = markerData[i];
// Define everything
position = new google.maps.LatLng(m.location.lat, m.location.lng);
title = m.title;
// etc etc
// Push all this info to the google maps marker
marker = new google.maps.Marker({
map: map,
position: position,
title: title
// etc with rest
});
doThis(marker);
}
function doThis(marker) {
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(this.title + '<br>' + this.address + '<br><a
target="_blank" href="' + this.directions + '">Get Directions</a>');
infoWindow.open(map, this); // Not sure where map is coming from
map.setCenter(this);
});
}
I'm having a google map where google markers are put up. The placement of markers works well. But if I click a marker, the adress should open up in an infowindow. The adress, longtitude and latitude are loaded from model.js into the variable myLocations.
EDIT: Currently a click on any marker returns the adress of the last object in myLocations. But I would like to get the myLocations.adress of the one who was clicked.
var markerspots;
var spot;
var j;
for (j = 0; j < myLocations.length; j++){
spot = {
lat: parseFloat(myLocations[j].lati),
lng: parseFloat(myLocations[j].long)
};
contentString = myLocations[j].adress;
markerspots = new google.maps.Marker({
position: spot,
map: map,
icon: markerspot,
content: contentString,
id: j
});
var infowindow = new google.maps.InfoWindow();
google.maps.event.addListener(markerspots, "click", (function(marker) {
return function(evt) {
infowindow.setContent(contentString);
infowindow.open(map, markerspots);
}
})(markerspots));
}
I have found lots of solutions, but I don't understand any of those. So how can I make the content of the clicked marker show up in an infowindow?
Thanks
Well you are accessing your contentString, which is set to the last one you created in your for loop.
What you really want is the content property of the marker you clicked on, which is stored in this.
So
google.maps.event.addListener(markerspots, 'click', function() {
console.log(this.content);
});
should do the trick.
Example here: https://jsfiddle.net/4tpnh00u/
i'm developing my first web application using Google Maps Javascript API v3 (with markers clustering libraries). Here is part of my code:
var markersReady = [];
for (var i = 0; i < markers.length; i++) {
var data = markers[i];
var myLatlng = new google.maps.LatLng(data.lat, data.lng);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: data.title,
icon : 'images/marker.png',
});
(function (marker, data) {
google.maps.event.addListener(marker, "click", function (e) {
infoWindow.setContent("<div id='info'><p id='title'>" + data.title + "</p><p>" + data.desc + "</p></div>");
infoWindow.open(map, marker);
});
})(marker, data);
markersReady.push(marker);
}
As you can see i add an event listener to every marker to make them clickable. When users click on one of them, it shows the infoWindow. Now how to add an event listener to the infoWindow as well? I'm using Bootstrap and i want to show a modal when user click on infoWindow popup. In addition, how to pass parameters to modal so every modal shows info according to the clicked marker?
I've seen other questions related to this and none of the solutions I saw seemed to help. Maybe I'm just overlooking something.
Any help would be appreciated.
I have a map that I'm loading upwards of 1000 markers. When a user performs a mouseover on the marker, I need the infowindow to display for that marker where the marker is.
The issue I'm having is that the same infowindow appears over the same marker no matter which marker I mouseover.
I provided a screenshot below that shows the map with the markers and an infowindow. So, no matter which marker I mouseover, that same infowindow is shown.
This is the code (gm is an instantiated google.maps object):
for (var i = 0; i < opts.LocationsData.length; i ++) {
var datum = opts.LocationsData[i];
var icon = new gm.MarkerImage(datum.map_pin_loc + datum.map_marker + '.svg',null, null, null, new google.maps.Size(31,51));
var loc = new gm.LatLng(datum.latitude, datum.longitude);
var zi = 500;
if(i>9)
{
datum.map_pin_icon = datum.map_pin_loc + 'dot1.svg';
icon = new gm.MarkerImage(datum.map_pin_icon,null, null, null, new google.maps.Size(8,8));
zi=450;
}
var marker = new gm.Marker({
position: loc,
/** title: datum.title != '' ? datum.title : datum.description, **/
icon: icon,
zIndex: zi,
map: map
});
marker.type = 'point';
marker.post_id = datum.pin_id;
marker.scrollAndAnimate = true;
/** (these are used elsewhere in my code for marker management and other purposes) **/
markers.push(marker);
markersLatLngObjs.push(loc);
var infowindow = new gm.InfoWindow({
content: '<strong>' + (datum.title != '' ? datum.title : datum.description) + '</strong>'
});
gm.event.addListener(marker, 'mouseover', function() {
infowindow.open(map,marker);
});
}
The pb is that the mouseover event handler is a closure referencing variables which are unique in the context of the calling function. Better move this part outside the loop to see clearer.
For example you can define a function such as :
function showInfo() {
// called in the context of a marker
var datum = opts.LocationsData[this.placeIndex];
var infowindow = new gm.InfoWindow({
content: '<strong>' + (datum.title != '' ? datum.title : datum.description) + '</strong>'
});
infowindow.open(map, this);
}
just before your loop, then tag the markers with a property placeIndex (for example) in your loop :
marker.placeIndex = i;
and finally bind the handler with :
gm.event.addListener(marker, 'mouseover', showInfo);
Edit: oops, my bad, forgot about the other references, same pb. You can probably replace the marker by 'this' within the handler. I updated the code.
I am pretty new to JavaScript and the google maps API. I cannot figure out what is wrong.
The InfoWindow is actually a class I found "InfoBubble".
http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobubble/examples/example.html/
Here is the situation:
1. I create my map and add a 'click' event. The event creates Markers.
2. I create one global infoWindow.
3. I click the map, a Marker appears.
4. I click the map, a Marker appears.
5. I click the map, a Marker appears. Step 3-5 can be repeated lots and lots.
6. I click marker number X
6.1. An infoWindow pops up.
7. I click marker number Y
7.1. The infoWindow is closed. (.close())
7.2. Its content and position is changed
7.3. It is opened on the new position (.open(map,marker))
7.4. Also Marker number X is removed.
Try it yourself: http://dl.dropbox.com/u/6084360/test/index.html
Why is step 7.4. happening? After it has happened I can click markers however I feel like without anything disappearing. WHY?
I have tried debugging somewhat via Google Chrome but after I do step 7.3 it takes me into some minified code and I get lost.
Here is the line which removes the marker. I have no idea why it removes it or how to know where to start.
R.addDomListenerOnce=function(a,b,c,d){var e=R[yc](a,b,function(){e[wb]();return c[Cc](this,arguments)},d);return e};R.R=function(a,b,c,d){c=cf(c,d);return R[yc](a,b,c)};function cf(a,b){return function(c){return b[oc](a,c,this)}}R.bind=function(a,b,c,d){return R[G](a,b,P(c,d))};R.addListenerOnce=function(a,b,c){var d=R[G](a,b,function(){d[wb]();return c[Cc](this,arguments)});return d};R.forward=function(a,b,c){return R[G](a,b,df(b,c))};R.ua=function(a,b,c,d){return R[yc](a,b,df(b,c,!d))};
My code:
var times = 0;
var treasureLocation = new google.maps.LatLng(62.05350309096103, 15.373047874999997);
var map, infoBubble = null;
function initialize()
{
// Create the actual map.
map = new google.maps.Map(document.getElementById("map_canvas"),
{
zoom: 4,
center: new google.maps.LatLng(62.05350309096103, 15.373047874999997),
mapTypeId: google.maps.MapTypeId.ROADMAP
}
);
infoBubble = new InfoBubble({
disableAutoPan: true
});
// Add an eventlistener to the map.
google.maps.event.addListener
(
map,
'click',
function(ev)
{
addMarker(ev);
}
);
}
function addMarker(ev)
{
// Get the distance.
var distance = getDistance( ev.latLng , treasureLocation );
// Skriv ut vart man klickade.
document.getElementById("click_info").innerHTML = "Du klickade " + distance + " ifrån skatten, försök igen!";
// Create a marker
var marker = new google.maps.Marker({
position: ev.latLng,
map: map,
clickable: true,
title: "Härifån är det bara " + distance + " till skatten!",
icon: "shovel.png"
});
// Hook the click on the created marker to show the created popup
google.maps.event.addListener
(
marker,
'click',
function(ev)
{
if( infoBubble != null ){infoBubble.close();}
infoBubble.setContent(marker.title);
infoBubble.setPosition(marker.position);
infoBubble.open(map, marker);
}
);
}
I can't really explain why but seems like infoBubble.setPosition(marker.position); is causing trouble. Just Delete it. You are using infoBubble.open(map, marker); to define bubble position, so you don't rly need it.