Google Maps API marker click event not firing [duplicate] - javascript

This question already has answers here:
Google Maps JS API v3 - Simple Multiple Marker Example
(15 answers)
Closed 8 years ago.
Problem with the following code is that the click event is not fired. The markers appear on the map as expected, but when clicked, nothing appears in the console. I've been searching for a while now, but all the answers I find are not relevant to my code.
/*
* Connect to Google API, load map and markers
*/
function drawMarkers(markerInfo) {
var mapOptions = {
center: { lat: 50.601079, lng: 4.4764595},
zoom: 8,
scrollwheel: false,
styles: style
};
var map = new google.maps.Map(document.getElementById('map-canvas'),mapOptions);
for (var i = 0; i < markerInfo.length; i++) {
var Latlng = new google.maps.LatLng(markerInfo[i][0],markerInfo[i][1]);
var title = markerInfo[i][2];
var marker = new google.maps.Marker({
position: Latlng,
animation: google.maps.Animation.DROP,
map: map,
title:title,
icon: markerUrl
});
};
google.maps.event.addListener(marker, 'click', function() {
console.log('test');
});
};
google.maps.event.addDomListener(window, 'load', getmarkerInfo);
I've got no idea what the problem could be, because there are no errors, and I can't seem to find the problem...
EDIT: When I refresh the page and I zoom out, so a marker which wasn't visible yet get's loaded in, only that one responds to the click event.

You only add the listener to the last marker, attach the listener in the loop and you'll be attaching the event to each marker.
for (var i = 0; i < markerInfo.length; i++) {
var Latlng = new google.maps.LatLng(markerInfo[i][0],markerInfo[i][1]);
var title = markerInfo[i][2];
var marker = new google.maps.Marker({
position: Latlng,
animation: google.maps.Animation.DROP,
map: map,
title:title,
icon: markerUrl
});
google.maps.event.addListener(marker, 'click', function() {
console.log('test');
});
};

You should probably create a function , which accepts marker as the argument , and call the function from within the for loop itself passing the current marker as the parameter.
function addListner(marker)
{
google.maps.event.addListener(marker, 'click', function() {
console.log('test');
});
}
And call the function inside the loop.
While referring to marker outside the for loop there is no reference to which marker it referring to. You need to assign a listener to each marker individually.

Related

Google Maps JavaScript - adding multiple markers to one map

I'm having difficulty setting event handlers to Google Maps markers in JavaScript. Below is my code:
var map = new google.maps.Map(document.getElementById('map-canvas'), {
zoom: 8,
center: {lat: -35, lng: 149}
});
for (var i = 0; i < basketballCourts.length; i++) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(basketballCourts[i].latitude, basketballCourts[i].longitude),
map: map,
title: 'Hello World!'
});
marker.set("data-index", i);
google.maps.event.addListener(marker, 'click', function() {
console.log(marker.get("data-index"));
});
}
You'll notice that there is a click event for the markers. However, the click event is the same for all the markers. A different number should be logged for every marker click, but no matter what marker I click on, I get the same response.
I'm not sure how to fix this.
What's happening is you're looping over all your basketballCourts, creating an event listener for each marker. That's all well and good. However that event listener function looks like:
console.log(marker.get("data-index"));
The function executes in response to a marker click, not when you define it. And the value of marker when the function executes will be the value it had at the end of your loop over all the basketballCourts.
Using #MiltoxBeyond's suggestion, try using this.get("data-index")

Change icon on mouseover/out fails

I'm tearing my hair out over this code. As you may guess, I'm relatively new to coding. I would appreciate any insight you have into why it is not working.
I am trying to change marker icons on mouseover/out. I am trying to create and add listeners in a for-loop. In the loop, the markers are created from an array of locations and pushed to another array, a listener is added for mouseover events to change the icon, and another listener is added for mouseout events to nullify the marker icon. The code below displays the map, adds the markers and seems to listen for mouseover and mouseout events (the cursor changes when hovering over a marker), but the icon does not change at these events.
function initialize(){
//Marker locations
var NYC = new google.maps.LatLng(40.721505, -74.004783);
var LA = new google.maps.LatLng(34.049519, -118.238698);
var Chicago = new google.maps.LatLng(41.877461, -87.624352);
var Seattle = new google.maps.LatLng(47.606747, -122.330349);
var Miami = new google.maps.LatLng(25.788661, -80.226617);
var Boston = new google.maps.LatLng(42.357913, -71.059217);
var Houston = new google.maps.LatLng(29.758182, -95.364213);
var KansasCity = new google.maps.LatLng(39.097781,-94.588079);
var locations = new Array(NYC, LA, Chicago, Seattle, Miami, Boston, Houston, KansasCity);
//Array to store markers
var markers = new Array ();
//Icon
var gif = 'http://demers-ambulances.com/assets/img/news/mapPinOver2.gif';
//Map options
var mapOptions = {
center: KansasCity,
zoom: 5,
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.SMALL,
position: google.maps.ControlPosition.TOP_LEFT
},
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU,
position: google.maps.ControlPosition.TOP_RIGHT,
},
};
//Create map
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
//Create markers and add listener to change marker icon on mouseover/out
for (i = 0; i<locations.length; i++){
var marker = new google.maps.Marker({
position: locations[i],
draggable: true,
map: map,
});
markers.push(marker);
google.maps.event.addListener(markers[i], 'mouseover', function() {
markers[i].setIcon(gif);
});
google.maps.event.addListener(markers[i], 'mouseout', function() {
markers[i].setIcon(null);
});
};
};
google.maps.event.addDomListener(window, 'load', initialize);
Thanks for your help :)
Closure problem: there is error reported:
Uncaught TypeError: Cannot read property 'setIcon' of undefined
Code has to be changed to:
(function(i) {
google.maps.event.addListener(markers[i], 'mouseover', function() {
markers[i].setIcon(gif);
});
google.maps.event.addListener(markers[i], 'mouseout', function() {
markers[i].setIcon(null);
});
})(i);
Basically the problem is in here:
for (i = 0; i<locations.length; i++){
var marker = new google.maps.Marker({
position: locations[i],
draggable: true,
map: map,
});
markers.push(marker);
google.maps.event.addListener(markers[i], 'mouseover', function() {
markers[i].setIcon(gif);
});
google.maps.event.addListener(markers[i], 'mouseout', function() {
markers[i].setIcon(null);
});
};
This code looks innocent, but the problem comes from the part that, once the loop has finished executing and our event listeners are called, the variable i is already equal to locations.length.
So whenever the event listener is called, i is already changed to locations.length, and markers[i] will return undefined, because the last push index was i = locations.length - 1
since the loop condition is i<locations.length.
Since markers[i] is undefined when the event listener is called, then it will throw the following error as it doesn't have setIcon method anymore: TypeError: Cannot read property 'setIcon' of undefined.
To fix this, you should capture value of i, in a closure(as Anto Jurković described above, don't forget to upvote him):
(function(i) {
google.maps.event.addListener(markers[i], 'mouseover', function() {
markers[i].setIcon(gif);
});
google.maps.event.addListener(markers[i], 'mouseout', function() {
markers[i].setIcon(null);
});
})(i);
Here we create a function on each loop and call it with i immediately so the value of i is captured in the closure, and since javascript functions have block scope(loops don't), the variable i will be the same for each iteration of loop.
The problem and it's solution is also described in the following question: Javascript closure inside loops - simple practical example
After further experimenting with the code that Anto and Farid recommended I found another solution. For this solution a function is created outside the initialize function to add listeners to the markers, and then called when each marker is created in the for loop. If you have any thoughts on this, please comment below. I have no clue if this is a good way to do this, I just know it works :)
for (i = 0; i<locations.length; i++){
var marker = new google.maps.Marker({
position: locations[i],
draggable: true,
map: map,
});
animateit(marker);
markers.push(marker);
};
};
function animateit(marker) {
google.maps.event.addListener(marker, 'mouseover', function() {
marker.setIcon(gif);
});
google.maps.event.addListener(marker, 'mouseout', function() {
marker.setIcon(null);
});

tooltip content undefined - google map

I added code for tool tip display when hovering the pointers in the google map.It is showing the tool tip but the content is "undefined". How can put the corresponding content related to the pointer into the tool tip box.The code is :
function initialize() {
var myOptions = {
zoom: 11,
center: new google.maps.LatLng(29.7,-95.4),
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("salon_map"), myOptions);
var locations = [
__newmapdetls__
];
for (var i = 0; i < locations.length; i++) {
var location = locations[i];
var image = new google.maps.MarkerImage("http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld="+location[3]+"|FF0000|000000",
new google.maps.Size(20, 34),
new google.maps.Point(0, 0),
new google.maps.Point(10, 34));
var myLatLng = new google.maps.LatLng(location[1], location[2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: image,
title: location[0],
zIndex: location[3],
tooltip:"testinggg"+i
});
google.maps.event.addListener(marker, 'mouseover', function() {
infowindow1.open(map, this);
});
google.maps.event.addListener(marker, 'mouseout', function() {
infowindow1.close(map, this);
});
var infowindow1 = new google.maps.InfoWindow({
content: "'"+this.tooltip+"'"
});
}
}
Also url is : http://myshopsalon.com/find-a-shop-salon
A couple of things I noticed when looking at your page source:
Your page is loading both jQuery 1.10.1 and 1.7.2. But it isn't using noConflict(). So these two jQuery versions are stepping on each other.
You're also loading three copies of the Maps API: two copies of version 3 and a copy of the deprecated version 2 API.
Now to your question:
Use a closure to save your variables for each iteration of the marker loop. You can do this by simply calling a function in each iteration.
Instead of using this when you call infowindow.open(), use marker. (this and marker may be the same in this context, but use marker for consistency.)
The .close() method of an infowindow does not take any parameters.
Don't set the tooltip property when you create the marker. That may work, but it isn't documented that you can add your own properties in this fashion. Instead, simply use a local variable or parameter for tooltip.
I would create the infowindow before adding the event listeners. This will actually work fine in either order (since the event listeners are asynchronous), but it looks better to see the infowindow created first.
So, change your for loop to:
for (var i = 0; i < locations.length; i++) {
addMarker( locations[i], "testinggg" + i );
}
function addMarker( location, tooltip ) {
var image = new google.maps.MarkerImage(
"http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld="+location[3]+"|FF0000|000000",
new google.maps.Size(20, 34),
new google.maps.Point(0, 0),
new google.maps.Point(10, 34)
);
var myLatLng = new google.maps.LatLng(location[1], location[2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: image,
title: location[0],
zIndex: location[3]
});
var infowindow = new google.maps.InfoWindow({
content: "'" + tooltip + "'"
});
google.maps.event.addListener(marker, 'mouseover', function() {
infowindow.open(map, marker);
});
google.maps.event.addListener(marker, 'mouseout', function() {
infowindow.close();
});
}
That said, you may not like the result you get when you open an infowindow in response to moving the mouse over a marker. What if the marker is near the top of the window? The page will immediately move to make the infowindow fit on the screen, and now the marker won't be under the mouse any more.
You're already setting the title property when you create the marker. This should cause a normal browser tooltip to appear when the mouse is hovered over the marker, and it won't cause the map to move as the infowindow may do. Any reason not to just use that tooltip instead of the infowindow? You could just remove all of the infowindow code, or let the infowindow open on a click as it normally would.
Set the content of the infowindow onmouseover(you may access there the tooltip-property of the specific marker)
google.maps.event.addListener(marker, 'mouseover', function() {
infowindow1.setContent(this.tooltip);
infowindow1.open(map, this);
});
the initializing of infowindow1 move to outside the loop and leave the arguments empty.
Use the below code:
var infowindow1 = new google.maps.InfoWindow({
content: "'"+marker.tooltip+"'"
});
EDIETD:
var contentString = "testinggg"+i;
var infowindow1[i] = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: image,
title: location[0],
zIndex: location[3],
tooltip:"testinggg"+i
});
google.maps.event.addListener(marker, 'mouseover', function() {
infowindow1[i].open(map, marker);
});
google.maps.event.addListener(marker, 'mouseout', function() {
infowindow1[i].close(map, marker);
});
You can not get the property of marker in the info window. So you need to define the content in other variable.

When a marker lies behind open infobox - Event mouseover with InfoBox plugin Google Maps API v3

I'm having trouble with v3 of the Google Maps API and using the InfoBox plugin specifically with respect to this usability issue use case:
Since my map requires a custom infobox to be opened upon hovering the mouse over each respective marker, when the map has 2 markers on it that are close in proximity, even when/if one of the markers lies behind an infobox that is currently open after hovering the other close-by marker, it is triggered when mousing over it marker (even though it's behind the currently open infobox) and the other infobox obstructs the currently/previously opened infobox
I've followed the question and answer process by another poster here: Google Maps API v3 Event mouseover with InfoBox plugin and have followed the recommended code, but i can't wrap my mind around how to prevent markers that lie BEHIND an open infobox to not be triggered until that infobox is closed.
var gpoints = [];
function initializeMap1() {
var Map1MileLatLang = new google.maps.LatLng(39.285900,-76.570000);
var Map1MileOptions = {
mapTypeControlOptions: {
mapTypeIds: [ 'Styled']
},
mapTypeControl: false,
zoom: 14,
center: Map1MileLatLang,
//mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeId: 'Styled'
};
var Map1Mile = new google.maps.Map(document.getElementById("map_canvas"), Map1MileOptions);
var styledMapType = new google.maps.StyledMapType(styles, { name: 'Styled' });//new
Map1Mile.mapTypes.set('Styled', styledMapType);//new
for ( var i=0; i<5; i++ ) {
gpoints.push( new point(Map1Mile) );
gpoints.push( new point2(Map1Mile) );
}
function popup(_point) {
_point.popup = new InfoBox({
content: _point.content,
pane: 'floatPane',
closeBoxURL: '',
alignBottom: 1
});
_point.popup.open(_point.marker.map, _point.marker);
google.maps.event.addListener(_point.popup, 'domready', function() {
//Have to put this within the domready or else it can't find the div element (it's null until the InfoBox is opened)
$(_point.popup.div_).hover(
function() {
//This is called when the mouse enters the element
},
function() {
//This is called when the mouse leaves the element
_point.popup.close();
}
);
});
}
function point(_map) {
this.marker = new google.maps.Marker({
position: new google.maps.LatLng(39.291003,-76.546234),
map: _map
});
this.content = '<div class="map-popup" style="width:100px;"><div class="map-popup-window"><div class="map-popup-content">Just try to click me!<br/>Hovering over this text will result in a <code>mouseout</code> event firing on the <code>map-popup</code> element and this will disappear.</div></div>';
// Scope
var gpoint = this;
// Events
google.maps.event.addListener(gpoint.marker, 'mouseover', function() {
popup(gpoint);
});
}
function point2(_map) {
this.marker = new google.maps.Marker({
position: new google.maps.LatLng(39.295003,-76.545234),
map: _map
});
this.content = '<div class="map-popup" style="width:100px;"><div class="map-popup-window"><div class="map-popup-content">Just try to click me!<br/>Hovering over this text will result in a <code>mouseout</code> event firing on the <code>map-popup</code> element and this will disappear.</div></div>';
// Scope
var gpoint = this;
// Events
google.maps.event.addListener(gpoint.marker, 'mouseover', function() {
popup(gpoint);
});
}
After doing experimenting, i suspect this issue is irrelevant to z-index... am i correct in understanding this needs to be caught in the javascript?
Any help or advice would be greatly appreciated!
Adding optimized: false attribute for your markers should solve the problem.
this.marker = new google.maps.Marker({
position: new google.maps.LatLng(39.295003,-76.545234),
map: _map,
optimized: false
});

Automatically opening marker info pane on google map

I've created a custom map with most things I want on it (custom icon and custom info bubble), however I can't find a solution to automatically open the markers info window on load, I've done alot of searching but can't seem to find anything the code I have so far is as follows, any help would be much appreciated:
function initialize() {
var myLatlng = new google.maps.LatLng(54.325109,-2.742226);
var myOptions = {
zoom: 15,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var countries = [
{
title:'Remedy',
lat:54.3210,
lon:-2.7438,
content:"<h2>Remedy</h2><p>address, <br />location, <br />postcode</p> <p><b>T:</b> 07595 153 835 <br /><b>E:</b> <a href='mailto:email'>email</a></p>"
}
];
for (var i = 0; i < countries.length; i++) {
var c = countries[i];
c.marker = new google.maps.Marker({
position: new google.maps.LatLng(c.lat, c.lon),
map: map,
icon: '/wp-content/themes/remedy/display_images/google_map_icon.png',
title: c.title});
c.infowindow = new google.maps.InfoWindow({content: c.content});
google.maps.event.addListener(c.marker, 'click', makeCallback(c));
}
function makeCallback(country) {
return function () {
country.infowindow.open(map, country.marker);
};
}
infowindow.open(map, marker);
}
Maybe it's not working because you just created the instance of the Map and didn't wait for the complete load of the map to open the InfoWindow.
Try something like this:
google.maps.event.addListenerOnce(map, 'tilesloaded', function(event) {
infowindow.open(map, marker);
});
According to the reference:
http://code.google.com/intl/en/apis/maps/documentation/javascript/reference.html#Map
tilesloaded - This event is fired when the visible tiles have finished loading.
Hmm, inforwindow does not refer to anything in your code, which is why it is not working.
Since you have one country in the list as of now you can do a quick test and intialize the infowindow variable with an actual info window, or better yet also since you have 1 item in the list, just define c to be outside the loop so you can access it and then open the popup passing it the map and the marker, something like this (assuming c has been defined outside the loop)
c.infowindow.open(map, c.marker);
var infowindow = new google.maps.InfoWindow({
content: "Test Route",
position: new google.maps.LatLng(38.8709866, -77.208055),
});
infowindow.open(map);

Categories