We using multiple marker with infowindow. Everything is working fine.
The issue is when we click marker, the infowindow opens but it doesn't close when click other markers. it stay opened. so can give solutions for this issue.
The code is in http://goo.gl/s0WZx
var berlin = new google.maps.LatLng(52.520816, 13.410186);
var neighborhoods = [
new google.maps.LatLng(52.511467, 13.447179),
new google.maps.LatLng(52.549061, 13.422975),
new google.maps.LatLng(52.497622, 13.396110),
new google.maps.LatLng(52.517683, 13.394393)
];
var markers = [];
var iterator = 0;
var map;
function initialize() {
var mapOptions = {
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: berlin
};
map = new google.maps.Map(document.getElementById("map_canvas"),
mapOptions);
}
function drop() {
for (var i = 0; i < neighborhoods.length; i++) {
setTimeout(function() {
addMarker();
}, i * 200);
}
}
function addMarker() {
var marker = new google.maps.Marker({
position: neighborhoods[iterator],
map: map,
draggable: false
});
markers.push(marker);
var contentString = $("#pop"+iterator).html();
var infowindow = new google.maps.InfoWindow({
content: contentString,
maxWidth: 300,
maxHeight: 500
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
});
iterator++;
}
You are creating as much infowindows, as there are markers. In your case,I think one infowindow is enough. So for working with only one infowindow, you could implement this on global scope:
//Using lazy initialization.
//InfoWindow will be created only after the first call
var getInfoWindow = (function(){
var _instance = null;
return function(){
if(_instance == null){
_instance = new google.maps.InfoWindow({
maxWidth: 300,
maxHeight: 500
});
}
return _instance;
};
})();
Also you need to store the contentString for every marker which must be shown on click event. So the final modification of addMarker method will be something like this:
function addMarker() {
var marker = new google.maps.Marker({
position: neighborhoods[iterator],
map: map,
draggable: false
});
markers.push(marker);
//Storing content html
marker.contentString = $("#pop"+iterator).html();
google.maps.event.addListener(marker, 'click', function() {
//Setting content of InfoWindow
getInfoWindow().setContent( marker.contentString );
//Opening
getInfoWindow().open(map,marker);
});
iterator++;
}
Put the var infowindow outside of the addMarker function. Like this:
var infowindow = new google.maps.InfoWindow();
Then inside your addMarker function use
infowindow.setContent(contentString);
This way the infowindow is only created once. Clicking on the different markers just moves the window and sets the content.
Related
I need to in InfoWindow show match.offer.text.
Each marker has a different match.offer.text.
This is my code:
var markerImageURL, lat, lng;
if (myoffer) {
markerImageURL = 'assets/img/markers/marker_my.png';
lat = match.lat;
lng = match.lng;
} else {
markerImageURL = 'assets/img/markers/marker_' + match.strength + '.png';
lat = match.offer.lat;
lng = match.offer.lng;
}
var marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
map: window.googleMap,
icon: {
size: new google.maps.Size(54,56),
url: markerImageURL
},
draggable: false,
visible: true
});
var infowindow = new google.maps.InfoWindow({
content: match.offer.text,
maxWidth: 300
});
window.googleMapMarkers.push(marker);
if(!myoffer) {
window.MVC.Events.GoogleMap.prototype.showInfoWindow(marker, infowindow, match);
}
Event triggered after clicking on the marker:
marker.addListener('click', function() {
infowindow.open(window.googleMap, marker);
}
Please, help me.
The content is applied to the marker on Open therefore your code will apply the content in last item in your loop to all markers, in your openWindow function add the content to a single infoWindow object i.e.
Also the Maps API has its own event wrapper for the click event
function initMarkers(){
//create markers
var marker = new google.maps.Marker();
google.maps.event.addListener(marker, 'click', openInfoWindow(marker, i));
}
var infowindow = new google.maps.InfoWindow();
function openInfoWindow(marker,index){
return function(e) {
//Close other info window if one is open
if (infowindow) {
infowindow.close();
}
var content = marker.offer.text;
infowindow.setContent(content);
setTimeout(function() {
infowindow.open(map, marker);
}, 200);
}
}
I have a problem with my GeoJson layers which I want to cluster (with MarkerClusterer) and then be able to show and hide them via checkboxes or similar. Therefore I tried something like the code below:
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(52.515696, 13.392624),
zoom: 11,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map"),
mapOptions);
var bounds = new google.maps.LatLngBounds();
var barLayer = new google.maps.Data();
var cafeLayer = new google.maps.Data();
barLayer.loadGeoJson('json/eat_drink/bar.geojson');
cafeLayer.loadGeoJson('json/eat_drink/cafe.geojson');
var markerClusterer = new MarkerClusterer(map);
var infowindow = new google.maps.InfoWindow();
markerClusterer.setMap(map);
function displayMarkers(layer) {
var layer = layer;
google.maps.event.addListener(layer, 'addfeature', function (e) {
if (e.feature.getGeometry().getType() === 'Point') {
var marker = new google.maps.Marker({
position: e.feature.getGeometry().get(),
title: e.feature.getProperty('name'),
map: map
});
// open the infoWindow when the marker is clicked
google.maps.event.addListener(marker, 'click', function (marker, e) {
return function () {
var myHTML = e.feature.getProperty('name');
infowindow.setContent("<div style='width:150px; text-align: center;'>"+myHTML+"</div>");
infowindow.setPosition(e.feature.getGeometry().get());
infowindow.setOptions({pixelOffset: new google.maps.Size(0,-30)});
infowindow.open(map, marker);
};
}(marker, e));
markerClusterer.addMarker(marker);
bounds.extend(e.feature.getGeometry().get());
map.fitBounds(bounds);
map.setCenter(e.feature.getGeometry().get());
}
});
layer.setMap(null);
google.maps.event.addListener(map, "click", function () {
infowindow.close();
});
};
document.getElementById('bar').onclick = function(){ // enable and disable markers
if(document.getElementById('bar').checked == true){
displayMarkers(barLayer);
}else{
return null;
}
};
}
Unfortunatley this doesn't work and I don't no exactly why.
If I remove the displayMarkers() function around the code and replace "layer" with the desired GeoJson layer, e.g. "barLayer", it works just fine.
Since I will end up with tons of GeoJason layers I would prefer a "compact" solution like this insted of copying the code multiple times. Have you guys any ideas how to do that properly?
I'm afraid I haven't done much more than refactor your code. Could you give this a try, and if it doesn't work specify exactly what doesn't work?
function displayMarkers(layer, map, markerClusterer) {
google.maps.event.addListener(layer, 'addfeature', function(e) {
if (e.feature.getGeometry().getType() === 'Point') {
var marker = new google.maps.Marker({
position: e.feature.getGeometry().get(),
title: e.feature.getProperty('name'),
map: map
});
// open the infoBox when the marker is clicked
google.maps.event.addListener(marker, 'click', function(e) {
var myHTML = e.feature.getProperty('name');
var infowindow = new google.maps.InfoWindow();
infowindow.setContent("<div style='width:150px; text-align: center;'>" + myHTML + "</div>");
infowindow.setPosition(e.feature.getGeometry().get());
infowindow.setOptions({
pixelOffset: new google.maps.Size(0, -30)
});
infowindow.open(map, marker);
google.maps.event.addListener(map, "click", function() {
infowindow.close();
});
});
markerClusterer.addMarker(marker);
var bounds = new google.maps.LatLngBounds();
bounds.extend(e.feature.getGeometry().get());
map.fitBounds(bounds);
map.setCenter(e.feature.getGeometry().get());
}
});
layer.setMap(null);
}
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(52.515696, 13.392624),
zoom: 11,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map"), mapOptions);
var barLayer = new google.maps.Data();
var cafeLayer = new google.maps.Data();
barLayer.loadGeoJson('json/eat_drink/bar.geojson');
cafeLayer.loadGeoJson('json/eat_drink/cafe.geojson');
var markerClusterer = new MarkerClusterer(map);
markerClusterer.setMap(map);
document.getElementById('bar').onclick = function() { // enable and disable streetViewControl
if (document.getElementById('bar').checked == true) {
displayMarkers(barlayer, map, markerClusterer);
} else {
return null;
}
};
}
I have the following code that works as intended except the google.maps.event.addListener(marker, 'click', function(). I am including all the code for reference. You will see the commented out code that I have tried. I want the map to zoom in when the marker is clicked. Thank you for your help.
$(document).ready(function() {
$("#map").css({
height: 700,
width: 800
});
var myLatLng = new google.maps.LatLng(46.053791, -118.3131256);
MYMAP.init('#map', myLatLng, 11);
$("#showmarkers").ready(function(e){
MYMAP.placeMarkers('markers.xml');
});
});
var MYMAP = {
map: null,
bounds: null
}
MYMAP.init = function(selector, latLng, zoom) {
var myOptions = {
zoom:zoom,
center: latLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
this.map = new google.maps.Map($(selector)[0], myOptions);
this.bounds = new google.maps.LatLngBounds();
}
MYMAP.placeMarkers = function(filename) {
$.get(filename, function(xml){
$(xml).find("marker").each(function(){
var name = $(this).find('name').text();
var address = $(this).find('address').text();
// create a new LatLng point for the marker
var lat = $(this).find('lat').text();
var lng = $(this).find('lng').text();
var point = new google.maps.LatLng(parseFloat(lat),parseFloat(lng));
// extend the bounds to include the new point
MYMAP.bounds.extend(point);
var marker = new google.maps.Marker({
position: point,
map: MYMAP.map
});
var infoWindow = new google.maps.InfoWindow();
var html='<strong>'+name+'</strong.><br />'+address;
google.maps.event.addListener(marker, 'mouseover', function() {
infoWindow.setContent(html);
infoWindow.open(MYMAP.map, marker);
});
<!-- *************** here is the code I need help with **************** -->
google.maps.event.addListener(marker, 'click', function() {
<!-- attempt 1 -->
<!--map.setZoom(10); -->
<!--map.setCenter(marker.getPosition());-->
<!--attempt 2 -->
<!--mapZoom = map.getZoom();-->
<!--startLocation = event.point; -->:
<!--attempt 3 (with and without MYMAP-->
<!--MYMAP.map.setZoom(10); -->
<!--MYMAP.map.panTo(marker.position); -->
});
google.maps.event.addListener(marker,'mouseout', function() {
infoWindow.close();
});
MYMAP.map.fitBounds(MYMAP.bounds);
});
});
}
I think the best way is to get the current zoom, increment it, and set the zoom to the new value, like this :
google.maps.event.addListener(marker, 'click', function() {
MYMAP.map.setZoom(MYMAP.map.getZoom()+1);
});
http://jsfiddle.net/OxyDesign/w26fL6f7/
Is it what you wanted ?
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Google Maps - Multiple markers - 1 InfoWindow problem
I'm making a map where I plot some towns and places.
As you will see, when you click on a marker, you are redirected to the corresponding page. But now I would like to put the link and some other information in an info bubble popover. So, I've edit my code to this:
function setMarkers(map, locations) {
for (var i = 0; i < locations.length; i++) {
var beach = locations[i];
var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
var infobulle = new google.maps.InfoWindow({content: beach[4], position: myLatLng});
var marker = new google.maps.Marker({position: myLatLng, map: map, title: beach[0], zIndex: beach[3], clickable: true, icon: beach[5],});
marker[i] = marker;
google.maps.event.addListener(marker[i], 'click', function() {
infobulle.open(map, marker);
});
}
}
But as you can see here the info bubble stays "blocked" on the last location. I really don't know how to sort this.
I have the same result with this :
function setMarkers(map, locations) {
for (var i = 0; i < locations.length; i++) {
var beach = locations[i];
var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
var infobulle = new google.maps.InfoWindow({content: beach[4]});
var marker = new google.maps.Marker({position: myLatLng, map: map, title: beach[0], zIndex: beach[3], clickable: true, icon: beach[5]});
google.maps.event.addListener(marker, 'click', function() {
infobulle.open(map, marker);
});
}
Last version :
function setMarkers(map, locations) {
for (var i = 0; i < locations.length; i++) {
processBeach(locations[i]);
}
}
function processBeach(beach) {
var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
var infobulle = new google.maps.InfoWindow({content: beach[4]});
var marker = new google.maps.Marker({position: myLatLng, map: map, title: beach[0], zIndex: beach[3], clickable: true, icon: beach[5]});
google.maps.event.addListener(marker, 'click', function() {
infobulle.open(map, marker);
});
}
You are using the marker variable for two different purposes it seems. One is as a single marker, and one as an array of markers. But you don't need an array of markers, if you use closures. Try this:
function setMarkers(map, locations) {
for (var i = 0; i < locations.length; i++) {
(function(beach) {
var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
var infobulle = new google.maps.InfoWindow({content: beach[4], position: myLatLng});
var marker = new google.maps.Marker({position: myLatLng, map: map, title: beach[0], zIndex: beach[3], clickable: true, icon: beach[5]}))
google.maps.event.addListener(marker, 'click', function() {
infobulle.open(map, marker);
});
}(locations[i]));
}
}
By the way you also had a spurious comma at the end of the options array for google.maps.Marker which will cause problems in some browsers.
EDIT
If you don't want to use closures, this is equivalent:
function processBeach(beach) {
var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
var infobulle = new google.maps.InfoWindow({content: beach[4], position: myLatLng});
var marker = new google.maps.Marker({position: myLatLng, map: map, title: beach[0], zIndex: beach[3], clickable: true, icon: beach[5]}))
google.maps.event.addListener(marker, 'click', function() {
infobulle.open(map, marker);
});
}
function setMarkers(map, locations) {
for (var i = 0; i < locations.length; i++) {
processBeach(locations[i]);
}
}
Have a look at my jSFiddle here. The code you are missing is
On Click you need to fetch the current infoWindow from the map and then update it with new information
If you want to keep windows open and close when people want to close then you have to set a toggle kind of variable so each window will be created on click and then when someone click on close it will go away. But i think you only need to complete first part.
The code you should look in my fiddle is from line 120 to 150 which does check for infowindow if it exists and then do open the same window on new marker so it moves from old marker and go to new. if you keep creating new windows the old ones will not close magically.
var map = $(this).gmap3("get"),
infowindow = $(this).gmap3({get:{name:"infowindow"}}); // Get current info window
if (infowindow){ // if infoWindow is there then use it else create new
infowindow.open(map, marker);
infowindow.setContent(context.data.ht);
jQuery("#customPopup").html(context.data.ht);
jQuery("#customPopup").show(500);
} else {
$(this).gmap3({
infowindow:{
anchor:marker,
options:{content: context.data.ht}
}
});
jQuery("#customPopup").html(context.data.ht);
jQuery("#customPopup").show(500);
}
I have three arrays : myLats, (latitudes) myLngs (longitudes) and myLocs (address strings)
e.g. myLats[0] = 53.3534751, ,myLngs[0] = -2.5682085, myLocs[0] = Longwood Rd Appleton Warrington. So the elements of each array all correspond to each other numerically.
When constructing the map in my initialize() function, I loop through these to place multiple markers at the correct coordinates, and i'm also trying to have each marker having an infowindow appear when clicked, yet when i click a marker an infowindow simply does not appear. Any help with this would be greatly appreciated.
Code:
function initialize() {
var myOptions = {
center: new google.maps.LatLng(54.00366, -2.547855),
zoom: 6,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map_canvas'), myOptions);
var marker, infowindow, i;
for (i = 0; i <= myLats.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(myLats[i], myLngs[i]),
map: map,
clickable: true,
icon: '". url::base() ."resources/icons/accident.png',
});
infowindow = new google.maps.InfoWindow({
content: myLocs[i],
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
}
}
That's a common problem when dealing with more than one marker. You aren't in fact creating a new window for each marker but must redefining the single window for each marker.
You'll find the problem and solution on page 88 onwards of Google Map API V3
If you are new to Google Maps API, I would recommend reading that book, it gave me a great start and I avoided a lot of the "common" mistakes.
Hope this helps.
Jim
I made a few changes, like adding the markers inside a function, adding 'var', and changing i <= myLats.length to i < myLats.length. It was a combination of these changes that made it work.
var myLats = [ 54.20366, 54.42366, 54.64366];
var myLngs = [ -2.54788, -2.66788, -2.78788];
var myLocs = [ "Loc a" , "Loc b" , "Loc c"];
function initialize()
{
var myOptions =
{
center: new google.maps.LatLng(54.00366,-2.547855),
zoom: 6,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map_canvas'),myOptions);
var marker, infowindow, i;
for (i=0; i < myLats.length; i++)
{
addMarker(i);
}
function addMarker(i) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(myLats[i],myLngs[i]),
map: map,
clickable: true,
//icon: '". url::base() ."resources/icons/accident.png',
});
var infowindow = new google.maps.InfoWindow({
content: myLocs[i]
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
});
}
}
However, I'm guessing you want a solution that keeps only one infowindow open, I had this figured out first:
var myLats = [ 54.20366, 54.42366, 54.64366];
var myLngs = [ -2.54788, -2.66788, -2.78788];
var myLocs = [ "Loc a" , "Loc b" , "Loc c"];
var map, marker, infowindow, i;
function initialize()
{
var myOptions =
{
center: new google.maps.LatLng(54.00366,-2.547855),
zoom: 6,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map_canvas'),myOptions);
infowindow = new google.maps.InfoWindow({ });
for (i = 0; i < myLats.length; i++) {
addMarker(i);
}
}
function addMarker(i) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(myLats[i],myLngs[i]),
map: map,
clickable: true
//icon: '". url::base() ."resources/icons/accident.png'
});
google.maps.event.addListener(marker, 'click', function(event) {
infowindow.setContent(myLocs[i]);
infowindow.open(map,marker);
});
}