Map not adding click event handlers to markers - javascript

The code below will add markers to my map. But the add Listener event never gets added to each marker.
var mapDiv = document.getElementById("google-map");
var infowindow = new google.maps.InfoWindow({
content: 'test'
});
var map = new google.maps.Map(mapDiv);
map.setCenter(new GLatLng(53.635784, 6.943359));
map.setZoom(5);
for (var i = 0; i < data.length; i++) {
var dataMarker = data[i];
var marker = new GLatLng(dataMarker.Latitude, dataMarker.Longitude);
map.addOverlay(new google.maps.Marker(marker, {
title: dataMarker.Name,
html: dataMarker.HtmlAttributes[0]
}));
google.maps.event.addListener(marker, 'click', function () {
infoWindow.setContent(this.html);
infoWindow.open(map, this);
});
}
What am I doing wrong?
Oh and I am using Maps v2.

You did not add any listener to marker.
var marker = new GLatLng(dataMarker.Latitude, dataMarker.Longitude);
marker is not a google.maps.Marker , it's a google.maps.LatLng , which will not respond to mouse-events, because it's not an UI-element, it's just a javascript-object

You created event listeners which are most probably connected with last marker.
You have to link info window with marker in separate function. Last part of your code should be written as:
addEventListener(marker, infoWindow, map);
}
function addEventListener(marker, infoWindow, map) {
google.maps.event.addListener(marker, 'click', function () {
infoWindow.setContent(marker.html);
infoWindow.open(map, marker);
});
}
See also An array of infoWindow in Google maps api and link with explanation about closures.

It looks like you have a mix of v2 and v3 code in that snippet, and so the whole thing is unlikely to work.
For example, you're using new google.maps.Infowindow (v3) in the same place as GLatLng.
My suggestion would be to change the bootstrap on the page to v3, and delete any references to v2 objects (like GLatLng). Make sure you're loading the API like this:
<script src="//maps.googleapis.com/maps/api/js?…"></script>

Related

InfoWindow - Google map API

I try to add infowindows for all my markers. But I add only one InfoWindow for last marker.
Can you help me?
for (i = 0; i < events.length; i++) {
var contentString = '<div id="content">'+i+'bla-bla-bla</div>';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var newMarker = new google.maps.Marker({
position: new google.maps.LatLng(events[i][1], events[i][2]),
map: map,
title: events[i][0]
});
newMarker.categorysassasas = 2;
newMarker.category = events[i][3];
markers.push(newMarker);
google.maps.event.addListener(newMarker, 'click', function() {
infowindow.open(map,newMarker);
});
}
found a similar solution to your question in this stackoverflow: Trying to bind multiple InfoWindows to multiple Markers on a Google Map and failing
Essentially all you'll have to do is wrap your addlistener function within another function to create a closure for your marker variable - so that it is bound to the infowindow. In your case, I believe you'll have to add the listenMarker function outside of your init() and pass in the variable for marker and infowindow, like so..
function listenMarker (marker, info)
{
// so marker is associated with the closure created for the listenMarker function call
google.maps.event.addListener(marker, 'click', function() {
info.open(map, marker);
});
}
and then in your for loop where you call the addlistener event, replace that with:
listenMarker(newMarker, infowindow);
That should do the trick.

markerclusterer mouseover doesn't work

I just looked at the following post: markerclusterer info windows
There's a thing I need in this post, the mouseover event for the markerclusterer. I need to change the icon when the mouse is hovered over the icon.
I got the following code:
var clusterOptions = {
zoomOnClick: false,
styles: [{
url: 'images/template/cluster.png',
height: 68,
width: 57,
textColor: '#FFF'
}]
}
var markerClusterer = new MarkerClusterer(map, markers, clusterOptions);
google.maps.event.addListener(markerClusterer, "mouseover", function(cluster) {
console.log('test');
});
// Listen for a cluster to be clicked
google.maps.event.addListener(markerClusterer, 'clusterclick', function(cluster) {
var markers = cluster.getMarkers();
var content = '';
$.each(markers, function () {
content += this.get('content');
});
// Convert lat/long from cluster object to a usable MVCObject
var info = new google.maps.MVCObject;
info.set('position', cluster.center_);
var infowindow = new google.maps.InfoWindow();
infowindow.close();
infowindow.setContent(content);
infowindow.open(map, info);
});
The clusterer works fine and also the infowindow shows up nice. It combines all the infowindows from the markers in the cluster.
What am I doing wrong in the mouseover event? I don't even see the console.log!
Thanks in advance
My solution was using markerclustererplus rather than markerclusterer.
Just replace your script src.
Here is an example.
You should use the following library:
https://github.com/googlemaps/v3-utility-library/tree/master/markerclustererplus
it has mouseover handlers
http://htmlpreview.github.io/?https://github.com/googlemaps/v3-utility-library/blob/master/markerclustererplus/docs/reference.html

How to get some information in google maps without click event on marker and show this in a div, other than infoWindow

Hi I am showing some markers on my google map and on click of the marker, I am calling the click event and showing some info about that place to the right side(area other than Map and not as an infoWindow). Now this event gets fired on click, and by default when page loads my div remains blank, How can I have the div the basic information being shown up once the map loads up. I need to show the information that corresponds to the marker that is the center point of the map, and later when the users click the marker icons the info should change and correspond to the particular marker being clicked
I have tried something but it doesn't work:
function loadMap() {
var myLatlng = new google.maps.LatLng(40.46998, -3.68705);
var myOptions = {
zoom: 3,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"), myOptions);
var places = [];
places.push(new google.maps.LatLng(51.43581, -0.51744));
places.push(new google.maps.LatLng(48.87187, 2.31764));
places.push(new google.maps.LatLng(45.45979, 9.19681));
var infowindow;
for(var i = 0; i<places.length; i++) {
var marker= new google.maps.Marker({
position: places[i],
map: map,
title: 'Place' + i
});
(function (i,marker){
google.maps.event.addListener(marker, 'click' , function() {
infowindow.setContent('PLace Number' + i)
infowindow.open(i, marker)
});
});(i, marker);
}
}
$("document").ready(function () {
loadMap();
});
UPDATE EDITED
Basically I need something like Layer KML features
But the info should come on the right hand side by default for the first time. Later on when the marker is clicked, the info should change. I am also not adamant that I need this info in a kml file(xml is fine with me as well). I can just have a marker and info should popup on click and for the first time be default as well depending on the location of the user.
Bottom Line: I need the info to appear on click of a marker and by default when the page loads the info should appear corresponding to the center point of the map. which means users coming from different locations will see different info's corresponding to their location from where they are coming.(I am centering the map based on users location)
You can use the addDomListener event of the google maps api. Something like this:
<script>
function initialize() {
// Map initialization
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<body>
<div id="map_canvas"></div>
</body>
Although the above code is Maps Javascript API code, the addDomListener() method binds to the window object of the browser and allows the API to communicate with objects outside of the API's normal domain.
further reading
Actually the basic Idea is that you need to read an XMl and parse the data and and show this in a seperate div on right side., This div you can create dynamically when you load the map e-g:
$("#body").append("<div class='newdiv'></div>")
From the google Docs in the section about InfoWindow:
Note that if you call open() without passing a marker, the InfoWindow
will use the position specified upon construction through the
InfoWindow options object.
So in your code, why don't you simply init your infoWindow and call the open() method? I am not particularly familiar with the api, but how about:
var infowindow = new google.maps.InfoWindow({
content: 'your initial text'
});
infowindow.open();
Or if you need the marker for special purposes on the infowindow, init an marker with the center position and use that in the infowindow.open(your_initial_pos) call.
You can use jQuery to .triger() a click event on the first marker on document.ready:
$(marker).trigger('click');
This will run the code you have already written and make it so when the page loads your div will be populated with data from whatever element you trigger the click on.
When you bind to document.ready you don't need encapsulate document in quotes:
$(document).ready(function () {...});
Or you could use the short-hand if you're into that sort of thing:
$(function () {...});
UPDATE
You can place the trigger function call after your for loop where you are setting up the markers:
for(var i = 0; i<places.length; i++) {
var marker= new google.maps.Marker({
position: places[i],
map: map,
title: 'Place' + i
});
(function (i,marker){
google.maps.event.addListener(marker, 'click' , function() {
infowindow.setContent('PLace Number' + i)
infowindow.open(i, marker)
});
});(i, marker);
//only run on the first marker
if (i === 0) {
//trigger a click event to show the first info-window
$(marker).trigger('click');
}
}
You can fire a tilesloaded event on the map object. Check out the Map reference for events
tilesloaded waits until the map tiles are actually loaded before firing. Using your code, you could do something like this:
function loadMap() {
var myLatlng = new google.maps.LatLng(40.46998, -3.68705);
var myOptions = {
zoom: 3,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"), myOptions);
google.maps.event.addListener(map, 'tilesloaded', function() {
doSomething();
});

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);

Have just one InfoWindow open in Google Maps API v3

I need to have only one InfoWindow open on my Google Map. I need to close all other InfoWindows before I open a new one.
Can someone show me how to do this?
You need to create just one InfoWindow object, keep a reference to it, and reuse if for all the markers. Quoting from the Google Maps API Docs:
If you only want one info window to display at a time (as is the behavior on Google Maps), you need only create one info window, which you can reassign to different locations or markers upon map events (such as user clicks).
Therefore, you may simply want to create the InfoWindow object just after you initialize your map, and then handle the click event handlers of your markers as follows. Let's say you have a marker called someMarker:
google.maps.event.addListener(someMarker, 'click', function() {
infowindow.setContent('Hello World');
infowindow.open(map, this);
});
Then the InfoWindow should automatically close when you click on a new marker without having to call the close() method.
Create your infowindow out of the scope so that you can share it.
Here is a simple example:
var markers = [AnArrayOfMarkers];
var infowindow = new google.maps.InfoWindow();
for (var i = 0, marker; marker = markers[i]; i++) {
google.maps.event.addListener(marker, 'click', function(e) {
infowindow.setContent('Marker position: ' + this.getPosition());
infowindow.open(map, this);
});
}
I had the same problem but the best answer didn't solve it completely, what I had to do in my for statement was using the this relating to my current marker. Maybe this helps someone.
for(var i = 0; i < markers.length; i++){
name = markers[i].getAttribute("name");
address = markers[i].getAttribute("address");
point = new google.maps.LatLng(parseFloat(markers[i].getAttribute("lat")), parseFloat(markers[i].getAttribute("lng")));
contentString = '<div style="font-family: Lucida Grande, Arial, sans-serif;>'+'<div><b>'+ name +'</b></div>'+'<div>'+ address +'</div>';
marker = new google.maps.Marker({
map: map,
position: point,
title: name+" "+address,
buborek: contentString
});
google.maps.event.addListener(marker, 'click', function(){
infowindow.setContent(this.buborek);
infowindow.open(map,this);
});
marker.setMap(map);
}
a tad late, but I managed to have only one infowindow open by maken infowindow a global variable.
var infowindow = new google.maps.InfoWindow({});
then inside the listner
infowindow.close();
infowindow = new google.maps.InfoWindow({
content: '<h1>'+arrondissement+'</h1>'+ gemeentesFiltered
});
infowindow.open(map, this);
Declare a globar var selectedInfoWindow; and use it to hold the opened info window:
var infoWindow = new google.maps.InfoWindow({
content: content
});
// Open the infowindow on marker click
google.maps.event.addListener(marker, "click", function() {
//Check if there some info window selected and if is opened then close it
if (selectedInfoWindow != null && selectedInfoWindow.getMap() != null) {
selectedInfoWindow.close();
//If the clicked window is the selected window, deselect it and return
if (selectedInfoWindow == infoWindow) {
selectedInfoWindow = null;
return;
}
}
//If arrive here, that mean you should open the new info window
//because is different from the selected
selectedInfoWindow = infoWindow;
selectedInfoWindow.open(map, marker);
});
You need to keep track of your previous InfoWindow object and call the close method on it when you handle the click event on a new marker.
N.B It is not necessary to call close on the shared info window object, calling open with a different marker will automatically close the original. See Daniel's answer for details.
Basically you want one function that keeps reference to one new InfoBox() => delegate the onclick event.
While creating your markers (in a loop) use bindInfoBox(xhr, map, marker);
// #param(project): xhr : data for infoBox template
// #param(map): object : google.maps.map
// #param(marker): object : google.maps.marker
bindInfoBox: (function () {
var options = $.extend({}, cfg.infoBoxOptions, { pixelOffset: new google.maps.Size(-450, -30) }),
infoBox = new window.InfoBox(options);
return function (project, map, marker) {
var tpl = renderTemplate(project, cfg.infoBoxTpl); // similar to Mustache, Handlebars
google.maps.event.addListener(marker, 'click', function () {
infoBox.setContent(tpl);
infoBox.open(map, marker);
});
};
}())
var infoBox is assigned asynchronously and kept in memory. Every time you call bindInfoBox() the return function will be called instead. Also handy to pass the infoBoxOptions only once!
In my example I've had to add an extra param to the map as my initialization is delayed by tab events.
InfoBoxOptions
Here is a solution that doesn't need to create only one infoWindow to reuse it. You can continue creating many infoWindows, the only thing you need is to build a closeAllInfoWindows function, and call it before open a new infowindow.
So, keeping your code, you just need to:
Create a global array to store all the infoWindows
var infoWindows = [];
Store each new infoWindow in the array, just after the infoWindow = new...
infoWindows.push(infoWindow);
Create the closeAllInfoWindows function
function closeAllInfoWindows() {
for (var i=0;i<infoWindows.length;i++) {
infoWindows[i].close();
}
}
In your code, call to closeAllInfoWindows() just before open the infoWindow.
Regards,
One smart easy way to do this with jQuery is the following :
google.maps.event.addListener(marker, 'click', function (e) {
jQuery(".gm-ui-hover-effect").click();
marker.info.open(map, this);
});
It will click on all the closing buttons amongst your tooltips.
My approach allows you to toggle the infoWindow as well.
Global space
var infoWindow = new google.maps.InfoWindow();
infoWindow.setContent(contentString);
var lastInfoWindow;
Local space
marker.addListener("click", (e) => {
if (lastInfoWindow === e.domEvent.srcElement) {
infoWindow.close();
lastInfoWindow = null;
} else {
infoWindow.open({
anchor: marker,
map,
shouldFocus: false,
});
lastInfoWindow = e.domEvent.srcElement;
}
});
Solved it this way:
function window(content){
google.maps.event.addListener(marker,'click', (function(){
infowindow.close();
infowindow = new google.maps.InfoWindow({
content: content
});
infowindow.open(map, this);
}))
}
window(contentHtml);
Google Maps allows you to only have one info window open. So if you open a new window, then the other one closes automatically.

Categories