I'm using addEventListener to add new Marker to Google Maps using angular version 6.
I get everything needed but the actual Marker icon, it does not show on the map, why?
Here is a link to a working example on developers.google.com
https://developers.google.com/maps/documentation/javascript/info-windows-to-db
private isMapInitialized = false;
private map: any;
// Here everything statrs
ngOnInit() {
this.openMapPanel();
}
// Here I get the map and everything works great!
openMapPanel() {
setTimeout(() => {
if (!this.isMapInitialized) {
this.initMap();
this.isMapInitialized = true;
}
}, 300);
}
initMap() {
var california = {lat: 37.4419, lng: -122.1419};
this.map = new google.maps.Map(document.getElementById('map'), {
center: california,
zoom: 13
});
google.maps.event.addListener(this.map, 'click', function(event) {
this.placeNewMarker(event.latLng);
});
}
placeNewMarker(location) {
var marker = new google.maps.Marker({
position: location,
map: this.map
});
});
}
do I miss something?
It was so simple.. all I needed to do is change that line of code.
google.maps.event.addListener(this.map, 'click', function(event) {
this.placeMarker(event.latLan);
}
to
google.maps.event.addListener(this.map, 'click', (event) => {
this.placeMarker(event.latLan);
});
and of course add the function
placeNewMarker(location) {
var marker = new google.maps.Marker({
position: location,
map: this.map
});
});
I hope it will help someone someday :-)
Im trying to code a functionality so when I click on a certain location button that markers info window pops up. Ive got the code to console log the certain title and location of the marker, but when i try to call the infowindow in the viewmodel it comes up undefined. I know that the Infowindow is in the init function for google map, i cant seem to figure out how to open it from the viewmodel
and here is my code for the view model:
function viewModel() {
this.marker = locationArray().location;
this.openWindow = function(location){
if(this.marker){
console.log(this.marker);
};
}
}
and my click event:
google.maps.event.addListener(marker,'click', (function(marker){
return function() {
viewModel()
infoWindow.setContent("<div>" + marker.title + "</div>");
infoWindow.open( map, marker);
}
})(marker));
here is my google map api, hopefully this will help :
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 41.764117, lng: -72.676470},
zoom: 13,
styles: style
});
// Iterates through the locationArray and gives the marker a proper
// location.
for(var i = 0; i < locationArray().length; i++){
var locations = locationArray()[i].location;
var title = locationArray()[i].title;
var marker = new google.maps.Marker({
position: locations,
map: map,
title: title,
animation: google.maps.Animation.DROP
});
locationArray()[i].marker = marker;
var message = "hello world!";
var infoWindow = new google.maps.InfoWindow({
content: title,
position: locations
});
google.maps.event.addListener(marker,'click', (function(marker){
return function() {
viewModel();
infoWindow.setContent("<div>" + marker.title + "</div>");
infoWindow.open( map, marker);
}
})(marker));
};
};
ko.applyBindings(new viewModel());
You definition of marker in the ViewModel is ambiguous. You should in general define the observables inside the ViewModel.
function ViewModel(data) {
var self = this;
self.locations = ko.observableArray(data.locations || []);
self.showMarker(function(loc) { // bind this to click (in html)
loc.marker.showInfo(); // I'm not sure if loc.marker.click() would work
});
}
var locations = []; // your list of locations
ko.applyBindings( new ViewModel({locations: locations}) );
And you can bind the click event of your marker in a simpler way, that'll also help to easily call the
marker.showInfo = function() {
infoWindow.setContent("<div>" + this.title + "</div>");
infoWindow.open( map, this);
};
google.maps.event.addListener(marker,'click', marker.showInfo);
today i saw an answer about toggle on/off in the same button, and i decided to try to use.
What i want is to click in the marker and than a infowindow appear in my map, but it doesn't work.
JSFiddle simple marker with infowindow
JSFiddle toogle on/off but no infowindow
When i try to join(toogle with infowindow) like this:
google.maps.event.addDomListener(buttonCarrosUI, 'click', function() {
if(marker && marker.setMap){
if (marker.getMap() != null)
marker.setMap(null);
else marker.setMap(map_canvas);
}else{
var myLatLng;
var title = marker.title;
$.each( data.markers, function(i, marker) {
myLatLng = new google.maps.LatLng(marker.latitude, marker.longitude);
});
var infowindow = new google.maps.InfoWindow({
content: title,
});
marker = new google.maps.Marker({
position: myLatLng,
map: map_canvas,
icon: image,
title: title
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map_canvas,marker);
});
}
});
I Got this issue
TypeError: marker is undefined
var title = marker.title;
I'll be very gratefull if someone can help me, thanks.
You are creating the marker outside of the $.each. Unless you want more than one infowindow open at a time, it is better to make a global infowindow and reuse it. Also, you are overwriting the "marker" variable inside the $.each. Note that this wont work for more than one marker. You need to keep references to the markers in an array if you have more than one (the original example from which this code came toggled a single polyline). The code below works for me:
google.maps.event.addDomListener(buttonCarrosUI, 'click', function () {
var data = JSON;
var myLatLng;
if (marker && marker.setMap) {
if (marker.getMap() != null) marker.setMap(null);
else marker.setMap(map_canvas);
} else {
$.each(data.markers, function (i, markerInfo) {
myLatLng = new google.maps.LatLng(markerInfo.latitude, markerInfo.longitude);
marker = new google.maps.Marker({
position: myLatLng,
map: map_canvas,
title: markerInfo.title
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.setContent(marker.getTitle());
infowindow.open(map_canvas, marker);
});
});
}
});
working fiddle
I'm trying to create a Google Maps listener for click event on a marker. The issue is that the event is not firing. My code below shows how I initialize the map and add markers to the map. I believe that the event listener has to be added in the initialization.
//initializing my variables
var marker = []; //final markers that wil go on the map
//this function loads the map on to the page.
function initialize() {
var mapOptions = {
center: {
lat: 0,
lng: 0
},
zoom: 2
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
//listener for clicks on markers
google.maps.event.addListener(marker, 'click', markerClick);
//listener that listens for the map to load before calling the drop function
google.maps.event.addListenerOnce(map, 'tilesloaded', function() {
//this part runs when the mapobject is created and rendered
google.maps.event.addListenerOnce(map, 'idle', function() {
//this part runs when the mapobject shown for the first time
drop();
});
});
}
//drop function
function drop() {
for (var i = 0; i < pictureLocations.length; i++) {
setTimeout(function() {
addMarker();
}, i * 200);
}
}
//add marker function
function addMarker() {
marker.push(new google.maps.Marker({
position: pictureLocations[iterator],
map: map,
draggable: false,
animation: google.maps.Animation.DROP,
id: iterator
}));
iterator++;
}
When I click on markers nothing happens. I have an alert in the click function to cause a javascript alert.
The problem is
you are trying to add the listener to the marker array which is a collection of markers.
you should add the listener to each individual marker and then push the marker to the array.
Try this :
//initializing my variables
var marker = []; //final markers that wil go on the map
//this function loads the map on to the page.
function initialize() {
var mapOptions = {
center: {
lat: 0,
lng: 0
},
zoom: 2
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
//listener that listens for the map to load before calling the drop function
google.maps.event.addListenerOnce(map, 'tilesloaded', function() {
//this part runs when the mapobject is created and rendered
google.maps.event.addListenerOnce(map, 'idle', function() {
//this part runs when the mapobject shown for the first time
drop();
});
});
}
//drop function
function drop() {
for (var i = 0; i < pictureLocations.length; i++) {
setTimeout(function() {
addMarker();
}, i * 200);
}
}
// define markerClick wich was not defined in your code
function markerClick(){
alert('click in the marker'):
}
//add marker function
function addMarker() {
var _marker = new google.maps.Marker({
position: pictureLocations[iterator],
map: map,
draggable: false,
animation: google.maps.Animation.DROP,
id: iterator
});
//listener for clicks on markers
google.maps.event.addListener(_marker, 'click', markerClick);
marker.push(_marker);
iterator++;
}
Besides that, you could consider to read more about the google.maps.event applying to the google.maps.Map object you will find that the idle event is not what you're thinking it is.
On my site, I'm using Google Maps API v3 to place house markers on the map.
The InfoWindows stay open unless you explicitly click the close icon. Meaning, you can have 2+ InfoWindows open at a time if you hover over the map marker.
Question: How do I make it so that only the current active InfoWindow is open and all other InfoWindows are closed? Meaning, no more than 1 InfoWindow will be open at a time?
There is a close() function for InfoWindows. Just keep track of the last opened window, and call the close function on it when a new window is created.
alternative solution for this with using many infowindows:
save prev opened infowindow in a variable and then close it when new window opened
var prev_infowindow =false;
...
base.attachInfo = function(marker, i){
var infowindow = new google.maps.InfoWindow({
content: 'yourmarkerinfocontent'
});
google.maps.event.addListener(marker, 'click', function(){
if( prev_infowindow ) {
prev_infowindow.close();
}
prev_infowindow = infowindow;
infowindow.open(base.map, marker);
});
}
//assuming you have a map called 'map'
var infowindow = new google.maps.InfoWindow();
var latlng1 = new google.maps.LatLng(0,0);
var marker1 = new google.maps.Marker({position:latlng1, map:map});
google.maps.event.addListener(marker1, 'click',
function(){
infowindow.close();//hide the infowindow
infowindow.setContent('Marker #1');//update the content for this marker
infowindow.open(map, marker1);//"move" the info window to the clicked marker and open it
}
);
var latlng2 = new google.maps.LatLng(10,10);
var marker2 = new google.maps.Marker({position:latlng2, map:map});
google.maps.event.addListener(marker2, 'click',
function(){
infowindow.close();//hide the infowindow
infowindow.setContent('Marker #2');//update the content for this marker
infowindow.open(map, marker2);//"move" the info window to the clicked marker and open it
}
);
This will "move" the info window around to each clicked marker, in effect closing itself, then reopening (and panning to fit the viewport) in its new location. It changes its contents before opening to give the desired effect. Works for n markers.
My solution.
var map;
var infowindow = new google.maps.InfoWindow();
...
function createMarker(...) {
var marker = new google.maps.Marker({
...,
descrip: infowindowHtmlContent
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setOptions({
content: this.descrip,
maxWidth:300
});
infowindow.open(map, marker);
});
Declare a variable for active window
var activeInfoWindow;
and bind this code in marker listener
marker.addListener('click', function () {
if (activeInfoWindow) { activeInfoWindow.close();}
infowindow.open(map, marker);
activeInfoWindow = infowindow;
});
From this link http://www.svennerberg.com/2009/09/google-maps-api-3-infowindows/:
Teo: The easiest way to do this is to
just have one instance of the
InfoWindow object that you reuse over
and over again. That way when you
click a new marker the infoWindow is
“moved” from where it’s currently at,
to point at the new marker.
Use its setContent method to load it
with the correct content.
There is a easier way besides using the close() function. if you create a variable with the InfoWindow property it closes automatically when you open another.
var info_window;
var map;
var chicago = new google.maps.LatLng(33.84659, -84.35686);
function initialize() {
var mapOptions = {
center: chicago,
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
info_window = new google.maps.InfoWindow({
content: 'loading'
)};
createLocationOnMap('Location Name 1', new google.maps.LatLng(33.84659, -84.35686), '<p><strong>Location Name 1</strong><br/>Address 1</p>');
createLocationOnMap('Location Name 2', new google.maps.LatLng(33.84625, -84.36212), '<p><strong>Location Name 1</strong><br/>Address 2</p>');
}
function createLocationOnMap(titulo, posicao, conteudo) {
var m = new google.maps.Marker({
map: map,
animation: google.maps.Animation.DROP,
title: titulo,
position: posicao,
html: conteudo
});
google.maps.event.addListener(m, 'click', function () {
info_window.setContent(this.html);
info_window.open(map, this);
});
}
var map;
var infowindow;
...
function createMarker(...) {
var marker = new google.maps.Marker({...});
google.maps.event.addListener(marker, 'click', function() {
...
if (infowindow) {
infowindow.close();
};
infowindow = new google.maps.InfoWindow({
content: contentString,
maxWidth: 300
});
infowindow.open(map, marker);
}
...
function initialize() {
...
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
...
google.maps.event.addListener(map, 'click', function(event) {
if (infowindow) {
infowindow.close();
};
...
}
}
How about -
google.maps.event.addListener(yourMarker, 'mouseover', function () {
yourInfoWindow.open(yourMap, yourMarker);
});
google.maps.event.addListener(yourMarker, 'mouseout', function () {
yourInfoWindow.open(yourMap, yourMarker);
});
Then you can just hover over it and it will close itself.
I stored a variable at the top to keep track of which info window is currently open, see below.
var currentInfoWin = null;
google.maps.event.addListener(markers[counter], 'click', function() {
if (currentInfoWin !== null) {
currentInfoWin.close(map, this);
}
this.infoWin.open(map, this);
currentInfoWin = this.infoWin;
});
Here is what I used if you are using many markers in a for loop (Django here). You can set an index on each marker and set that index every time you open a window. Closing the previously saved index:
markers = Array();
infoWindows = Array();
var prev_infowindow =false;
{% for obj in objects %}
var contentString = 'your content'
var infowindow = new google.maps.InfoWindow({
content: contentString,
});
var marker = new google.maps.Marker({
position: {lat: {{ obj.lat }}, lng: {{ obj.lon }}},
map: map,
title: '{{ obj.name }}',
infoWindowIndex : {{ forloop.counter0 }}
});
google.maps.event.addListener(marker, 'click',
function(event)
{
if( prev_infowindow ) {
infoWindows[prev_infowindow].close();
}
prev_infowindow = this.infoWindowIndex;
infoWindows[this.infoWindowIndex].open(map, this);
}
);
infoWindows.push(infowindow);
markers.push(marker);
{% endfor %}
var contentString = "Location: " + results[1].formatted_address;
google.maps.event.addListener(marker,'click', (function(){
infowindow.close();
infowindow = new google.maps.InfoWindow({
content: contentString
});
infowindow.open(map, marker);
}));