Im looping and placing some markers, but when i click a marker, they all respond with the same value
Here is my code
for(a=0; a < prod.length; a++){
// we add marker to map
var myLatlng = new google.maps.LatLng(prod[a]['lat'],prod[a]['lon']);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: prod[a]['name']+" \n"+prod[a]['description'],
icon: image
});
google.maps.event.addListener(marker, "click", function() {
show_details(a);
});
}
function show_details, a always has the same value
I have looked at the other answers here but that didnt solve my problem.
Tipical problem in async programming/scripting. The a variable passing, when the click event runs, so , the value of that is what is after the for loop finishes.
You should create an inner function scope, and save the value of a in a variable, what lives only in that scope.
The solution:
(function(z){
google.maps.event.addListener(marker, "click", function() {
show_details(z);
});
})(a);
The a variable lives outside the callback function too. So if you modify the value of a ( or the for loop modify that) and when the event handler is called, it see the modified a.
Help link: http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/ .
Related
I am trying to get a Google Maps instance setup, where I can have the marker icons change into a larger image on hover. I am loading the larger image within arrays and then trying to pass those values into the callback event function. For some reason I only get a default map marker showing on hover, and not the image.
You can see where I am doing this below by using the "testVar".
https://jsfiddle.net/sj1zv02a/
for (i = 0; i < locations_programs.length; i++) {
var id = 'programs' + i;
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations_programs[i][1], locations_programs[i][2]),
map: map,
id: id,
icon: 'http://www.christielakekids.com/_images/new/blue_circle.png',
url: locations_programs[i][5],
image: locations_programs[i][4],
zIndex: 100
});
var testVar = locations_programs[i][4];
google.maps.event.addListener(marker, 'mouseover', function (event, testVar) {
this.setIcon(testVar);
});
google.maps.event.addListener(marker, 'mouseout', function (event) {
this.setIcon('http://www.christielakekids.com/_images/new/blue_circle.png');
});
I would also like to know how to attach a URL to the larger image so it will redirect there when clicked. I have the "URL" parameter set in the marker code, but that doesn't seem to do anything.
I have found this solution (the sample is for //**** PROGRAMS only but is easly extendible for the other section.
the JSFiddle for test
And the code for a better explanation
In the marker attributes add a altIcon attribute and assign to this the image you need.
In mouseover listener set the icon using this.setIcon(this.altIcon)
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations_programs[i][1], locations_programs[i][2]),
map: map
,id: id
,icon: 'http://www.christielakekids.com/_images/new/blue_circle.png'
,url: locations_programs[i][5]
,image: locations_programs[i][4]
,zIndex:100
,altIcon: locations_programs[i][4]
});
google.maps.event.addListener(marker, 'mouseover', function(event) {
this.setIcon(this.altIcon);
});
I met some difficulties to display images in the array. (the site says file not found) so inside jsfiddle I used icons with different colors.
I have a function that loops an array of markers and assigns click events to all of them.
for(var key in markers){
clickEvent(markers[key], sekolah[j].show, sekolah[j].hide, key);
}
function clickEvent(mark, showArr, hideArr, key){
var listener = google.maps.event.addListener(mark, 'click', function() {
//does a lot of stuff
});
}
What I would like to do is to remove/disable all click events when any marker has been clicked (so that no two markers can be clicked sequentially without resetting the map first). The click events would be enabled again when the user resets the map.
This is the function to reset the map:
google.maps.event.addListener(map, "click", function(){
setAllMap(map); //Shows all markers
//and a lot of stuff
});
I have tried using addListenerOnce, but that didn't work. I have also tried this suggestion from another post, but the result was the same as using addListenerOnce.
Is there a way to achieve this?
Thank you.
PS this is how I created markers:
var newMark = new google.maps.Marker({
map: map,
position: pos,
id: ids,
title: name,
icon: "res/schoolf.png"
});;
markers[ids] = newMark;
I'm using google maps v3, and my issue is that I have 200+ polygons on one map, they are all editable, and I need to make an ajax call in the event listeners for change which use path instead of the polygon to detect the changes.
so in the callback function this = polygon.getPath(), how can I get the polygon that it belongs to. In the polygon I use set to set the info I require for the ajax call.
poly1.set('name', 'poly1');
poly1.set('id', 1);
google.maps.event.addListener(poly1, 'dragend', setNewArea);
google.maps.event.addListener(poly1.getPath(), 'insert_at', setNewArea);
google.maps.event.addListener(poly1.getPath(), 'remove_at', setNewArea);
google.maps.event.addListener(poly1.getPath(), 'set_at', setNewArea);
so in setNewArea, I can easily check this to see if it's the poly or the path, but if it's the path I have no way to get the parent poly for it. I don't want to have 200 custom callbacks just to hardcode the poly, there has to be an other cleaner way.
One way to do this is to add the object reference to poly1 to your assigned callback. Here is some code I wrote using the maps API that adds a listener for a click event on a specific marker that opens an info window.
var latLng = new google.maps.LatLng(lat,lng);
var marker = new google.maps.Marker({
position: latLng,
map: window.map,
title: pinName
});
var infoWindow = new google.maps.InfoWindow({
content: content
});
google.maps.event.addListener(marker, 'click', function() {
infoWindow.open(window.map, marker);
});
So for your example, you might want to do something like what's below. That will ensure that your callback function is getting a reference to the poly object, even if the triggering event is related to the path.
poly1.set('name', 'poly1');
poly1.set('id', 1);
google.maps.event.addListener(poly1, 'dragend', function() {
setNewArea(poly1);
});
google.maps.event.addListener(poly1.getPath(), 'insert_at', function() {
setNewArea(poly1);
});
You can make circular reference among objects.
var thePath = poly1.getPath();
thePath.parent = poly1;
google.maps.event.addListener(thePath, 'set_at', function () {
console.log('My parent is the polygon', this.parent);
}.bind(this);
I have the following function to add one single marker but I want to add multiple markers by clicking on the map. I have Googled but I can't get any straight answer on how I can solve this problem.
function placeMarker(location) {
if(marker) {
marker.setPosition(location);
} else {
marker = new google.maps.Marker({
position: location,
map: gm_map,
draggable: true
});
}
}
I know I need to use Array() but I don't know exactly how. How can I solve my problem?
DEMO: removed because the problem has been solved.
Do you need to use the marker variable outside of the placeMarker function? Your function is not deleting the marker, it is checking to see if the marker variable exists and moves the marker using the setPosition function. You need to remove that line if you want multiple markers to exist.
function placeMarker(location) {
//marker variable will only exist inside this function
var marker = new google.maps.Marker({
position: location,
map: gm_map,
draggable: true
});
}
Here is an example: http://jsfiddle.net/bryan_weaver/aEyfW/
Ok, you need to have an event listener for the 'click' event on the map. And this needs to pass the currently-clicked location to your placeMarker function. Try this (add this event listener in the same place where you initialise your map)
google.maps.event.addListener(gm_map, 'click', function(event) {
placeMarker(event.latLng);
});
And modify your placeMarker function, so instead of having one global variable marker which you update with each click, create a new marker each time:
function placeMarker(location) {
var marker = new google.maps.Marker({
position: location,
map: gm_map,
draggable: true
});
}
I have some code here : http://bitbucket.org/natim/lo53_tp1/src/tip/part3/camions/medias/js/tracking.js
That I use to draw some information about trucks direction.
The problem come from a function defined in a for loop like this one :
...
for(i = 0; i < nb_trucks; i++)
{
...
contentString = '<div id="content">'+ trucks[i]['name'] + '</div>';
current_window = new google.maps.InfoWindow({
content: contentString
});
infosWindow.push(current_window);
current_marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(trucks[i]['end']['lat'], trucks[i]['end']['lon']),
draggable: false,
title: trucks[i]['name']
});
markers.push(current_marker);
google.maps.event.addListener(current_marker, 'click', function() {
current_window.open(map, current_marker);
});
}
In this code, you can see the last block
google.maps.event.addListener(current_marker, 'click', function() {
current_window.open(map, current_marker);
});
And my problem is that current_marker in the addListener parameters is different from the one inside the function.
The current_window and the current_marker inside the function is overide at each loop turn.
How can I get it right ?
Thanks
Wrap it in a closure (just this little section, no other changes) so you get the variable you want, like this:
(function(marker) { //a copy is passed, accessible as marker inside this function
google.maps.event.addListener(marker, 'click', function() {
current_window.open(map, marker);
});
})(current_marker); //pass in the current value
This doesn't reference the same variable that's changing every loop, a copy of it is passed into the closure, so each time you run this it gets a copy of what current_marker is that that time passed in. If you're more curious about this, there are some great answers explaining closures in this question.