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
Related
In this jsfiddle is simplified version of my js: http://jsfiddle.net/Drecker/2m4kvxb8/4/ Note that interesting part of the jsfiddle is only showRoute method. And method showMarker only shows desired behavior on normal marker.
Basically I generate a route via gmap3 getroute with some waypoints. After clicking on a waypoint I need to open a small infobox with more custom information of that point - so basically somehow get onclick event of such waypoint (with some identification of that waypoint so I would be able to get proper information). I'm able to achieve desired behavior on a separate marker (as you can see in the jsfiddle - that's the fully functional separate marker on the top left), but not on the markers generated by directionrenderer.
Furthermore please note that my waypoints have stopover: false and such markers for some reason ignore (some) options like title, as you can see in jsfiddle.
Any help is very appreciated - I've tried several things none of them works.
Hope you are using the google APIs library some version, in case something like this
<script src="http://maps.googleapis.com/maps/api/js?sensor=false&libraries=places,geometry" type="text/javascript"></script>
You have one div space to show the map, say
<div id="map" style="width: 700px; height: 600px;"></div>
So you can use this for adding listener on markers
//location is an array variable where you store your co ordinates
//code to show map
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: new google.maps.LatLng(locations[0].latitude, locations[0].longitude),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
//adding listener
var marker,i;
var infowindow = new google.maps.InfoWindow();
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent(locations[i].city);
infowindow.open(map, marker);
}
})(marker, i));
where
marker
is the varible which will be something like this,
//adding marker
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i].latitude, locations[i].longitude),
map: map
});
Hope from above you got some idea, might be helpful for you with your problem
There is no such option, according to the documentation and a lot of similar questions here on the stackoverflow, you can't bind click action to waypoints.
I have a workaround for that problem. The main idea is to add markers instead of waypoints and change their icon. Marker has much more options than waypoint. So I removed waypoints and added markers. Note that you have to be much more precise when adding marker's location
options without waypoints:
options: {origin: {lat:49.9, lng: 14.9},
destination: {lat: 50.1, lng: 15.1},
travelMode: google.maps.DirectionsTravelMode.DRIVING
},
added markers with a new icon and click event:
marker:{
values:[
{latLng:[49.96485, 14.88392], data:"Waypoint1", options:{icon: "http://mt.google.com/vt/icon/name=icons/spotlight/directions_transfer_icon_10px.png&scale=1"}},
{latLng:[49.97730, 14.88185], data:"Waypoint2", options:{icon: "http://mt.google.com/vt/icon/name=icons/spotlight/directions_transfer_icon_10px.png&scale=1"}}
],
options:{
draggable: false
},
events:{
click: function(marker, event, context){
var map = $(this).gmap3("get"),
infowindow = $(this).gmap3({get:{name:"infowindow"}});
if (infowindow){
infowindow.open(map, marker);
infowindow.setContent(context.data);
} else {
$(this).gmap3({
infowindow:{
anchor:marker,
options:{content: context.data}
}
});
}
}
}
}
Here is my workaround for that problem : DEMO
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>
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
});
I'm playing around with Google maps for the first time, so I looked at a nice tutorial over at CSS Tricks: http://css-tricks.com/google-maps-slider/ I like working with jQuery better than pure JS, and this tutorial makes a nice way to click on a place in a list to display the marker in the map.
I liked it that way, but I need to add infowindows to the marker. Which I did, but when I click on a place on the list and the map pans away, the infowindow stays open! I think it's because I need to attach the infowindow.close() to the event of clicking on a "#locations li".
Here's my code, which runs on document.ready:
$(function() {
var chicago = new google.maps.LatLng(41.924832, -87.697456),
pointToMoveTo,
first = true,
curMarker = new google.maps.Marker({}),
$el;
var myOptions = {
zoom: 10,
center: chicago,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map($("#map_canvas")[0], myOptions);
$("#locations li").click(function() {
$el = $(this);
if (!$el.hasClass("hover")) {
$("#locations li").removeClass("hover");
$el.addClass("hover");
if (!first) {
// Clear current marker
curMarker.setMap();
// Set zoom back to Chicago level
// map.setZoom(10);
}
// Move (pan) map to new location
function move(){
pointToMoveTo = new google.maps.LatLng($el.attr("data-geo-lat"), $el.attr("data-geo-long"));
map.panTo(pointToMoveTo);
}
move();
// Add new marker
curMarker = new google.maps.Marker({
position: pointToMoveTo,
map: map
});
// Infowindow: contenido
var contentString = '<p>'+$el.find("h3").html()+'</p>';
contentString += 'hola' ;
var infowindow = new google.maps.InfoWindow(
{
size: new google.maps.Size(150,50),
content: contentString
});
// On click, zoom map
google.maps.event.addListener(curMarker, 'click', function() {
//map.setZoom(14);
infowindow.open(map,curMarker);
});
It looks like you're creating a new InfoWindow for each marker. 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 one InfoWindow object just after you initialize your map, and then handle the click event handler as follows:
google.maps.event.addListener(curMarker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map, curMarker);
});
Then the InfoWindow should automatically close when you click on a new marker without having to call the close() method.
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.