Can somebody please explain why my Google Maps info windows are only opening at the bottom left marker?
See here for the fiddle http://jsfiddle.net/Vj3nw/7/
When I click on any of the markers, only the bottom-left one is opened. I would like the marker that is clicked to open.
I believe the problem is due to the loop below, and this question seems to have the same problem Setting onclick to use current value of variable in loop
"The problem you were hitting is that javascript doesn't use block scope. Instead all variables have a lifetime of their containing function. So there was only ever one a captured in all of the onclick functions and they all see it's final value."
I just can't quite translate that solution to mine.
Many thanks.
for (var i = 0; i < 4; i++) {
var marker = new google.maps.Marker({
position: flightPlanCoordinates[i],
icon: Symbol,
map: map
});
infowindow = new google.maps.InfoWindow();
infowindow.setContent("hello");
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
}
Generating your markers and adding the listeners in their own function, called from the loop like the updated fiddle works.
function create_marker(i,flightPlanCoordinates,Symbol,map){
var marker = new google.maps.Marker({
position: flightPlanCoordinates[i],
icon: Symbol,
map: map
});
infowindow = new google.maps.InfoWindow();
infowindow.setContent("hello" + i);
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
});
}
Related
i was checking out the google map api to integrate in my website.
made this page with what ever i could understand so far.
everything is working fine but there is just one thing, that i want three markers on the same map.
when i am adding more than one markers then the map stops working.
test link : http://goo.gl/X9q92s
you will have a better understanding if u see my link.
this is the code that i got from google map api.
and i edited it to get grey scale map with my desired marker box.
i just want to add two more....
Please help.
<script>
function initialize() {
var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
var mapOptions = {
zoom: 4,
center: myLatlng
}
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: 'Hello World!'
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
You should place your "new marker" code into its own function, like so:
function LoadMarkers(name, lat, lng) {
var MarkerLatLng = new google.maps.LatLng(lat, lng);
var MarkerOption = { map: map, position: MarkerLatLng, title: name};
var Marker = new google.maps.Marker(MarkerOption);
}
Putting this into its own function allows you to "refresh" the markers with ease, by simply invoking the function with a timer or some other event. A program I'm working on refreshes the map every few seconds, as my data source is constantly changing with new/removed/updated records that should be reflected immediately on the map. I think this is a great way to do this.
Then, in your program, you can create a loop that shoots the information for each marker in by invoking the LoadMarkers function. I've recently fallen in love with SqlDataReader.
Your loop would iterate through a SqlDataReader and each record read will invoke the script like so:
InvokeScript("LoadMarkers", New Object() {name, lat, lng})
This is a great moment to also add an InfoWindow for each marker.
var infowindow = new google.maps.InfoWindow(
{
content: "Content here"
});
As well as a click listener for the InfoWindows. ;)
google.maps.event.addListener(Marker, 'click', function () {
typeof infoWindowsOpenCurrently !== 'undefined' && infoWindowsOpenCurrently.close(); //If there is an InfoWindow currently open, close it
infowindow.open(map, Marker); //Open a new one for the selected marker
infoWindowsOpenCurrently = infowindow; //Set the new info window to the temporary variable
});
Some might not like this method of using a loop. I like it because I can "personalize" each marker for each record, while personalizing each of their InfoWindows too. In my code above, assume that "name" is a unique ID that lets you specify a specific marker for later use, such as identifying which marker was clicked and which InfoWindow is currently open.
I have multiple markers on a map that I want the ability to pan between. The idea being that if you click Marker 1 it will pan to Marker 1 being centered, and then if you click Marker 2 it will pan from Marker 1 to Marker 2. I've got the pan to work fine initially, but it won't pan from one marker to another without the user moving the map first.
The current code I'm using is:
google.maps.event.addListener(marker, 'click', function() {
map.panTo(marker.getPosition());
});
I'm thinking there might be something I'm unaware of when it comes to using multiple marker event listeners in a row (maybe? I'm not sure).
Here's the functioning example as I'm encountering it now:
http://kolosk.us/pan/
Hopefully that's clear, let me know if you can help. Thanks!
There is only one marker variable in your code, left at the last marker created by the loop. The usual solution is to use function closure, associates a unique copy of the marker variable with each event listener.
for (var i = 0; i < locations.length; i++) {
var beach = locations[i];
var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
//icon: image,
//shape: shape,
title: beach[0],
zIndex: beach[3]
});
google.maps.event.addListener(marker, 'click', (function(marker) {
return function() {
map.panTo(marker.getPosition());
}
})(marker));
}
working example
I have scoured stackoverflow and other forums including the google maps v3 api docs for an answer but I cannot find how to change the event that fires the marker info window from click to mouseover in the files I am working with.
I am working with a demo from the google library that includes a fusion table layer.
You zoom into the clusters and see the small red circle markers for locations.
You have to click to reveal an info window. I wish to rollover to reveal the info window.
My demo is here:
http://www.pretravelvideo.com/gmap2/
The functions.js file does most of the work here:
http://www.pretravelvideo.com/gmap2/functions.js
Here's an example:
http://duncan99.wordpress.com/2011/10/08/google-maps-api-infowindows/
marker.addListener('mouseover', function() {
infowindow.open(map, this);
});
// assuming you also want to hide the infowindow when user mouses-out
marker.addListener('mouseout', function() {
infowindow.close();
});
var icon1 = "imageA.png";
var icon2 = "imageB.png";
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: icon1,
title: "some marker"
});
google.maps.event.addListener(marker, 'mouseover', function() {
marker.setIcon(icon2);
});
google.maps.event.addListener(marker, 'mouseout', function() {
marker.setIcon(icon1);
});
Thanks to duncan answer, I end up with this:
marker.addListener('mouseover', () => infoWindow.open(map, marker))
marker.addListener('mouseout', () => infoWindow.close())
This loads the map, gets new results and removes the old ones:
google.maps.event.addListener(map, 'idle', function() {
updateMap();
});
That part works great.
My trouble comes when I click on a marker to open it's InfoWindow. Opening an InfoWindow re-centers the map around the marker, which triggers the Listener from above, which then resets the map, hiding the InfoWindow.
Here is how I am creating the markers/InfoWindow:
var infowindow = new google.maps.InfoWindow({});
function makeMarker(LatLong, markerName) { //this is called from a loop
var marker = new google.maps.Marker({
position: LatLong,
map: map,
title:markerName,
content: "html for the infoWindow"
});
//Detect marker click
google.maps.event.addListener(marker, "click", function() {
infowindow.setContent(this.content);
infowindow.open(map, marker);
});
}
Any insights are greatly appreciated.
updateMap might be where the underlying problem is. When you're updating the map you really don't need to be deleting every marker and adding it again; instead you want to remove the ones that you no longer need and add the ones that you do. (Admittedly, the first strategy is much simpler and works well for most use cases.)
Alternatively, there are two approaches I'd explore:
Store a global variable like markerClick and implement something like:
google.maps.event.addListener(map, 'idle', function() {
if(!markerClick){
updateMap();
markerClick = false;
}
});
google.maps.event.addListener(marker, "click", function() {
markerClick = true;
infowindow.setContent(this.content);
infowindow.open(map, marker);
});
The one ceveat being that is really a quick hack, and could definitely cause trouble if a marker is clicked that doesn't trigger the idle event (i.e. one in the center or something).
Don't use idle anymore. Events like dragend and zoom_changed might better capture the specific user interactions you're looking for.
Adding to bamnet's answer and maybe it will be useful for someone. It is not an answer by itself, because it was already answered but I had almost the same problem. In my case, the conflict was between dragging and redrawing.
When the user was dragging and taking the marker too far that the map was being panned. Therefore, the 'idle' would be called somewhere in the middle of the drag and drop process causing the moving marker to be positioned on the starting point. To avoid that, I've employed the same approach proposed by bamnet but using the dragstart and dragend events like following:
markerDrag = false;
google.maps.event.addListener(map, 'idle', function() {
if(!markerDrag) {
updateMap();
}
});
google.maps.event.addListener(marker, 'dragstart', function() {
markerDrag = true;
});
google.maps.event.addListener(marker, 'dragend', function() {
// do stuff here, send new position to the server, etc.
// ...
markerDrag = false;
});
I hope it will be helpful for someone.
The "drag", "dragstart" and "dragend" events in the Google Maps V3 API each pass a mouseEvent to the registered callback function.
However - this event does not contain any information as to which marker is being dragged. How can I determine that?
This is even more complicated if you are just looking at the "dragend" event - which would only have the new coordinates, making it impossible to even infer from the coordinates.
I'd assume there's got to be an easy way to just determine which marker is being dragged...
I would attach add the drag event to the marker using a listener when it is created.
google.maps.event.addListener(marker, 'dragend', function() {
//do something with the event.
});
here is an example fiddle: http://jsfiddle.net/2YQg6/10/
(Dont mind the other stuff I just edited a fiddle I have used before to handle draggable markers.)
The relavant code is in the marker creation loop:
//geo code and build markers for each list item.
for (var i = 0; i < $listItems.length; i++) {
geocoder.geocode({
'address': $($listItems[i]).text()
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var marker = new google.maps.Marker({
position: results[0].geometry.location,
map: map,
draggable: true,
originalPos: results[0].geometry.location
});
google.maps.event.addListener(marker, 'dragend', function() {
infoWindow.setContent("marker originally at this position: " + this.originalPos + " was dragged to: " + this.position);
infoWindow.open(map, this);
});
markers.push(marker);
}
});
}