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.
Related
I want to use Google API to show route between A and B point and show all company's locations as marker. Showing route works well. But markers not displaying and showing no error.
Here is my code:
google.maps.event.addDomListener(window, "load", initMap);
function initMap() {
//create map
map = new google.maps.Map(document.getElementById("googleMap"), mapOptions);
ContextMenu = document.getElementById("my-context-menu");
google.maps.event.addListener(map, "rightclick", function (ev) {
currentLatLng = ev.latLng;
console.log(ev.latLng);
ShowContextMenuGoolge(ContextMenu, ev);
/** this stop NOT stopping DOM 'context-menu' event from firing */
ev.stop();
});
google.maps.event.addListener(map, "click", function () {
HideContextMenuGoolge(ContextMenu);
});
//create a DirectionsService object to use the route method and get a result for our request
directionsService = new google.maps.DirectionsService();
//create a DirectionsRenderer object which we will use to display the route
directionsDisplay = new google.maps.DirectionsRenderer();
//bind the DirectionsRenderer to the map
directionsDisplay.setMap(map);
$.ajax({
type: "GET",
url: getAllMarkers,
success: function (res) {
createMarker(res);
},
err: function (err) {},
});
}
function createMarker(companies) {
// console.log(map);
companies.map((el) => {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(el.lat, el.lng),
map: map,
});
comMarkers.push(marker);
});
console.log(comMarkers);
}
This is result SS. Calculating route is works fine.
Thank for helping me.
I'm using javascript Google Maps component in Angular 5 frontend framework
export class MapComponent implements OnInit {
ngOnInit() {
this.initializeGMap()
}
initializeGMap() {
var myLatlng = new google.maps.LatLng(12,77);
var mapOptions = {
zoom: DEFAULT_MAP_ZOOM,
center: myLatlng,
scrollwheel: true,
styles: MAP_STYLE
};
this.map = new google.maps.Map(document.getElementById("map"), mapOptions);
this.initOnMapClickListener();
}
initOnMapClickListener() {
google.maps.event.addListener(this.map, 'click', function(event) {
var selectedLocation = new google.maps.LatLng(event.latLng.lat(), event.latLng.lng());
this.addMarker(selectedLocation)
});
}
addMarker(latlng) {
var marker = new google.maps.Marker({
position: latlng,
map: this.map,
icon: './assets/map_marker.png'
});
}
}
Above is my typescript file, it has three functions
initializeGMap() //to initialize google maps
initOnMapClickListener() //to initialize on map click listener
addMarker(latlng) // to add the marker when onmapclick event happens
Uncaught TypeError: Cannot read property 'addMarker' of null
this is what the console error I'm getting if I run Angular application
Please help to understand how to call a typescript function inside a Javascript callback
Try calling function using arrow function => like this to bind to the laxical scope of this -
initOnMapClickListener() {
google.maps.event.addListener(this.map, 'click', (event) => {
var selectedLocation = new google.maps.LatLng(event.latLng.lat(), event.latLng.lng());
this.addMarker(selectedLocation)
});
}
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);
Hello I'm trying to bind Google Maps with Knockout script.
Nearly everything works but I can't force infowindows to show up on event.
Without Knockout my code works but with it doesn't.
Below my js code:
var infowindow;
function point(name, lat, long) {
this.name = name;
this.lat = ko.observable(lat);
this.long = ko.observable(long);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, long),
title: name,
map: map,
draggable: true
});
//if you need the poition while dragging
google.maps.event.addListener(marker, 'drag', function () {
var pos = marker.getPosition();
this.lat(pos.lat());
this.long(pos.lng());
}.bind(this));
//if you just need to update it when the user is done dragging
google.maps.event.addListener(marker, 'dragend', function () {
var pos = marker.getPosition();
this.lat(pos.lat());
this.long(pos.lng());
}.bind(this));
google.maps.event.addListener(marker, 'mouseover', function () {
infowindow = new google.maps.InfoWindow({ content: "empty" });
console.log("mouseover");
infowindow.setContent(this.title);
infowindow.open(map, this);
}.bind(this));
}
var map = new google.maps.Map(document.getElementById('googleMap'), {
zoom: 5,
center: new google.maps.LatLng(55, 11),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var viewModel = {
points: ko.observableArray([
new point('Test1', 55, 11),
new point('Test2', 56, 12),
new point('Test3', 57, 13)])
};
function addPoint() {
viewModel.points.push(new point('a', 58, 14));
}
ko.applyBindings(viewModel);
Now my question:
Is it simple way to make it works. If yes can anyone suggest me where should I look for it?
Could be your use of this.
Add var self = this; as the first line within point function & use self to refer to properties within point.
In the mouseover event, does this refer to the marker, the map, or viewmodel? If the drag event are setting values correctly, then this is the point viewmodel, in which case within the mouseover event you called this.title. There is no title...
function point(name, lat, long) {
var self = this;
self.name = name;
self.lat = ko.observable(lat);
self.long = ko.observable(long);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, long),
title: name,
map: map,
draggable: true
});
//if you need the poition while dragging
google.maps.event.addListener(marker, 'drag', function () {
var pos = marker.getPosition();
self.lat(pos.lat());
self.long(pos.lng());
}.bind(this));
//if you just need to update it when the user is done dragging
google.maps.event.addListener(marker, 'dragend', function () {
var pos = marker.getPosition();
self.lat(pos.lat());
self.long(pos.lng());
}.bind(this));
google.maps.event.addListener(marker, 'mouseover', function () {
infowindow = new google.maps.InfoWindow({ content: "empty" });
console.log("mouseover");
infowindow.setContent(marker.title);
infowindow.open(map, this);
}.bind(this));
}
I have never used knockout myself but integrating it with maps does not look simple, here are some reading materials: http://www.codeproject.com/Articles/351298/KnockoutJS-and-Google-Maps-binding
http://www.codeproject.com/Articles/387626/BikeInCity-2-KnockoutJS-JQuery-Google-Maps
Google maps and knockoutjs
The maps code you have provided looks correct so I assume the issue lies with the knockout integration.