Reputation: 1165
I'm working on my first google maps project. I have got multiple markers to appear and also used a custom marker. However I cannot get the info window to work when clicking a marker! Can anyone help?
When clicking a marker, nothing happens - it doesn't even enter the function (I set a console log).
<script type="text/javascript">
var map,
geocoder,
bounds,
address,
marker = [],
myLatlng = new google.maps.LatLng(40, -74);
function initialize() {
var mapOptions = {
center: myLatlng,
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDefaultUI: false,
scrollwheel: false,
navigationControl: true,
mapTypeControl: false,
scaleControl: true,
draggable: true
};
//styles
var styles = [{
"elementType": "geometry.fill",
"stylers": [
{ "visibility": "on" },
{ "hue": "#FF0000" },
{ "weight": 2 },
{ "gamma": 1 },
{ "lightness": 20 },
{ "saturation": 50 }
]
}];
map = new google.maps.Map(document.getElementById('map'), mapOptions);
geocoder = new google.maps.Geocoder();
map.setOptions({styles: styles});
var buildings = [
'76 Ninth Ave, New York, NY ',
'825 8th Ave, New York, NY ',
'127 E 23rd St, New York, NY '
];
var contentString = '<div id="content">test</div>';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker = {url:'<?php echo site_url(); ?>/wp-content/themes/theme/img/pointer2.png', scaledSize:new google.maps.Size(45, 72)};
for (var i = 0; i < buildings.length; ++i) {
(function(address) {
geocoder.geocode({ 'address': address }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
marker += new google.maps.Marker ({
map: map,
position: results[0].geometry.location,
icon: marker
});
};
});
})(buildings[i]);
};
google.maps.event.trigger(map, 'resize');
google.maps.event.addListener(marker, 'click', function() {
console.log("test3");
infowindow.open(map,marker);
map.setZoom(8);
map.setCenter(marker.getPosition());
});
};
google.maps.event.addDomListener(window, 'load', initialize);
Upvotes: 1
Views: 1044
Reputation: 1667
I think first of all you have to move the click eventListener inside the loop. You have a marker array at the top, but you are overwriting it with var marker = {url:'<?php echo site_url(); ?>...
, so let's rather call it "yourIcon" for the time being. Moreover, within the loop your adding all markers up to one single string, which makes no sense as far as I am concerned ;)
Within the loop, you then have to attach an eventListener to every single marker.
for (var i=0; i < buildings.length; i++) {
// Create a new lexical scope by "copying the buildings"
(function(address) {
geocoder.geocode({ 'address': address }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
// Create the marker
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
// Create the info window
var infowindow = new google.maps.InfoWindow({
content: address
});
// Add the eventListener
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map, this);
map.setZoom(12);
map.panTo(this.getPosition());
});
};
});
})(buildings[i]);
}
You can see the working fiddle here
P.S.
You already avoided the closure issue in your question, I was just to tired to see it;)
Here is an approach to explain closures: How do JavaScript closures work?
Edit 1: Wordpress
In order to make this work in wordpress, you don't have to do much. I would suggest to use objects inside your buildings array, this way you can easily access more data.
This is how your buildings array could look like:
var buildings = [
{ address: '76 Ninth Ave, New York, NY', title: "Test 1" },
{ address: '825 8th Ave, New York, NY', title: "Test 2" },
{ address: '127 E 23rd St, New York, NY', title: "Test 3" }
];
The loop:
<?php if ( have_posts() ) : ?>
<?php $postCount = 0; ?>
var buildings = [
<?php while ( have_posts() ) : the_post(); ?>
<?php $postcount++; ?>
{ address: '<?php customMetaAddressHere; ?>', title: '<?php the_title(); ?>', link: '<?php the_permalink(); ?>', }
<?php if($postCount < sizeof($posts)) { ?>
,
<?php } ?>
<?php endwhile; ?>
];
<?php else : ?>
var buildings = [];
<?php endif; ?>
Change your Google marker loop to:
(function(building) {
geocoder.geocode({ 'address': building.address }, function(results, status) {
// You have access to buildings.title as well
...
});
})(buildings[i]);
This is untested, but you can see a fiddle of what I mean here.
Edit 2: Only one active infowindow
If you want only one infowindow open at a time, it is best to create it outside the loop and only change it's content and position on marker click:
// Create the info window
var infowindow = new google.maps.InfoWindow();
for (var i=0; i < buildings.length; i++) {
// Create a new lexical scope by "copying the buildings"
(function(building) {
geocoder.geocode({ 'address': building.address }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
// Create the marker
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
// Add the eventListener
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent("<b>" + building.title + "</b><br> " + building.address);
infowindow.setPosition(this.getPosition());
infowindow.open(map, this);
map.setZoom(12);
map.panTo(this.getPosition());
});
};
});
})(buildings[i]);
}
You can find a working fiddle here.
Upvotes: 2