Customising the google map info window - javascript

I'm struggling to change the size of the infoWindow on google maps apiv3. I've been looking at the documentation here - https://developers.google.com/maps/documentation/javascript/examples/infowindow-simple-max
But I can't seem to change the width and the height of the infoWidow. I would like to be able to just remove the scroll bar that it adds when the content is to large for the default window. To do this I'm going give the window a fixed height and width. Which for some reason isn't working as it should.
Here is my JS for google maps:
var map;
var bounds;
var infowindow;
var markersArray = [];
var data;
var image = '/img/markers/google_icon.png';
function initialize() {
console.log("Map Initialised");
var myLatlng = new google.maps.LatLng(52.8382,-2.327815);
var mapOptions = {
zoom: 6,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
google.maps.visualRefresh = true;
map = new google.maps.Map(document.getElementById('maps-canvas-xx'), mapOptions);
bounds=new google.maps.LatLngBounds();
}
function clearOverlays() {
for (var i = 0; i < markersArray.length; i++ ) {
markersArray[i].setMap(null);
}
markersArray = [];
}
function getMarker(event) {
console.log("Lookup requested.");
$('#code_search').text($('#PostcodePostcode').val());
$('#address_search').show('slow');
/* stop form from submitting normally */
event.preventDefault();
/* get some values from elements on the page: */
var form_data = $(this).serialize();
url = "http://weburl/location/a/",
$.ajax({
crossDomain:true,
dataType: "jsonp",
url: url,
data : form_data,
success: function ( data ) {
clearOverlays();
bounds = new google.maps.LatLngBounds();
for (var i = 0; i < data.locations.length; i++) {
var latlng = new google.maps.LatLng(data.locations[i].lat,data.locations[i].lng);
var contentString = '<div id="infoWrap"><p>' + data.locations[i].name + '</p>' +
'<p style="font-size:8pt;">' + data.locations[i].address.replace(/,/g,',<br>') + '<br>' + data.locations[i].post_code + '<br>' +
data.locations[i].phone + '<br>' + '<a target="_blank" href="' + data.locations[i].url + '">' + data.locations[i].url + '</p></div>';
var infowindow = new google.maps.InfoWindow({
content: contentString,
});
var marker = new google.maps.Marker({
map: map,
position: latlng,
title:data.locations[i].name,
info: infowindow,
content: contentString,
icon: image,
});
bounds.extend(latlng);
markersArray.push(marker);
google.maps.event.addListener(marker, 'click', function() {
marker.info.setContent(this.content);
marker.info.open(map, this);
});
}//close each
map.fitBounds(bounds);
}
});
}
I've tried adding this:
var infowindow = new google.maps.InfoWindow({
content: contentString,
width: "800px",
});
But I can't seem to change the width and height of the infoWindow. Any help would be much appreciated.
Thanks,
Josh

There is no width property in the InfoWindowOptions object, just a maxWidth. To set the size use normal css on the HTML markup in the contentString.
var infowindow = new google.maps.InfoWindow({
content: '<div style="height:200px; width: 800px;">'+ contentString+'</div>';
});

Related

Removing all showed marks Google API

I work in Laravel project and I have module for displaying and removing all stores on a Google map if I choose only 1 store.
This is a duplicate question, however, why my function is not working setting the function showallmarks as null.
Question: How to remove all the marks displayed in the google maps once a button is clicked?
I have here the codes.
Show all marks:
showallmarks();
function showallmarks() {
$.each(locations, function(index, value) {
var position = new google.maps.LatLng(value.store_lat, value.store_long);
var title = value.branch_name;
var address = value.store_address;
var contentString = "<h5>" + title + "</h5>" + address;
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: position,
icon: google.maps.marker,
map: map,
zoom: 12
});
marker.addListener('click', function() {
infowindow.open(map, marker);
});
});
}
Once I click this button the showallmarks must not be shown on the Google map.
var markeronce;
$('button#addresses').click(function() {
//removing all marks
showallmarks(null);
var infowindow = new google.maps.InfoWindow({
content: "<span>Visit us on our store.</span>"
});
var address_href = $(this).val();
var commaPos = address_href.indexOf(',');
var coordinatesLat = parseFloat(address_href.substring(0, commaPos));
var coordinatesLong = parseFloat(address_href.substring(commaPos + 1, address_href.length));
var centerPoint = new google.maps.LatLng(coordinatesLat, coordinatesLong);
if (!markeronce) {
markeronce = new google.maps.Marker({
position: centerPoint,
map: map,
zoom: 8
});
} else {
markeronce.setPosition(centerPoint);
}
map.setCenter(centerPoint);
})
Add Button like
<input type="button" value="Delete" onclick="DeleteMarkers()" />
And try this function
<script type="text/javascript">
var markers = [];
function DeleteMarkers() {
//Loop through all the markers and remove
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
markers = [];
};
</script>

Google Maps API v3 infoWindow.close() not closing others on click

I have been working on this for a while now. I have looked at multiple stack overflow posts on the topic and several tutorials, but I have not been able to get infoWindow.close() to work.
I have even tried using jQuery to click $('#googleMap > div > div > div:nth-child(1) > div:nth-child(4) > div:nth-child(4) > div:nth-child(1) > div:nth-child(3)').click(); which actually seems to work in the browser console, but not when running the click listener.
Any suggestions or directions are much appreciated.
d3.csv('/data/locs.csv', function(locs){
var obj = [];
for(i=0;i<locs.length;i++) {
var country = locs[i].country;
var location = locs[i].location;
var lat = locs[i].lat;
var long = locs[i].long;
var description = locs[i].description;
obj.push({
con: country,
location: location,
lat: lat,
lng: long,
description: description
});
}
console.log(obj);
initMap(obj)
});
function initMap(obj, error) {
if (error){console.log("Error: "+error)}
var openInfoWindow = null;
var mapProp = {
center: {lat: 39.8283, lng: -98.5795},
zoom: 2
};
var map = new google.maps.Map(document.getElementById("googleMap"), mapProp);
var pointLoc = [];
var labels = [];
var descrip = [];
var locale = [];
for(i=0;i<obj.length;i++) {
pointLoc.push({lat: obj[i].lat, lng: obj[i].lng});
labels.push(obj[i].con);
descrip.push(obj[i].description);
locale.push(obj[i].location);
}
map.data.loadGeoJson();
for (var i = 0; i < pointLoc.length; i++) {
var coords = pointLoc[i];
var latLng = new google.maps.LatLng(coords.lat,coords.lng);
var marker = new google.maps.Marker({
position: latLng,
map: map
});
var contentStr = '<div id="popcontent">'+
'<div id="siteNotice">'+
'</div>'+
'<h1 id="firstHeading" class="firstHeading">'+descrip[i]+'</h1>'+
'<p>'+locale[i]+', '+labels[i]+'</p>' +
'</div>';
var infoWindow = new google.maps.InfoWindow({
maxWidth: 300
});
google.maps.event.addListener(marker,'click', (function(marker,contentStr,infowindow){
infowindow.close();
return function() {
infowindow.setContent(contentStr);
infowindow.open(map, marker);
};
})(marker,contentStr,infoWindow));
}
}
Stephen's answer identifies the problem with the infowindow. I want to help you learn to write simpler code.
There is a lot of complication in this code that you don't need; in fact you can get rid of most of the code!
The code first converts the locs array to a very similar obj array that has a couple of fields renamed.
Then it converts this obj array to four individual arrays pointLoc, labels, descrip, and locale.
None of this conversion is needed.
Also, when naming an array, I recommend using a plural name for the array and the singular form of that name for an element of the array. You did this in some places, just not consistently.
There is a map.data.loadGeoJson(); call that doesn't do anything because no URL is provided.
You also don't need the function-that-returns-a-function in the click listener, if you provide a closure in a simpler way as in the code below.
Here's an example of how you could do the whole thing in a much simpler manner:
d3.csv( '/data/locs.csv', function( places ) {
var infoWindow;
var map = new google.maps.Map( document.getElementById('googleMap'), {
center: { lat: 39.8283, lng: -98.5795 },
zoom: 2
});
places.forEach( function( place ) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng( place.lat, place.long ),
map: map
});
google.maps.event.addListener( marker, 'click', function() {
if( infoWindow ) infoWindow.close();
var content =
'<div id="popcontent">' +
'<div id="siteNotice">' +
'</div>' +
'<h1 id="firstHeading" class="firstHeading">' + place.description + '</h1>' +
'<p>' + place.location + ', ' + place.country + '</p>' +
'</div>';
infoWindow = new google.maps.InfoWindow({
maxWidth: 300,
content: content
});
infoWindow.open( map, marker );
});
});
});
Your variable infoWindow goes out of scope when returning a function, and you not modifying the outer infoWindow, but the one passed into the function. Try this.
d3.csv('/data/locs.csv', function(locs){
var obj = [];
for(i=0;i<locs.length;i++) {
var country = locs[i].country;
var location = locs[i].location;
var lat = locs[i].lat;
var long = locs[i].long;
var description = locs[i].description;
obj.push({
con: country,
location: location,
lat: lat,
lng: long,
description: description
});
}
console.log(obj);
initMap(obj)
});
function initMap(obj, error) {
if (error){console.log("Error: "+error)}
var openInfoWindow = null;
var mapProp = {
center: {lat: 39.8283, lng: -98.5795},
zoom: 2
};
var map = new google.maps.Map(document.getElementById("googleMap"), mapProp);
var pointLoc = [];
var labels = [];
var descrip = [];
var locale = [];
for(i=0;i<obj.length;i++) {
pointLoc.push({lat: obj[i].lat, lng: obj[i].lng});
labels.push(obj[i].con);
descrip.push(obj[i].description);
locale.push(obj[i].location);
}
map.data.loadGeoJson();
for (var i = 0; i < pointLoc.length; i++) {
var coords = pointLoc[i];
var latLng = new google.maps.LatLng(coords.lat,coords.lng);
var marker = new google.maps.Marker({
position: latLng,
map: map
});
var contentStr = '<div id="popcontent">'+
'<div id="siteNotice">'+
'</div>'+
'<h1 id="firstHeading" class="firstHeading">'+descrip[i]+'</h1>'+
'<p>'+locale[i]+', '+labels[i]+'</p>' +
'</div>';
var infoWindow = new google.maps.InfoWindow({
maxWidth: 300
});
google.maps.event.addListener(marker,'click', (function(marker,contentStr,infowindow){
infowindow.close();
return((function(infowindow) {
infowindow.setContent(contentStr);
infowindow.open(map, marker);
})(infowindow));
})(marker,contentStr,infoWindow));
}
}
I was able to handle it easily with jQuery trigger event.
jQuery('.gm-ui-hover-effect').trigger('click');
Just put above code inside addListener function of marker and don't forget to include jQuery in your script.

Add listener event for multiple markers in Google Maps API

I am using Google Maps API in Rails. Getting my all locations from ajax call and displaying it in for loop. I followed this link When I copy paste this
code in my file it seems to work perfectly. But when I am trying to do the same thing for my code. It keeps showing the last marker info.
jQuery(function($) {
var myCenter = new google.maps.LatLng(51.508742,-0.120850);
var mapCanvas = document.getElementById("map");
var mapOptions = {center: myCenter, zoom: 5};
var map = new google.maps.Map(mapCanvas, mapOptions);
$.ajax({
url: "/list_proposals",
type: "GET",
dataType: "json",
success:function(data) {
placeMarker(map, data);
}
});
function placeMarker(map, data){
for (var i = 0; i < data.length; i++) {
var location_data = data[i];
var lat = location_data["lat"];
var long = location_data["long"];
var planting_proposal = location_data["planting_proposal"];
var proposal_id = planting_proposal["id"];
var title = planting_proposal["title"];
var photo_url = planting_proposal["main_photo"]["attachment_thumb_url"];
latlngset = new google.maps.LatLng(lat, long);
var image = {
url: window.location.origin + "/" + photo_url,
size: new google.maps.Size(50, 50),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(0, 32)
};
var marker = new google.maps.Marker({
map: map, title: title , position: latlngset, icon: image
});
map.setCenter(marker.getPosition());
var show_proposal_link = '' + title + '';
var contentString = '<div class="card text-center" style="width: 20rem;">' +
'<div class="card-block">' +
'<h4 class="card-title">'+ show_proposal_link + '</h4>' +
'<p class="card-text">' + '<img src="'+ window.location.origin + "/" + photo_url + '" width="100%;"/>' + '</p>' +
'</div>' +
'</div>';
var infowindow = new google.maps.InfoWindow();
google.maps.event.addListener(marker,'click', (function(marker,content,infowindow){
return function() {
infowindow.setContent(contentString);
infowindow.open(map, marker);
};
})(marker,content,infowindow));
}
}
});
I am new in Google Maps API. Please me help me out with it what am I doing wrong?
You should correctly implement an IIFE in your code. Please replace the google.maps.event.addListener(marker,... part of the code with the following IIFE:
(function(marker,content,infowindow) {
google.maps.event.addListener(marker,'click', function() {
infowindow.setContent(content);
infowindow.open(map, marker);
});
})(marker,contentString,infowindow);
Proof of concept
var map;
var locations = [
{
planting_proposal: {
id: 1,
title: "Proposal 1"
},
lat: 41.386043,
long: 2.14561
},
{
planting_proposal: {
id: 2,
title: "Proposal 2"
},
lat: 41.417371,
long: 2.172115
},
{
planting_proposal: {
id: 3,
title: "Proposal 3"
},
lat: 41.399475,
long: 2.184048
}
]
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 41.385064, lng: 2.173403},
zoom: 12
});
placeMarker(map, locations);
}
function placeMarker(map, data){
for (var i = 0; i < data.length; i++) {
var location_data = data[i];
var lat = location_data["lat"];
var long = location_data["long"];
var planting_proposal = location_data["planting_proposal"];
var proposal_id = planting_proposal["id"];
var title = planting_proposal["title"];
latlngset = new google.maps.LatLng(lat, long);
var marker = new google.maps.Marker({
map: map,
title: title ,
position: latlngset
});
var show_proposal_link = '' + title + '';
var contentString = '<div class="card text-center" style="width: 20rem;">' +
'<div class="card-block">' +
'<h4 class="card-title">'+ show_proposal_link + '</h4>' +
'</div>' +
'</div>';
var infowindow = new google.maps.InfoWindow();
(function(marker,content,infowindow) {
google.maps.event.addListener(marker,'click', function() {
infowindow.setContent(content);
infowindow.open(map, marker);
});
})(marker,contentString,infowindow);
}
}
#map {
height: 100%;
}
html, body {
height: 100%;
margin: 0;
padding: 0;
}
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDztlrk_3CnzGHo7CFvLFqE_2bUKEq1JEU&callback=initMap"
async defer></script>
I hope this helps!

google maps infowindow positioning with polylines

I have a map with multiple polylines which I am looking to display infowindow for each line. I have the infowindow working but it is not positioning to the event click as it should be. Instead, each window displays in the same place. Can't seem to track down the root of the issue.
<script type="text/javascript">
var contentString = "";
var infowindow = new google.maps.InfoWindow({
content: contentString,
});
function initialize() {
var myLatlng = new google.maps.LatLng(30.695895, -97.354080);
var mapOptions = {
zoom: 5,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.TERRAIN,
};
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
downloadUrl("data.xml", function(data) {
var xml = xmlParse(data);
var polylines = xml.documentElement.getElementsByTagName("polyline");
var polylineData = new Array();
for (var i = 0; i < polylines.length; i++) {
polylineData[i] = {id:polylines[i].getAttribute("id"),
name:polylines[i].getAttribute("name"),
olat:polylines[i].getAttribute("olat"),
olng:polylines[i].getAttribute("olng"),
dlat:polylines[i].getAttribute("dlat"),
dlng:polylines[i].getAttribute("dlng")}
}
for (var j = 0; j < polylineData.length; j++) {
var path = [
new google.maps.LatLng(parseFloat(polylineData[j].olat), parseFloat(polylineData[j].olng)),
new google.maps.LatLng(parseFloat(polylineData[j].dlat), parseFloat(polylineData[j].dlng))
];
var polyline = new google.maps.Polyline({
path: path,
strokeWeight: 2
});
google.maps.event.addListener(polyline, 'click', (function(event,index){
return function(){
infowindow.content = '<div class="infobox" style="width:280px;"><span class="name">' + polylineData[index].name + '</span></div>';
var point = event.latLng;
infowindow.setPosition(point);
infowindow.open(map);
};
})(event,j));
polyline.setMap(map);
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
XML data looks like this:
<polylines>
<polyline id="176" name="Line Name" olat="53.545204" olng="-113.369492" dlat="53.545204" dlng="-113.369492"/>
</polylines>
I have read some similar posts but none of the answers have worked in this case thus far. Thanks!
event must be the argument passed to the returned function:
google.maps.event.addListener(polyline, 'click', (function(index){
//_________________________________________________________^:the index of the item
return function(event){
//________________^:the event
infowindow.content = '<div class="infobox" style="width:280px;"><span class="name">' + polylineData[index].name + '</span></div>';
var point = event.latLng;
infowindow.setPosition(point);
infowindow.open(map);
};
})(j));

'myFunction is not a function', JS & Google Maps v 3?

Hello I cannot figure out why I get this error.
I've got a list with inputs which values contain lat/long/name/address.
Printing the markers on the map works fine, using the infowin workED fine, till I realized that it only openend the same info in all windows. Soo, obviously I needed to attach this (the marker i just clicked) to the eventListner.
But, when doing this I get an error saying view.createMarkerHTML is not a function.
Question: What do I do to attach the right info to be open, on the right marker?
view = {
map: {
init: function init (){
view.map.initMap();
},
initMap: function initMap() {
if(navigator.geolocation) {
function hasPosition(position) {
var point = new google.maps.LatLng(position.coords.latitude, position.coords.longitude),
myOptions = {
zoom: 12,
center: point,
mapTypeId: google.maps.MapTypeId.ROADMAP
},
mapDiv = document.getElementById("map"),
map = new google.maps.Map(mapDiv, myOptions);
view.map.handleMarkers(map);
}
navigator.geolocation.getCurrentPosition(hasPosition);
}
},
handleMarkers: function handleMarkers(map) {
var list = $('#pois input'),
l = list.length,
i = 0, lat = '', long = '', marker = {}, theName = '', address = '', info = {};
for (i = 0; i < l; i += 1) {
info = $(list[i]).val().split('|');
lat = parseFloat(info[0], 10);
long = parseFloat(info[1], 10);
theName = info[2];
address = info[3];
marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, long),
map: map,
icon: icon
});
google.maps.event.addListener(marker, 'click', function() {
currentMarker = this;view.map.createMarkerHTML(map, theName, address);
});
}
} ,
createMarkerHTML: function createMarkerHTML(map, theName, address) {
var contentString =
'<div id="gMapInfoWin">' +
'<h1>' + theName + '</h1>' +
'<ul>' +
'<li>' + address + '</li>' +
'</ul>' +
'</div>'
;
currentMarker.infowindow = new google.maps.InfoWindow({
content: contentString
});
currentMarker.infowindow.open(map, currentMarker);
}
}
};
Shouldn't you use a closure to keep the values of your variables set in the loop ?
(function(theName, address) {
google.maps.event.addListener(marker, 'click', function() {
currentMarker = this;view.map.createMarkerHTML(map, theName, address);
});
}(theName, address));
You could even add your marker in parameter instead of using currentMarker
I'll wager that it's a scoping issue. Not having access to your libs I can't be sure that this will work, but try replacing:
google.maps.event.addListener(marker, 'click', function() {
currentMarker = this;view.map.createMarkerHTML(map, theName, address);
});
with this:
google.maps.event.addListener(marker,
'click',
createClickListener( this,
map,
theName,
address ) );
and then add this function somewhere else in the program:
function createClickListener( cm, map, theName, address )
{
return function() {
currentMarker = cm;
view.map.createMarkerHTML(map, theName, address);
}
}
for (i = 0; i < l; i += 1) {
info = $(list[i]).val().split('|');
lat = parseFloat(info[0], 10);
long = parseFloat(info[1], 10);
marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, long),
map: map,
icon: icon
});
marker.theName = info[2];
marker.address = info[3];
google.maps.event.addListener(marker, 'click', function() {
currentMarker = this;
m_name = this.theName;
m_address = this.address
view.map.createMarkerHTML(map, m_name, m_address);
});
}
marker.theName = info[2];
marker.address = info[3];
currentMarker = this;
m_name = this.theName;
m_address = this.address
... is the soulution!

Categories

Resources