How to close POI's InfoWindow? - google-maps-api-3

I'm trying to make POI's InfoWindow close when click a link.
I overrided the setContent of InfoWindow like this:
//override the built-in setContent-method
google.maps.InfoWindow.prototype.setContent = function (content) {
content = content.innerHTML + '<br/> Save place';
//run the original setContent-method
fx.apply(this, arguments);
};
Note: I didn't create any InfoWindow object to reference to use close() method.

In your override function capture a global reference to the infowindow so you can reference it to close it.
Your override of the infowindow doesn't work. I took a working version from this question: How to get a click event when a user clicks a (business) place on the map
proof of concept fiddle
code snippet:
var geocoder;
var map;
var infowindow;
//keep a reference to the original setPosition-function
var fx = google.maps.InfoWindow.prototype.setPosition;
// from https://stackoverflow.com/questions/24234106/how-to-get-a-click-event-when-a-user-clicks-a-business-place-on-the-map/24234818#24234818
//override the built-in setPosition-method
google.maps.InfoWindow.prototype.setPosition = function() {
//logAsInternal isn't documented, but as it seems
//it's only defined for InfoWindows opened on POI's
if (this.logAsInternal) {
// save reference in global infowindow variable.
infowindow = this;
google.maps.event.addListenerOnce(this, 'map_changed', function() {
var map = this.getMap();
//the infoWindow will be opened, usually after a click on a POI
if (map) {
//trigger the click
google.maps.event.trigger(map, 'click', {
latLng: this.getPosition()
});
}
});
}
//call the original setPosition-method
fx.apply(this, arguments);
};
function initialize() {
var map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
google.maps.event.addDomListener(document.getElementById('btn'), 'click', function(e) {
// close the last opened POI infowindow
infowindow.close();
});
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<input id="btn" type="button" value="close IW" />
<div id="map_canvas"></div>

Related

How to close an open google maps infowindow by clicking marker again

I'm trying to close a open google maps infowindow by clicking a marker again. Currently there are only questions about how to close all other infowindows when clicking the map or other markers.
How to close an open google maps infowindow by clicking the same marker again? Currently I can only close an infowindow by clicking the cross on the top right corner of the infowindow.
This is what I tried but it doesn't even open the infowindow:
EncoreMarker.addListener('click', function () {
if (EncoreInfoCard.open) {
EncoreInfoCard.close(map, EncoreMarker);
}
else {
EncoreInfoCard.open(map, EncoreMarker);
}
});
Your code won't work because open is a function that opens the InfoWindow, not a boolean that tells whether it is open or not.
This works for me:
EncoreMarker.addListener('click', function () {
// create a custom property of the InfoWindow, defaults to a value that evaluates as false
if (EncoreInfoCard.isOpen) {
EncoreInfoCard.close(map, EncoreMarker);
EncoreInfoCard.isOpen = false;
}
else {
EncoreInfoCard.open(map, EncoreMarker);
EncoreInfoCard.isOpen = true;
}
});
proof of concept fiddle
code snippet:
// This example displays a marker at the center of Australia.
// When the user clicks the marker, an info window opens.
// When the user clicks the makrer again, the info window closes.
function initMap() {
var uluru = {
lat: -25.363,
lng: 131.044
};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: uluru
});
var EncoreInfoCard = new google.maps.InfoWindow({
content: "<b>This is a Test</b>"
});
google.maps.event.addListener(EncoreInfoCard, 'closeclick', function() {
EncoreInfoCard.isOpen = false;
});
var EncoreMarker = new google.maps.Marker({
position: uluru,
map: map,
title: 'Uluru (Ayers Rock)'
});
EncoreMarker.addListener('click', function() {
if (EncoreInfoCard.isOpen) {
EncoreInfoCard.close(map, EncoreMarker);
EncoreInfoCard.isOpen = false;
} else {
EncoreInfoCard.open(map, EncoreMarker);
EncoreInfoCard.isOpen = true;
}
});
}
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap">
</script>

Google maps API getting infowindow on click with geojson file

I am using the google maps API and I am displaying polygons on a map using a GeoJSON file. When the user presses inside the polygon, I would like an InfoWindow to appear and display data that is stored in the properties. Seems easy enough but when I am clicking on the polygons, nothing is popping up. Can anyone explain what I am doing wrong?
Below is what I am currently attempting:
map.data.loadGeoJson('plant_bounds_2011.json');
map.data.setStyle({
fillColor: 'red',
strokeWeight: 1
});
var infowindow = new google.maps.InfoWindow({
content: "hello"
});
map.data.addListener('click', function(event) {
let id = event.feature.getProperty('ID');
let name = event.feature.getProperty('HORZ_ORG');
let html = id + " " + name;
infowindow.setContent(html); // show the html variable in the infowindow
infowindow.setPosition(event.feature.getGeometry().get()); // anchor the infowindow at the marker
infowindow.setOptions({pixelOffset: new google.maps.Size(0,-30)}); // move the infowindow up slightly to the top of the marker icon
infowindow.open(map);
});
There is a javascript error with the posted code: Uncaught TypeError: event.feature.getGeometry(...).get is not a function on the line:
infowindow.setPosition(event.feature.getGeometry().get()); // anchor the infowindow at the marker`
A Data.Polygon geometry doesn't have a .get() method. It has a .getArray() method (which returns an array of LineStrings)
One location to place the InfoWindow at would be the point clicked (which is in the polygon):
infowindow.setPosition(event.latLng);
(if you want to either add an fixed point for the infowindow to the GeoJson or you want to compute a fixed point from the polygon you can do that as well)
proof of concept fiddle
code snippet:
function initialize() {
var map = new google.maps.Map(
document.getElementById("map_canvas"), {
zoom: 4,
center: {
lat: -28,
lng: 137
},
mapTypeId: google.maps.MapTypeId.ROADMAP
});
map.data.loadGeoJson('https://storage.googleapis.com/mapsdevsite/json/google.json');
map.data.setStyle({
fillColor: 'red',
strokeWeight: 1
});
var infowindow = new google.maps.InfoWindow({
content: "hello"
});
map.data.addListener('click', function(event) {
let id = event.feature.getProperty('ID');
let name = event.feature.getProperty('HORZ_ORG');
if (typeof id == "undefined") id = event.feature.getProperty('letter');
if (typeof name == "undefined") name = event.feature.getProperty('color');
let html = id + " " + name;
infowindow.setContent(html); // show the html variable in the infowindow
infowindow.setPosition(event.latLng);
infowindow.setOptions({
pixelOffset: new google.maps.Size(0, 0)
}); // move the infowindow up slightly to the top of the marker icon
infowindow.open(map);
});
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map_canvas"></div>

Google Maps display none document ready

I have a problem with the wrapper for the Google map. The class is set by document ready to display:none. If I click on the link the map must be set on show(). It works, but the map doesn't display right.
Here's a screenshot:
And here is my JSFiddle example.
Here my HTML code:
show map
<div class="advertise-mapper">
<div class="responsiveContaineradv">
<div id="map-canvas" class="map-adver"></div>
</div>
</div>
Here my JS Code:
jQuery(document).ready(function() {
jQuery(document).on("click", ".advertise-map", function(e) {
e.preventDefault();
jQuery('.advertise-mapper').show();
});
});
var map;
function initialize() {
var locations = [
['<h4>BMX Golden MILE 20 Fahrrad</h4>250.00 €<br>zur Kleinanzeige', 51.4627921, 6.9787572],
['<h4>Apple Macbook Air 13 A1466 Juni 2013</h4>800.00 €<br>zur Kleinanzeige', 51.665041, 7.631431],
['<h4>Apple iPod nano 16 GB Grün 6. Generation</h4>60.00 € VB<br>zur Kleinanzeige', 51.5096015, 7.377755],
];
var myLatlng = new google.maps.LatLng(51.513587, 7.465298);
var mapOptions = {
zoom: 11,
center: myLatlng
}
var infowindow = new google.maps.InfoWindow({
maxWidth: 360
});
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var markers = new Array();
for (var i = 0; i < locations.length; i++) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map,
animation: google.maps.Animation.DROP
});
markers.push(marker);
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
function autoCenter() {
// Create a new viewpoint bound
var bounds = new google.maps.LatLngBounds();
// Go through each...
for (var i = 0; i < markers.length; i++) {
bounds.extend(markers[i].position);
}
// Fit these bounds to the map
map.fitBounds(bounds);
}
autoCenter();
}
google.maps.event.addDomListener(window, 'load', initialize);
How can I make the map display correctly when shown?
I would make a few small corrections, the most important of which goecodezip mentioned in the comments.
In your onclick of .advertise-map, add the map resize (important) and autoCenter (optional).
jQuery(document).on("click",".advertise-map",function(e){
e.preventDefault();
jQuery('.advertise-mapper').show();
google.maps.event.trigger(map, "resize");
autoCenter();
});
Next, I'd make 'markers' a global variable:
var map;
var markers = new Array();
Finally, I'd move the autoCenter() function out from the initialize function.
With all those changes, I believe this is what you're looking for: http://jsfiddle.net/2xn7wywo/22/

Trying to find error why map isn't centered when resize window

I'm using a dom listener to set the center of the map when a user is resizing the window, but i'm confused because nothing happens!? What have I missed? Every thing else works fine with the map in responsive design. Help is preciated.
If someone is wondering why I have this code {$mapPoints} this is a PHP string of all markers.
EDIT 2:
At start I have the markers in the center of the map. Then I pan the map and the markers isn't in the center any more. When I resize the window I want the markers at the center of the map as it was from the beginning (55.678939, 12.568359). Have I miss understodd something or isn't this possible? I have also tried to set the center of the map to the these coordinates when resizing the window.
EDIT 1:
CSS for the map:
#map_canvas
{
width: 100%;
height: 350px;
margin: 20px 0 20px 0px;
}
var map = null;
var infowindow = new google.maps.InfoWindow();
var iconBase = 'images/mapNumbers/number';
function initialize() {
var myOptions = {
zoom: 11,
center: new google.maps.LatLng(55.678939, 12.568359),
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
google.maps.event.addListener(map, 'click', function () {
infowindow.close();
});
google.maps.event.addListener(map, 'zoom_changed', function () {
infowindow.close();
});
google.maps.event.addDomListener(window, 'resize', function() {
//map.setCenter(55.678939, 12.568359);
var center = map.getCenter();
google.maps.event.trigger(map, 'resize');
map.setCenter(center);
});
// Add markers to the map
var point;
{$mapPoints}
}
// Create markers
function createMarker(latlng, html, name, number) {
var marker = new google.maps.Marker({
position: latlng,
map: map,
title: name,
icon: iconBase + number + '.png'
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.setContent(html);
infowindow.open(map, marker);
//map.setCenter(marker.getPosition());
});
}
google.maps.event.addDomListener(window, 'load', initialize);
It seems that at the beginning you almost got it right. I did the following changes:
function initialize() {
var markerPos = new google.maps.LatLng(55.678939, 12.568359);
var myOptions = {
center: markerPos,
...
}
map = new google.maps.Map(document.getElementById("map-canvas"), myOptions);
var marker = new google.maps.Marker({
position: markerPos,
...
});
google.maps.event.addDomListener(window, 'resize', function() {
console.log('window resize');
map.setCenter(markerPos);
var center = map.getCenter();
console.log(center);
// google.maps.event.trigger(map, 'resize');
});
Test should be like you wrote: load the map, pan to the left/right, resize the window. Marker and the map should be centered.
Take a look at the bounds_changed event:
google.maps.event.addListener(map, 'bounds_changed', function() {
//do really cool stuff and change the world or at least a map of it
}

Get Google Maps v3 to resize height of InfoWindow

When I click a marker and the InfoWindow appears, the height does not adjust if the length of the content is longer that the InfoWindow default height (90px).
I am using text-only, no images.
I have tried maxWidth.
I have checked for inherited CSS.
I have wrapped my content in a div
and applied my CSS to that, including
a height.
I have even tried forcing the
InfoWindow to resize with jQuery
using the domready event on the
InfoWindow.
I only have a few hairs left. Here is my JS:
var geocoder;
var map;
var marker;
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(41.8801,-87.6272);
var myOptions = {
zoom: 13,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
function codeAddress(infotext,address) {
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var image = '/path-to/mapMarker.png';
var infowindow = new google.maps.InfoWindow({ content: infotext, maxWidth: 200 });
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
icon: image
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
}
});
}
function checkZipcode(reqZip) {
if ( /[0-9]{5}/.test(reqZip) ) {
$.ajax({
url: 'data.aspx?zip=' + reqZip,
dataType: 'json',
success: function(results) {
$.each(results.products.product, function() {
var display = "<span id='bubble-marker'><strong>"+this.name+"</strong><br>"+
this.address+"<br>"+
this.city+", "+this.state+" "+this.zip+"<br>"+
this.phone+"</span>";
var address = this.address+","+
this.city+","+
this.state+","+
this.zip;
codeAddress(display,address);
});
},
error: function() { $('#information-bar').text('fail'); }
});
} else { $('#information-bar').text('Zip codes are five digit numbers.'); }
}
$('#check-zip').click(function() { $('#information-bar').text(''); checkZipcode($('#requested-zipcode').val()); });
initialize();
InfoText and Address come from an AJAX query of an XML file. Data is not the issue, as it always comes through correctly. codeAddress() is called after the data has been retrieved and formatted.
HTML in the file:
<div id="google_map"> <div id="map_canvas" style="width:279px; height:178px"></div> </div>
CSS for my InfoWindow content (no other CSS applies to the map):
#bubble-marker{ font-size:11px; line-height:15px; }
I finally found a working solution for the problem. Is not as flexible as I wished, but it's pretty good. Fundamentally the key point is: don't use a string as window content but instead a DOM node.
This is my code:
// this dom node will act as wrapper for our content
var wrapper = document.createElement("div");
// inject markup into the wrapper
wrapper.innerHTML = myMethodToGetMarkup();
// style containing overflow declarations
wrapper.className = "map-popup";
// fixed height only :P
wrapper.style.height = "60px";
// initialize the window using wrapper node
var popup = new google.maps.InfoWindow({content: wrapper});
// open the window
popup.open(map, instance);
the following is the CSS declaration:
div.map-popup {
overflow: auto;
overflow-x: hidden;
overflow-y: auto;
}
ps: "instance" refers to the current custom subclass of google.maps.OverlayView (which I'm extending)
Just wrap your content with a div and specify it's height: <div style="height:60px">...</div>, e.g.
myMarker.setContent('<div style="height:60px">' + txt + '</div>');
- In my case it was fairly enough.
Your map canvas is too small. Increase the width/height of your <div id="map_canvas"> element and you should see larger InfoWindows automatically.
That said, I had the same problem on a site I was building. I solved it by creating a cloned div containing the InfoWindow content, measuring that div's width and height, and then setting the InfoWindow content div to have that measured width and height. Here's my code ported into the middle of your codeAddress function (also note that I removed the maxWidth: 200 from your InfoWindow declaration):
function codeAddress(infotext,address) {
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
// Create temporary div off to the side, containing infotext:
var $cloneInfotext = $('<div>' + infotext + '</div>')
.css({marginLeft: '-9999px', position: 'absolute'})
.appendTo($('body'));
// Wrap infotext with a div that has an explicit width and height,
// found by measuring the temporary div:
infotext = '<div style="width: ' + $cloneInfotext.width() + 'px; ' +
'height: ' + $cloneInfotext.height() + 'px">' + infotext +
'</div>';
// Delete the temporary div:
$cloneInfotext.remove();
// Note no maxWidth defined here:
var infowindow = new google.maps.InfoWindow({ content: infotext });
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
}
});
}
Just wrap you InfoBox content with DIV with padding-bottom: 30px;
JS:
map_info_window = new google.maps.InfoWindow();
var $content = $('<div class="infobox">').html(content);
map_info_window.setContent($content.get(0));
map_info_window.open(map, marker);
CSS:
.infobox{
padding-bottom: 30px;
}
It is not really an answer (daveoncode's solution to create a DOM node and use it as content is right), but if you need to dynamically change the content once set (e.g. with jQuery) then you can force gmail to resize the infoWindow with:
infoWindowLinea.setContent(infoWindowLinea.getContent());

Resources