How to display newer Google Map InfoWindows on top of older ones - javascript

I am having Google Map with InfoWindows being added dynamically. The issue is, when two InfoWindows overlap, the recent one won't always be on top of older ones.
How can I make sure latter InfoWindow always show up on top of all other InfoWIndows using Javascript/jQuery?
The InfoWindows are added when I receive new images and coordinates through websocket. Here is my code:
function addToMap(image) {
console.log("In addToMap...");
coordinates = image[2].split(',');
pin=new google.maps.LatLng(coordinates[0], coordinates[1]);
if(marker) {
marker.setMap(null);
}
var markerIcon = image_car_icon;
marker=new google.maps.Marker({
position:pin,
zIndexProcess: function( m )
{
return 9999999 + pin_count;
},
icon:markerIcon
});
marker.setMap(map);
map.setCenter(marker.getPosition());
pin_count++;
if(image[0] != "NOP") {
popup = new google.maps.InfoWindow({
content:'<image id="pin_' + pin_count + '" src="data:image/png;base64,' + image[1] +'"/>',
});
popup.open(map, marker);
}
}
popup is the InfoWindow created when I get a new image. Suppose two images have almost same coordinates, I want the second InfoWindow to be on top (z-index). But, most of the time, the first window stays on top.

I have found out a solution. I am manually modifying the z-index of the marker by using the image as the handle. marker_count is a running marker, so the z-index will be greater than the previous marker.
google.maps.event.addListener(popup, 'domready', function() {
console.log("DOM READY...........................");
// Bring latest Image to top
e = $('#pin_' + img_count).parent().parent().parent().parent();
e.css({
'z-index' : (99999 + marker_count),
});
});

Related

Google Maps API - bouncing marker issue 2

i'm new to javascript, hope you'll forgive me my bad if i'm doing something wrong.
In fact, i've allready found a solution for my problem, but i don't get how exactly get it into my own code.
Google Maps API - bouncing marker issue
Unfortunately i can't just comment it because i'm new on stackoverflow.
My Problem:
I'm working on a map with several markers on it. If i click on a marker, i want it bouncing and switching its color by a different icon i set. All fine till this point, but at the moment all markers i clicked won't stop bouncing. I want the marker bouncing, till i click another marker. At this point the "old" marker should stop bouncing and just the new one start.
//Marker Icons
var unvisitedMarker = 'img/m1.svg';
var activeMarker = 'img/m2.svg';
var visitedMarker = 'img/m3.svg';
//Add Marker Function
function addMarker(props) {
marker = new google.maps.Marker({
position: props.coords,
map: map,
icon: unvisitedMarker
});
//Opens marker information
var marker.addListener('click', function() {
document.getElementById("paperContainer").style.top = '40vh';
document.getElementById("locationBar").style.top = 'calc(40vh - 2em)';
map.panTo(marker.getPosition());
//Panby the map-position
map.panBy(0, 350);
//Set active Marker Icon
marker.setIcon(activeMarker);
//Set Marker Animation
marker.setAnimation(google.maps.Animation.BOUNCE);
});
}
So i got this code from the other Thread i linked from user "doublesharp":
// track marker that is currently bouncing
var currentMarker = null;
function bindInfoWindow(marker, map, infoWindow, html) {
google.maps.event.addListener(marker, 'click', function() {
document.getElementById('loc-info').innerHTML = html;
// remove the bounce from the "old" marker
if (currentMarker) currentMarker.setAnimation(null);
// set this marker to the currentMarker
currentMarker = marker;
// add a bounce to this marker
marker.setAnimation(google.maps.Animation.BOUNCE);
});
}
I don't know exactly how to implement this in my owm code. And further - how do i get realized to switch the icon after it stoped bouncing to the "visitedMarker"?
Thank you very much in advance!
The idea of that solution is to keep a reference to the clicked marker and modify that marker when a new one is clicked.
This is what I mean:
var currentMarker = null; // Define this variable preferably in the global context.
....
marker.addListener('click', function() {
if(currentMarker){ // Check if there is already an active marker
currentMarker.setAnimation(null);
currentMarker.setIcon(visitedMarker);
}
currentMarker = marker;// Keep a reference to this marker because it will became active.
document.getElementById("paperContainer").style.top = '40vh';
document.getElementById("locationBar").style.top = 'calc(40vh - 2em)';
map.panTo(marker.getPosition());
//Panby the map-position
map.panBy(0, 350);
//Set active Marker Icon
marker.setIcon(activeMarker);
//Set Marker Animation
marker.setAnimation(google.maps.Animation.BOUNCE);
});

google maps, adding click event to anchors to open info windows

I have an application using Google maps, currently I have a number of markers added to the page and clicking on them opens up a info window.
I also have a pagniated list of results which I would like to open the corresponding info window when clicked. Currently clicking on one of these anchors opens all of the info windows, but this is as far as I can get currently.
I have a position marker function:
positionMarkers: function(lat, lng, user) {
var marker = new google.maps.Marker({
animation: google.maps.Animation.DROP,
position: new google.maps.LatLng(lat, lng),
map: map
});
if (caption == null) {
var caption = 'No caption available';
} else {
var caption = caption.text;
}
var contentString = '<div class="infoWindow"><h2>' + user + '</h2></div>';
var infowindow = new google.maps.InfoWindow({
content: contentString,
maxWidth: 284
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map, marker);
});
$('.instaframe').bind('click', function(){
infowindow.open(map, marker);
});
}
The trouble I am having is with the bind function towards the end of the snippet. I am not sure where to go to bind the click event with just the marker being added each time the positionMarkers function runs.
Marker one
Marker two
Marker three
Help would be greatly apprecaited.

Gmaps API v3 -> infoWindow Content not showing

I am using Google Maps API v3 on my website and am trying to display markers from a markersArray.
Here's the relevant code:
var map;
var markersArray = [];
var infowindow;
var marker;
Then I am adding the markers in a loop to the array, calling the following function
function addMarker(location, name) {
marker = new google.maps.Marker({
position: location,
map: map,
company: name,
title: name
});
markersArray.push(marker);
}
I am then trying to display the markers, which works like a charm, using this function:
function showOverlays() {
if (markersArray) {
for (var i in markersArray) {
markersArray[i].setMap(map);
google.maps.event.addListener(markersArray[i], 'click', function () {
infowindow.setContent('<div style="height:300px; color:black">' + this.title + '</div>');
infowindow.open(map, this);
});
}
}
}
Now comes my problem: The content of the infoWindows is not showing up. It opens up, but nothing is being displayed...
If I put a 300px high div in it, the infoWindow actually resizes properly.... but no content is being displayed.
I've searched the web up and down and tried fiddling with it, but to no avail.
Has anybody experienced this and might give me a hint as to how to resolve this?
Thanks in advance!
Chris
I just found the error!
I've had the parent div (the DIV that the map canvas is in) styled with CSS... and set the z-index to 11. Apparently that prevented the content of the infowindow to be on top...
Hope that helps some people who might have done the same "mistake" :)
Thanks to kevmc for trying to help
I'm thinking that the marker object doesn't have a title attribute, you need to retrieve it using getTitle():
function showOverlays() {
if (markersArray) {
for (var i in markersArray) {
markersArray[i].setMap(map);
google.maps.event.addListener(markersArray[i], 'click', function () {
infowindow.setContent('<div style="height:300px; color:black">' + this.getTitle() + '</div>');
infowindow.open(map, this);
});
}
}
}

Google API 3 open Infowindow from divs outside google maps

As the title states how can I with Google API 3 open Infowindow from divs outside google maps.
this is what I am doing today but this only working on the last div link and not every link
markerObj = document.getElementById(markerId);
markerObj.onclick = function(){
google.maps.event.trigger(marker, 'click');
}
Any clues?
I think to make this work you'd need to have an array of markers. Then you'd trigger the click on the exact marker you want (right now it'll just do it on your last marker).
So, as you add markers to your map, append them into an array:
var markers = [];
var marker = new google.maps.Marker({ ... });
marker.addListener('click', function() {
infowindow.setContent('blah blah');
infowindow.open(map, this);
});
markers.push(marker);
Then on your divs, pass in an ID to work out which of the array you're dealing with.
<div id="link0">1</div> <div id="link1">2</a> (JS arrays start at zero)
Then just a slight amend to your code:
markerObj = document.getElementById(markerId);
// work out which number it is
var linkID = markerId.replace("link", "");
markerObj.onclick = function(){
google.maps.event.trigger(markers[linkID], 'click');
}

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