I add custom Google Maps Info Window for my GMap v3
How to disable 'click' event when i click on InfoWindow content and InfoWindow close button ?
Example code i puts on https://codepen.io/anon/pen/rwLdxG
function InfoBox(opts) {
google.maps.OverlayView.call(this);
this.latlng_ = opts.latlng;
this.map_ = opts.map;
this.content = opts.content;
this.offsetVertical_ = -195;
this.offsetHorizontal_ = 5;
this.height_ = 165;
this.width_ = 266;
var me = this;
this.boundsChangedListener_ =
google.maps.event.addListener(this.map_, "bounds_changed", function () {
return me.panMap.apply(me);
});
// Once the properties of this OverlayView are initialized, set its map so
// that we can display it. This will trigger calls to panes_changed and
// draw.
this.setMap(this.map_);
}
Here is a partial solution. Didn't want to spend time going through and learning about InfoBoxes - Infowindow would have been solved.
The following will remove the click event when you click/open a infoBOX. you need to find a way to re-add when closing the InfoBOX. InfoBox != Infowindow, I have no API to do it.
you need to add/change:
ADD: var listener to the top of script;
CHANGE:
google.maps.event.addListener(map, 'click', function(event) {
alert("google.maps.event.addListener");
});
to
listener = google.maps.event.addListener(map, 'click', function(event) {
alert("google.maps.event.addListener");
});
Change:
google.maps.event.addListener(markers[i], "click", function (e) {
var infoBox = new InfoBox({
latlng: this.getPosition(),
map: map,
content: this.content
});
google.maps.event.removeListener(listener)
});
To
google.maps.event.addListener(markers[i], "click", function (e) {
var infoBox = new InfoBox({
latlng: this.getPosition(),
map: map,
content: this.content
});
google.maps.event.removeListener(listener)
});
CODEPEN: https://codepen.io/anon/pen/rwLrYJ?editors=0010
Related
I do not know how to do in order to automatically close a InfoWindow when another opens.
function bindInfoWindow(marker, map, title, race, loc, org, web, link) {
var infoWindowVisible = (function () {
var currentlyVisible = false;
return function (visible) {
if (visible !== undefined) {
currentlyVisible = visible;
}
return currentlyVisible;
};
}());
iw = new google.maps.InfoWindow();
google.maps.event.addListener(marker, 'click', function() {
if (infoWindowVisible()) {
iw.close();
infoWindowVisible(false);
} else {
var html= "<div style='color:#000;background-color:#fff;padding:5px;width:250px;'><h4>"+title+"</h4><p>Race</p><h4>"+race+"</h4><p>Location</p><h4>"+loc+"</h4><hr /><p>Organizzazione</p><h4>"+org+"</h4><a href='"+link+"'' >"+web+"<a></div>";
iw = new google.maps.InfoWindow({content:html});
iw.open(map,marker);
infoWindowVisible(true);
}
});
google.maps.event.addListener(iw, 'closeclick', function () {
infoWindowVisible(false);
});
}
I tried but I can not find my type cases.
If you only want one infowindow ever, only create one InfoWindow (in the global scope), reuse it and change its contents when a marker is clicked, close it if the user clicks on the map.
similar question
var iw = new google.maps.InfoWindow(); // single global infowindow
google.maps.event.addListener(map, 'click', function() {
iw.close();
});
function bindInfoWindow(marker, map, title, race, loc, org, web, link) {
google.maps.event.addListener(marker, 'click', function() {
iw.close();
var html= "<div style='color:#000;background-color:#fff;padding:5px;width:250px;'><h4>"+title+"</h4><p>Race</p><h4>"+race+"</h4><p>Location</p><h4>"+loc+"</h4><hr /><p>Organizzazione</p><h4>"+org+"</h4><a href='"+link+"'' >"+web+"<a></div>";
iw.setContent(html);
iw.open(map,marker);
});
}
working fiddle - different code as you didn't provide a complete example, demonstrates the concept.
I'm trying to use Shadowbox.js inside multiple InfoWindow :
function initialize() {
//create the Map
var map = new google.maps.Map(...);
//create the Markers
var marker = new google.maps.Marker(...);
var marker2 = new google.maps.Marker(...);
//create the InfoWindow
var infoWindow = new google.maps.InfoWindow();
//link the Markers to the InfoWindow
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent('Working shadowbox link');
infoWindow.open(map, marker);
});
google.maps.event.addListener(marker2, 'click', function() {
infoWindow.setContent('Broken shadowbox link');
infoWindow.open(map, marker2);
});
//enable Shadowbox
google.maps.event.addListener(infoWindow, 'domready', function() {
Shadowbox.init({
overlayOpacity: 0.8
});
});
}
google.maps.event.addDomListener(window, 'load', initialize);
As you can see, I've successfully made it work, but only for the first InfoWindow.
This seems to be caused by my event attachment, I'm using domready :
google.maps.event.addListener(infoWindow, 'domready', function() {});
I can't find another way to "reinit" Shadowbox for each InfoWindow.
Any advice ?
As usual, I find the solution I'm searching for just a few minutes after writing my question...
To get Shadowbox working on every InfoWindow : you need to call Shadowbox player manually.
Use a custom class instead of rel=shadowbox :
<a href="http://placehold.it/200x200.jpg" class="dyn-shadowbox">
Shadowbox link
</a>
Every time domready is triggered on an InfoWindow, manually attach an event listener to every .dyn-shadowbox link :
google.maps.event.addListener(infoWindow, 'domready', function() {
var dynlinks = document.getElementsByClassName('dyn-shadowbox');
var n = dynlinks.length;
for (var i = 0; i < n; i++) {
var link = dynlinks[i];
link.removeEventListener('click');
link.addEventListener('click', function(ev) {
ev.preventDefault();
Shadowbox.open({
link: link,
content: link.getAttribute('href'),
player: 'img',
title: ''
});
});
}
});
Updated JSFiddle
I using this technique: http://www.geocodezip.com/v3_MW_example_map2.html
I want to have the first info window open when the map loads.
I also want to be able to center the map when you click a location link.
Can anyone help?
JS:
// this variable will collect the html which will eventually be placed in the side_bar
var side_bar_html = "";
// arrays to hold copies of the markers and html used by the side_bar
// because the function closure trick doesnt work there
var gmarkers = [];
var map = null;
function initialize() {
// create the map
var myOptions = {
zoom: 12,
center: new google.maps.LatLng(50.822096, -0.375736),
mapTypeControl: true,
mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
navigationControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel:false
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
google.maps.event.addListener(map, 'click', function() {
infowindow.close();
});
// Add markers to the map
// Set up three markers with info windows
// add the points
var point = new google.maps.LatLng(50.810438, -0.374925);
var center = new google.maps.LatLng(50.810438, -0.374925);
var marker = createMarker(point,"Worthing","<p><b>Worthing</b><br>1-13 Buckingham Road,<br>Worthing,<br>West Sussex,<br>BN11 1TH</p>")
var point = new google.maps.LatLng(51.497421,-0.141604);
var center = new google.maps.LatLng(51.497421,-0.141604);
var marker = createMarker(point,"London","<p><b>London</b><br>Portland House,<br>Bressenden Place,<br>London,<br>SW1E 5RS</p>")
var point = new google.maps.LatLng(-33.867487,151.20699);
var center = new google.maps.LatLng(-33.867487,151.20699);
var marker = createMarker(point,"Sydney","<p><b>Sydney</b><br>Level 1, Cosco House,<br>95-101 Sussex Street,<br>Sydney NSW<br>Australia 2000</p>")
// put the assembled side_bar_html contents into the side_bar div
document.getElementById("side_bar").innerHTML = side_bar_html;
$('#side_bar li:first-child').addClass("active");
$('#side_bar li').click(function(){
$('#side_bar li').removeClass("active");
$(this).addClass("active");
});
}
var infowindow = new google.maps.InfoWindow(
{
size: new google.maps.Size(150,50)
});
// This function picks up the click and opens the corresponding info window
function myclick(i) {
google.maps.event.trigger(gmarkers[i], "click");
}
// A function to create the marker and set up the event window function
function createMarker(latlng, name, html) {
var contentString = html;
var iconBase = '../Themes/FreshEgg/assets/img/';
var marker = new google.maps.Marker({
position: latlng,
map: map,
zIndex: Math.round(latlng.lat()*-100000)<<5,
icon: iconBase + 'map_marker_24x46.png',
animation: google.maps.Animation.DROP
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map,marker);
});
infowindow.setContent(contentString);
infowindow.open(map,marker);
// save the info we need to use later for the side_bar
gmarkers.push(marker);
// add a line to the side_bar html
side_bar_html += '<li><a href="javascript:myclick(' + (gmarkers.length-1) + ')">' + name + '<\/a></li>';
}
google.maps.event.addDomListener(window, 'load', initialize);
HTML:
<ul class="list-inline" id="side_bar"></ul>
<div id="map_canvas"></div>
Add a 4th parameter to your createMarker() function for the default state of markers - createMarker(latlng, name, html, show) - where show will be a boolean variable: true to open on load, false to leave it closed. Then when you call createMarker() in your initialize() method specify true for the marker you want open on load.
Then in createMarker() add a condition that handles this for you - something like:
if (show) {
google.maps.event.trigger(marker, "click");
/*if you're going to take this approach, make sure this is triggered after
*you specify your listener
*alternately, you can also setContent() and open() your infoWindow here
*/
}
To have the map pan to the center when you click on the marker, you first need to disable the auto panning of the map when an infoWindow is open. This can be done where you set the options for your infoWindow:
var infowindow = new google.maps.InfoWindow(
{
size: new google.maps.Size(150,50),
disableAutoPan : true
});
Then, in your listener for the click event on the marker add the function to panTo(LatLng) the position of the marker on your map.
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map, marker);
map.panTo(marker.getPosition());
});
I am using below code to open up a infowindow in my map through ajax call
var openedInfoWindow = null;
var infoWindow = new google.maps.InfoWindow();
function profileInitialiser(marker, location) {
google.maps.event.addListener(marker, 'click', function(){
new Ajax.Request('/ajax/', {
parameters: {'action':'profileInfo', 'id':location.id},
onSuccess: function(transport){
addInfoWindow(marker, transport.responseText, location.id);
}
});
});
}
function addInfoWindow(marker, content, id) {
google.maps.event.addListener(marker, 'click', function () {
if (openedInfoWindow != null) {
openedInfoWindow.close();
}
infoWindow.setContent(content);
infoWindow.open(this.map, marker);
openedInfoWindow = infoWindow;
google.maps.event.addListener(infoWindow, 'closeclick', function() {
openedInfoWindow = null;
});
});
}
The above code, profileInitialiser function calling while loading on the marker in the google map.
At fist time, first click on the marker through ajax call, the content of the infowindow comes as response.
In the second click the infowindow will open. Next time onwards, clicking on the marker loading the infowindow comes in first click. Has any one had this bug before ? could some one help me to sort this issue please ?
Your AddInfoWindow function just adds a click listener to the marker when the data comes back from the server. You should also open the infoWindow with the content.
var openedInfoWindow = null;
var infoWindow = new google.maps.InfoWindow();
function profileInitialiser(marker, location) {
// only do this on the first click
google.maps.event.addListenerOnce(marker, 'click', function(){
new Ajax.Request('/ajax/', {
parameters: {'action':'profileInfo', 'id':location.id},
onSuccess: function(transport){
addInfoWindow(marker, transport.responseText, location.id);
}
});
});
}
function addInfoWindow(marker, content, id) {
// display the content when the marker is clicked
google.maps.event.addListener(marker, 'click', function () {
if (openedInfoWindow != null) {
openedInfoWindow.close();
}
infoWindow.setContent(content);
infoWindow.open(this.map, marker);
openedInfoWindow = infoWindow;
google.maps.event.addListener(infoWindow, 'closeclick', function() {
openedInfoWindow = null;
});
});
// click on the marker to display the newly added infowindow
google.maps.event.trigger(marker, 'click');
}
Why are you adding click event listener twice. Just remove the listener from your addInfoWindow function.
Here is the code:
function addInfoWindow(marker, content, id) {
if (openedInfoWindow != null) {
openedInfoWindow.close();
}
infoWindow.setContent(content);
infoWindow.open(this.map, marker);
openedInfoWindow = infoWindow;
google.maps.event.addListener(infoWindow, 'closeclick', function() {
openedInfoWindow = null;
});
}
I have a simple enough map on Google Maps V3.
I change the icon image on mouse over listener event, I change it back on mouse out simple enough.
I change the icon again when I click the marker, but, I want to keep that icon while the marker is selected. When I mouse out, the marker icon changes again because I told it to do so in the mouse out listener event.
I need to exclude the selected marker from the mouseout listener event but I can't figure out how to find the marker I have currently selected. Any ideas?
Here is my code
google.maps.event.addListener(marker, 'mouseover', function () {
this.setIcon("images/star-3-white.png");
});
google.maps.event.addListener(marker, 'mouseout', function () {
// this overwrites the image again,
// need to exclude the current one here
this.setIcon("images/star-3.png");
});
google.maps.event.addListener(marker, 'click', function () {
this.setIcon("images/star-3-white.png");
infowindow.setContent(this.html);
infowindow.open(map, this);
});
Either
create a member of the marker .selected and set that when you click on it, then test it in the mouseout function (and the mouseover function if you want to be complete), don't change the icon if it is set.
create a global variable (assuming there is only one marker selected at a time), set that equal to the marker that was clicked. In the mouseout (and mouseover) check if it is equal to the current marker (this), if it is don't change the icon.
A bit long winded but I just added a variable to store the current marker title which I know is unique. I then check to see if it is that one that I am selecting. Also, I make sure to reset all the markers so it doesnt stay the same color as a selected one:
var clickedMarkerTitle = null;
function addMarker(latLng, _title, contentString) {
marker = new google.maps.Marker({
map: map,
position: latLng,
icon: "images/star-3.png",
title: _title,
html: contentString
});
google.maps.event.addListener(marker, 'mouseover', function () {
this.setIcon("images/star-3-white.png");
});
google.maps.event.addListener(marker, 'mouseout', function () {
//this.setIcon("images/star-3.png");
testIcon(this);
});
google.maps.event.addListener(marker, 'click', function () {
resetMarkerIcons();
saveIconState(this);
this.setIcon("images/star-3-white.png");
infowindow.setContent(this.html);
infowindow.open(map, this);
});
markersArray.push(marker);
}
function resetMarkerIcons() {
// reset all the icons back to normal except the one you clicked
for (var i = 0; i < markersArray.length; i++) {
markersArray[i].setIcon("images/star-3.png");
}
}
function saveIconState(marker) {
clickedMarkerTitle = marker.title;
}
function testIcon(marker) {
$('#test').html('<span>' + marker.title + '</span>');
if (clickedMarkerTitle != null) {
$('#test').html('<span>' + marker.title + ' and its not null</span>');
if (marker.title != clickedMarkerTitle) {
$('#test').html('<span>' + marker.title + ' and ' + clickedMarkerTitle + '</span>');
marker.setIcon("images/star-3.png");
}
}
else {
marker.setIcon("images/star-3.png");
}
}
Stumbled on this answer when searching for something else. This will do.
var currentMarker = null;
var markerIcon = 'some.svg';
var markerIconHover = 'some-other.svg';
// Initialize marker here
[...]
// Set current marker on click
google.maps.event.addListener(marker, 'click', function() {
// Reset market icons
clearMarkerIcons();
// Set hovered map marker
marker.setIcon(markerIconHover);
// Set current marker
currentMarker = marker;
// Open infoWindow here
[...]
});
// Set correct icon on mouseover
google.maps.event.addListener(marker, 'mouseover', function() {
marker.setIcon(markerIconHover);
});
// Set correct icon on mouseout
google.maps.event.addListener(marker, 'mouseout', function() {
if (currentMarker !== marker) {
marker.setIcon(markerIcon);
}
});
// Clear all set marker icons
function clearMarkerIcons() {
for (var i = 0; i < map.markers.length; i++) {
map.markers[i].setIcon(markerIcon);
}
}