I'm trying to create a custom info window for google maps.
I have sort of succeeded with one exception! Basically, the main info window is still visible and I have no idea how to remove it or hide it.
This is a working FIDDLE
And this is what I am following: custom info window
I have this code as mentioned in the link above:
// Reference to the DIV which receives the contents of the infowindow using jQuery
var iwOuter = $('.gm-style-iw');
/* The DIV we want to change is above the .gm-style-iw DIV.
* So, we use jQuery and create a iwBackground variable,
* and took advantage of the existing reference to .gm-style-iw for the previous DIV with .prev().
*/
var iwBackground = iwOuter.prev();
// Remove the background shadow DIV
iwBackground.children(':nth-child(2)').css({'display' : 'none'});
// Remove the white background DIV
iwBackground.children(':nth-child(4)').css({'display' : 'none'});
But this doesn't seem to do anything as you can see in my Fiddle.
Could someone please advise on this issue?
Any help would be appreciated.
Thanks in advance.
Edit:
I think I'm getting somewhere.
I've created a custom Function and put all the code for the removing the background in it. and then I call the customFunction(); right after html='' stuff.
But the issue is that it won't work for the first click but it will work for second click or third click etc...
I've updated the FIDDLE here
any suggestions?
SECOND EDIT:
Getting very close.
https://jsfiddle.net/8yL2vhoe/3/
If you click on one marker and then click on the second one you would see the result that I am looking for. (no background for the main popup).
I just don't understand why it doesn't work for the first click!!
Please see your updated Fiddle here.
Just move the var html = "..."; and var iw = new google.maps.InfoWindow({...}) outside of your marker's click listener.
The click listener for the marker could be made simpler as below:
var activeInfoWindow;
function infoWindow(marker, map, title, address, url) {
var html = "...";
var iw = new google.maps.InfoWindow({
content: html,
//maxWidth: 350
},customFunction());
google.maps.event.addListener(marker, 'click', function () {
if (activeInfoWindow != null) activeInfoWindow.close();
iw.open(map, marker);
activeInfoWindow = iw;
customFunction();
});
}
Also, your createMarker() function should be applied as
function geocodeAddress(locations, i) {
var title = locations[i][0];
var address = locations[i][1];
var url = locations[i][2];
geocoder.geocode({
'address': locations[i][1]
},
function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
createMarker(results, url, title, address);
} else {
alert("geocode of " + address + " failed:" + status);
}
});
}
function createMarker(results, url, title, address) {
var marker = new google.maps.Marker({
icon: url,
map: map,
position: results[0].geometry.location,
title: title,
animation: google.maps.Animation.DROP,
address: address,
url: url
});
infoWindow(marker, map, title, address, url);
bounds.extend(marker.getPosition());
map.fitBounds(bounds);
}
Related
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.
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);
});
}
}
}
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),
});
});
I wrote a script that first geocodes an address and then displays a map of that address.
The trouble is, it only works in Chrome / Chromium. Other browsers (Firefox 10 & IE9) display a grey box. A problem that could be related, if I add a marker to the map, the marker does not show in Chrome.
I know that :
I connect with the API successfully with my API key.
The address is properly geocoded.
I use jQuery UI dialog to display the map. This, however, does not seem to be a problem. Removing the dialog and using a static div creates the same "grey box" result.
Below is my script, how I invoke it, and the website that I am using this on.
Here's the script:
function Map(properties)
{
var that = this;
// the HTML div
this.element = properties.element;
// address string to geocode
this.address = properties.address;
// title to use on the map and on the jQuery dialog
this.title = properties.title;
this.latlng = null;
this.map = null;
this.markers = [];
// geocode address and callback
new google.maps.Geocoder().geocode({'address': this.address}, function(data)
{
// geocoded latitude / longitude object
that.latlng = data[0].geometry.location;
// map options
var options =
{
zoom: 16,
center: that.latlng,
zoomControl: false,
streetViewControl: false,
mapTypeControl: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
// create a map
that.map = new google.maps.Map(that.element, options);
// add a marker
that.markers.push(new google.maps.Marker({map: that.map,
position: that.latlng,
title: that.title + "\n" +
that.address}));
});
this.get_google_map = function()
{
return that.map;
}
// creates a jQuery UI dialog with a map
this.show_in_dialog = function()
{
// because the dialog can resize, we need to inform the map about this
$(that.element).dialog({ width: 400, height: 300, title: that.title,
resizeStop: function(event)
{
google.maps.event.trigger(that.map, 'resize');
},
open: function(event)
{
google.maps.event.trigger(that.map, 'resize');
}});
}
this.center = function()
{
that.map.setCenter(that.latlng);
}
}
Here's how I invoke it :
// grab the address via HTML5 attribute
var address = $("#address").attr("data-address");
// ... and the title
var title = $("#address").attr("data-title") + " Map";
var map_element = document.createElement('div');
// append the newly created element to the body
$("body").append(map_element);
// create my own map object
var map = new Map({ element : map_element,
address : address,
title : title });
// bind a link to show the map
$("#map_link").click(function()
{
map.center();
map.show_in_dialog();
return false;
});
And here's the URL of the problem (click on map):
http://testing.fordservicecoupons.com/dealer/30000/premium_coupon_page
Last but not least, I combine and obfuscate my JavaScripts, so what you see above is not exactly the same as in the source on the website.
This doesn't look good:
resizeStop: function(event) { google.maps.event.trigger(that.element, 'resize'); },
open: function(event) { google.maps.event.trigger(that.element, 'resize'); }
you trigger the resize-event on the element that contains the map(that.element), but you must trigger resize on the google.maps.Map-object (what should be that.map in this case)
Wow... Here was the issue.
The layout that I built was a fluid layout. So, one of the first CSS rules that I have written was:
img, div { max-width: 100%; }
So that divs and images can scale. Well, for whatever reason, Google maps DOES NOT like this rule with the end result being a grey box.
And so I added another rule - an exception for Google maps:
img.no_fluid, div.no_fluid { max-width: none; }
And then, in javascript:
// AFTER DIALOG CREATION
$(dialog).find('*').addClass("no_fluid");
The find('*') will get us all the descendants.
Viola!
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.