This question already has an answer here:
Open infoWindows from an external link outside of the google map
(1 answer)
Closed 4 years ago.
I am displaying markers and info windows on a Google Map using the following (partial) code. I have a listener setup so that when you click a marker, the corresponding info window shows (attached to the marker).
My question is, how can I access the info windows outside of this listener? For example, if I wanted to write Javascript to arbitrarily choose an info window and display it over its marker, can I do that by using its ID somehow?
This code was mostly taken from Google example scripts.
var bounds=new google.maps.LatLngBounds();
var infowindow=new google.maps.InfoWindow(), marker, i;
for (i=0; i<markerLength; i++){
var position=new google.maps.LatLng(markers[i][1], markers[i][2]);
bounds.extend(position);
marker=new google.maps.Marker({
position: position,
map: map,
title: markers[i][0]
});
setmarkers.push(marker);
google.maps.event.addListener(marker, 'click', (function(marker, i){
return function(){
infowindow.setContent(infocontent[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
You could use the position of the marker in an array (if you know it) or you could assign your markers with some custom id property and trigger a click event on a specific marker based on that id.
var map = null;
var markers = [];
var infowindow = new google.maps.InfoWindow();
function initialize() {
var myOptions = {
zoom: 8,
center: new google.maps.LatLng(43.907787, -79.359741),
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"),
myOptions);
google.maps.event.addListener(map, 'click', function() {
infowindow.close();
});
// Setup three markers with info windows
var point;
point = new google.maps.LatLng(43.65654, -79.90138);
createMarker(point, 'This is marker with id aaa', 'aaa');
point = new google.maps.LatLng(43.91892, -78.89231);
createMarker(point, 'This is marker with id abc', 'abc');
point = new google.maps.LatLng(43.82589, -79.10040);
createMarker(point, 'This is marker with id ccc', 'ccc');
}
function createMarker(latlng, html, id) {
var marker = new google.maps.Marker({
position: latlng,
map: map,
myCustomId: id
});
markers.push(marker);
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(html);
infowindow.open(map, marker);
});
}
function clickMarker(id) {
// Loop through markers array
for (var i=0; i<markers.length; i++) {
// Check custom id
if (markers[i].myCustomId === id) {
// Trigger marker click
google.maps.event.trigger(markers[i], 'click');
}
}
}
initialize();
#map_canvas {
height: 150px;
}
<div id="map_canvas"></div>
<hr>
<button onClick="clickMarker('aaa')">Marker with id aaa</button>
<button onClick="clickMarker('abc')">Marker with id abc</button>
<button onClick="clickMarker('ccc')">Marker with id ccc</button>
<script src="https://maps.googleapis.com/maps/api/js"></script>
Related
I a using Google Maps in my app.
The user is to be able to place a marker on any place in the map.
To this end I wrote the following code:
var marker;
function myMap() {
var mapCanvas = document.getElementById("map-canvas");
var myCenter=new google.maps.LatLng(50.833,-12.9167);
var mapOptions = {center: myCenter, zoom: 5};
var map = new google.maps.Map(mapCanvas, mapOptions);
google.maps.event.addListener(map, 'click', function(event) {
//marker.setMap(null); // this line does not work
placeMarker(map, event.latLng);
});
}
function placeMarker(map, location) {
marker = new google.maps.Marker({
position: location,
map: map
});
}
The marker is supposed to always move to the place where the user clicked.
The line
marker.setMap(null);
is supposed to remove the old marker (before the new marker is placed).
However, with this line in the code I cannot place any markers any more. Not including this line means that every marker stays in the map and is not removed (i.e. the map is filling up with markers over time).
Look at the javascript console, you will see Uncaught TypeError: Cannot read property 'setMap' of undefined. The first time, marker is null, you need to only set its map property to null if it already exists.
google.maps.event.addListener(map, 'click', function(event) {
if (marker) marker.setMap(null);
placeMarker(map, event.latLng);
});
proof of concept fiddle
code snippet:
var marker;
function myMap() {
var mapCanvas = document.getElementById("map-canvas");
var myCenter = new google.maps.LatLng(50.833, -12.9167);
var mapOptions = {
center: myCenter,
zoom: 5
};
var map = new google.maps.Map(mapCanvas, mapOptions);
google.maps.event.addListener(map, 'click', function(event) {
if (marker) marker.setMap(null);
placeMarker(map, event.latLng);
});
}
function placeMarker(map, location) {
marker = new google.maps.Marker({
position: location,
map: map
});
}
google.maps.event.addDomListener(window, "load", myMap);
html,
body,
#map-canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map-canvas"></div>
The problem is that you try to use method setMap after the first click when marker variable doesn't have this method. So, first check if marker has the method and then call it.
google.maps.event.addListener(map, 'click', function(event) {
// check if setMap is available and call it.
if(marker.hasOwnProperty('setMap')){
marker.setMap(null);
}
placeMarker(map, event.latLng);
});
I'm trying to display a Google map in a Bootstrap modal with multiple markers. I have found several posts where people were having problems displaying the map on the modal with just one marker, but none with multiple markers. This is what I currently have, but my map is just showing up gray.
var locations = [...]
var complexMap = new google.maps.Map(document.getElementById('complexes-modal-map-canvas'), {
mapTypeId: google.maps.MapTypeId.ROADMAP
});
//create empty LatLngBounds object
var bounds = new google.maps.LatLngBounds();
var infowindow = new google.maps.InfoWindow();
for (i = 0; i < locations.length; i++) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
icon: locations[i][3],
map: complexMap
});
//extend the bounds to include each marker's position
bounds.extend(marker.position);
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent(locations[i][0]);
infowindow.open(complexMap, marker);
}
})(marker, i));
}
$("#complexes-modal-map-canvas").on("shown.bs.modal", function () {
var currentCenter = complexMap.getCenter();
google.maps.event.trigger(complexMap, "resize");
complexMap.setCenter(currentCenter);
complexMap.fitBounds(bounds);
});
There are 2 things I had to do to make this work. The first thing was an obvious mistake - I was selecting the incorrect element on the "shown.bs.modal" method. I needed to select my Bootstrap modal, not the Google Map. The second thing was to call the "fitBounds" method before calling the "resize" event and setting the center.
$("#complexes-modal").on("shown.bs.modal", function () {
complexMap.fitBounds(bounds);
var currentCenter = complexMap.getCenter();
google.maps.event.trigger(complexMap, "resize");
complexMap.setCenter(currentCenter);
});
This question already has answers here:
Google Maps JS API v3 - Simple Multiple Marker Example
(15 answers)
Closed 9 years ago.
Using a loop to show markers on Google Maps, I am finding that previous windows wont close even though I have a listener
Here is my code (set to limit number to 50 deliberately) that displays a marker if a user has location info set
function loadGmodule() {
var map = new google.maps.Map(
document.getElementById('gmashup'), {
center: new google.maps.LatLng(20, 0),
zoom: 1,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
for (var i=0;i<50;i++) {
u = users[i];
if (u.lat) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(u.lat, u.lang),
map: map
});
infoContent[i] = '<table ><tr><td><img src=\"'+u.avatar+'\" width=\"60\" height=\"75\"></td>';
infoContent[i] = infoContent[i] + '<td><b>'+u.firstname+' '+u.middlename+' '+u.lastname+'</b><br />'+u.designation + '<br />'+u.company+'<br />'+u.city+'</td>';
infoContent[i] = infoContent[i] + '</tr></table>';
var infoWindow = new google.maps.InfoWindow();
infoWindow.setContent(infoContent[i]);
addInfoWindowOnEvent(marker, infoWindow, map, 'click');
}
}
}
and the function / listener
function addInfoWindowOnEvent(marker, infoWindow, map, event) {
google.maps.event.addListener(marker, event, function () {
infoWindow.close();
infoWindow.open(map, marker);
});
}
Can anyone advise the best location to put the infoWindow.close() so that previous windows will shut when another pin is clicked.
Thanks in advance for any assistance
Even though the edited indicated a duplicate, it was not to be found in the supplied link.. HOWEVER (even though I think this is a hack, but it will do) there was an answer here which worked
Google Maps API v3 (one infowindow open at a time)
I changed my function to
function addInfoWindowOnEvent(marker, infoWindow, map, event) {
google.maps.event.addListener(marker, event, function () {
if($('.gm-style-iw').length) {
$('.gm-style-iw').parent().remove();
}
infoWindow.open(map,marker);
});
}
and now only one window stays open
For each marker you are creating new infowindow. If you want to close previous infowindow and have only one opened then it is enough to create only one infowindow. It should be global:
var infoContent = [];
var infoWindow;
function loadGmodule() {
var map = new google.maps.Map(
...
infoWindow = new google.maps.InfoWindow();
//for (var i = 0; i < 50; i++) {
for (var i = 0; i < users.length; i++) {
...
and then provide specific content to event listener:
...
infoContent[i] = infoContent[i] + '</tr></table>';
//infoWindow = new google.maps.InfoWindow();
//infoWindow.setContent(infoContent[i]);
addInfoWindowOnEvent(marker, infoContent[i], map, 'click');
}
}
}
function addInfoWindowOnEvent(marker, infoContent, map, event) {
google.maps.event.addListener(marker, event, function () {
infoWindow.close();
infoWindow.setContent(infoContent)
infoWindow.open(map, marker);
});
}
I'm wondering if it's possible to open one of the infoWindow objects that are attached to each marker in the code below on page load and not just by clicking on them? As it is now, the user has to click on one of the markers to open an info window.
I tested to create a "stand alone" info window object and that opened fine onload, but it didn't close when I clicked on some of the other markers, because the onClick function was attached to the markers that only could close the info windows attached to that object. Correct med if I'm wrong?
Would this be possible and can I "call" an object by the number or what options do I have? Tips are preciated!
Or if there is possible, that I have tried to open an separate info window onload and be able to close that if I open one of the other info windows!?
var map = null;
var infowindow = new google.maps.InfoWindow();
var iconBase = 'images/mapNumbers/number';
//var zoomLevel = 11;
//var mapPositionLat = 55.678939;
//var mapPositionLng = 12.568359;
function initialize() {
var markerPos = new google.maps.LatLng(55.674196574861895, 12.583808898925781);
var myOptions = {
zoom: 11,
//center: new google.maps.LatLng(55.678939, 12.568359),
center: markerPos,
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(markerPos);
map.setZoom(zoomLevel);
//var center = map.getCenter();
});
// Add markers to the map
var point;
point = new google.maps.LatLng(55.667093,12.581255); createMarker(point, "<div class='infoWindow'>1</div>");
point = new google.maps.LatLng(55.660794,12.58972); createMarker(point, "<div class='infoWindow'>2</div>");
point = new google.maps.LatLng(55.660491,12.587087); createMarker(point, "<div class='infoWindow'>3</div>");
}
// 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());
map.setCenter(55.678939, 12.568359);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
In order to display InfoWindow when the map loads, make the call to
infowindow.open(map, marker);
outside of the marker listener.
Below is demonstrated createMarker function, where parameter displayInfoWindow defines whether to display InfoWindow when the map loads:
// Create marker
function createMarker(map,markerPos, markerTitle,infoWindowContent,displayInfoWindow) {
var marker = new google.maps.Marker({
position: markerPos,
map: map,
title: markerTitle,
});
var infowindow = new google.maps.InfoWindow({
content: infoWindowContent
});
if(displayInfoWindow) {
infowindow.open(map, marker);
}
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
}
Example: http://jsbin.com/lusuquwu/1/
It is possible. One possible solution is to save markers to an array and then trigger click event on of one of them using google.maps.event.trigger(). For example:
...
var zoomLevel = 11; // uncommented due to error message
var markers = [];
function initialize() {
...
point = new google.maps.LatLng(55.660491,12.587087); createMarker(point, "<div class='infoWindow'>3</div>");
google.maps.event.trigger(markers[1], 'click');
}
function createMarker(latlng, html, name, number) {
var marker = new google.maps.Marker({
position: latlng,
map: map,
title: name,
//icon: iconBase + number + '.png'
icon: iconBase
});
// added to collect markers
markers.push(marker);
google.maps.event.addListener(marker, 'click', function () {
console.log('click event listener');
infowindow.setContent(html);
infowindow.open(map, marker);
//map.setCenter(marker.getPosition());
// corrected due to error
map.setCenter(new google.maps.LatLng(55.678939, 12.568359));
});
}
I combined info from this and another site to come up with the below solution as most solutions are for multi-marker maps.
Just a few lines is all you actually need.
// Start with your map
var map = new google.maps.Map(...);
// Now define the info window using HTML. You can insert images etc.
var info = new google.maps.InfoWindow({content: 'YOUR HTML HERE'});
// Now define the marker position on the map
var marker = new google.maps.Marker({map: map, position:{lat: 'YOUR LATITUDE',lng: 'YOUR LONGITUDE'}});
Now we have the variables, just hide the marker, show the info window and set the map zoom and center.
// Set the map zoom
map.setZoom('YOUR ZOOM LEVEL [1 - 20]');
// Set the map center
map.setCenter({lat: 'YOUR LATITUDE',lng: 'YOUR LONGITUDE'});
// Hide the marker that we created
marker.setVisible(false);
// Open the info window with the HTML on the marker position
info.open(map, marker);
For the content, you can create layers and insert images and text as you need. Just make sure you include the full URL to images in your html.
I also recommend adding this to your CSS to hide the close button, which effectively makes this a permanent, info window.
.gm-style-iw + div {display: none;}
I'm trying to load a google map with dynamic markers and dynamic infoWindows to go with them. Basically I've got the markers working. The infoWindows are clickable and closable, however they do not have the correct content. It seems that the content for every infoWindow is the last record that is found in the query loop. You will see whats happening here Here's the code:
<script type="text/javascript">
//Load the Google Map with Options//
function initialize() {
var myLatlng = new google.maps.LatLng(42.48019996901214, -90.670166015625);
var myOptions = {
zoom: 6,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
//Begin query loop to set the markers and infoWindow content//
<cfoutput query="GetCoord">
var LatLng = new google.maps.LatLng(#Client_Lat#, #Client_Lng#);
var marker = new google.maps.Marker({
position: LatLng,
map: map,
title: "#Client_Company#"
});
var contentString = '<p><b>#Client_Company#</b><br>'+
'#Client_Address#<br>'+
'#Client_City#, #Client_State# #Client_Zip#<br>'+
'View Details';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,this);
});
</cfoutput>
//End query loop
}
</script>
Any ideas on why this is happening?
Add content as a property to marker object and use this.content in the event handler:
var marker = new google.maps.Marker(options);
marker.content = '<div>Content goes here....</div>';
var infoWindow = new google.maps.InfoWindow();
google.maps.event.addListener(marker, 'click', function () {
infoWindow.setContent(this.content);
infoWindow.open(this.getMap(), this);
});
In your code you statically set the infowindow content on load with
var infowindow = new google.maps.InfoWindow({
content: contentString
});
Then when your markers are clicked you are just opening that infowindow
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
});
this will display the same content for every marker, you do not want this.
what you want to do is create only one infowindow with no content (before your marker loop). then when a marker is clicked attach the content to the info window... then open the infowindow. This will save lines of code and cause the infowindow to close automatically.
before creating your markers (with the loop) add this
infowindow = new google.maps.InfoWindow();
in your marker code add the infowindow.setContent call
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map,marker);
});