Reputation: 5
I have several markers (in an array) on my map, each with a custom ID tag i've given them.
What I want: When I click on a marker, i wish to add it's ID to another array.
The problem: The mouse event from Google does not have a target attribute, only the position, so I can't seem to access the ID directly.
I don't really want to have to resort to using the position to find the closest marker to it and returning it's ID this way, it's rather convoluted.
All help is appreciated
Upvotes: 0
Views: 243
Reputation: 28850
This is really easy, thanks to a feature in JavaScript and many other languages called a closure.
Simply put the code that creates the marker and sets up its event listener(s) insidea function, and call that function for each marker with the data needed for that specific marker. For example:
var places = [
{
id: 'one', lat: 1, lng: -1, name: 'First'
},
{
id: 'two', lat: 2, lng: -2, name: 'Second'
}
];
for( var i = 0; i < places.length; i++ ) {
addPlace( places[i] );
}
function addPlace( place ) {
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng( place.lat, place.lng ),
title: place.name
});
google.maps.event.addListener( 'click', function() {
alert( 'Clicked ' + place.id + ': ' + place.name );
});
}
I didn't test this Maps API code, but the specifics of the code are not important. What is important to understand is that place
variable you see used in the code. This is the key part: that variable is accessible inside the event listener, simply because the event listener is nested inside the addPlace()
function which has place
as a parameter.
Note the difference between that code and code like this, which will not work:
for( var i = 0; i < places.length; i++ ) {
var place = places[i];
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng( place.lat, place.lng ),
title: place.name
});
google.maps.event.addListener( 'click', function() {
alert( 'Clicked ' + place.id + ': ' + place.name );
});
}
The only difference between the two is that the working version puts the loop body in a separate function which is called from the loop, instead of having all that code directly inside the loop. Having that code in a function that you call each time is what creates the closure, and that's what lets the inner event listener function "see" the variables in the outer function.
The great thing about closures is that you can use them in any similar situation. It isn't specific to the Maps API or the objects that the API uses. You may have even used them already and not realized it, for example in a setTimeout()
call like this:
// Display an alert 'time' milliseconds after this function is called
function slowAlert( message, time ) {
setTimeout( function() {
alert( message );
}, time );
}
slowAlert( 'Howdy!', 1000 ); // Wait a second and then say Howdy!
Where the alert()
call is made inside the setTimeout()
callback function is made, it's using the closure on the slowAlert()
function to pick up the value of the message
variable that was passed into that function.
Upvotes: 2
Reputation: 4473
This should help. I added a customId
property to the marker object and then in the marker click
event I assign the id property to the new array.
function initialize() {
var map;
var centerPosition = new google.maps.LatLng(38.713107, -90.42984);
var options = {
zoom: 6,
center: centerPosition,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var bounds = new google.maps.LatLngBounds();
map = new google.maps.Map($('#map')[0], options);
var infoWindow = new google.maps.InfoWindow();
//marker array
var markers = [];
//sencondary array to store markers that were clicked on.
var markerIdArray = [];
for (i = 0; i < 6; i++) {
var lat = 38.713107 + Math.random();
var lng = -90.42984 + Math.random();
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(lat, lng),
customId: i //add a custom id to the marker
});
bounds.extend(marker.position);
google.maps.event.addListener(marker, 'click', function () {
//add the id to the other array.
markerIdArray.push(this.customId);
//log the content of the array to the console.
console.log(markerIdArray);
});
markers.push(marker);
}
map.fitBounds(bounds);
}
Here is an example of this in action.
Upvotes: 0