Google Maps API v3 - why no context with events? - javascript

Using Google Maps API v3 for the first time and I've got a map with a bunch of markers. I wanted to make it so when you click one, a specific InfoWindow will display (specific to the marker you clicked). I was really surprised that the click event doesn't tell you the actual marker that was clicked!
I know there is a solution using a separate method to create a closure but that seems like a hack to me. Is there a better way to do it? Or, is there a way to ask the map "what markers exist at this position" and pass in the position from the event argument?
I expected events to work like this:
google.maps.event.addListener(marker, 'click', function(event, obj)
{
//Now I can work with "obj" - the thing that was clicked.
});

You should just refer to 'this' in the event listener.
google.maps.event.addListener(marker, 'click', function(e) {
// this == marker;
// e == MouseEvent
});

let mousemoveDraw = this.mousemoveDraw.bind(this);
let mousedown_event_DrawPolygonByFinger = this.mousedown_event_DrawPolygonByFinger.bind(this);
let mouseup_event_DrawPolygonByFinger = this.mouseup_event_DrawPolygonByFinger.bind(this);
this.mapInst.addEvents([
{ type: 'mousedown', event : mousedown_event_DrawPolygonByFinger },
{ type: 'mousemove', event: mousemoveDraw },
{ type: 'mouseup', event : mouseup_event_DrawPolygonByFinger }
]);
mapInst - is wrapper on google and yandex map. It is may use this way in callbacak
//event drawing event
mousemoveDraw(event : any){
console.log('mousemoveDraw')
console.log(this)
console.log(this.stateDrawing)
try{
if (this.stateDrawing != 1){
console.log(this.stateDrawing)
let lat = event.latLng.lat();
let lng = event.latLng.lng();
console.log(lat,lng)
this.polyLine.pushCoord({ lat, lng });
}
}catch(e){
console.log('error Polyline.mousemoveDraw : ',e.message);
}
}

How is that a hack when it's provided by the API? What you are describing is a hack. When you click on the marker, it will pass an event which contains the lat & lng.
google.maps.event.addListener(marker, 'click', function(e) {
console.log(e); // { x: 0, y: 0 }
});

I think it would be a mistake to try and hunt down the marker object based on the position of the click event. Using closures to associate the event with a particular marker seems like a valid solution to me. I would create a function that looks something like this:
function createMarker (point, map)
{
var marker = new google.maps.Marker({
position: point,
map: map,
title: "blah"});
marker.stuffOnTheMarker = "Some interesting stuff";
var content = buildSomeContentForThisMarker ();
google.maps.event.addListener(marker, 'click', function() {
infowindow.close ();
infowindow.setContent(content);
infowindow.open(map,marker);
// access the marker than caused this event
alert (marker.stuffOnTheMarker);
});
}

Related

node.js how to delay importing modules

I am new to google-map. I want to create a map where, when user click on any location. it will allow user to place marker on map.
I try to use map.addEventListener("click"), which works fine.
mycode:
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 12
});
map.addListener('click', function clickHandler() {
//do something
});
}
However when user click on any landmark/clickableIcon https://imgur.com/a/M3vVu,.
Google-map will show infobox and ignoring the clickHandler, https://imgur.com/a/R3uWL. it seems that each of the landmark/clickableIcon has event.stopPropagation();
Is there any way to enable both methods. That is when user click on clickableIcon, it will both show infoBox and place the marker on the map.
thanks,
You can do this way :
google.maps.event.addListener(map, 'click', function(event) {
placeMarker(event.latLng);
});
function placeMarker(location) {
var marker = new google.maps.Marker({
position: location,
map: map
});
}

How to add only one marker in leaflet map

I am adding marker on map on user click.
Problem is that I want only one marker but now whenever I click on map new marker is added.
I am trying to remove it but nothing happens:
var marker;
map.on('click', function (e) {
map.removeLayer(marker)
marker = new L.Marker(e.latlng, { draggable: true });
marker.bindPopup("<strong>" + e.latlng + "</strong>").addTo(map);
marker.on('dragend', markerDrag);
});
Instead of using .on to capture and handle the event, you could use .once. That way the event will be only captured once and the handler will unbind itself after that.
map.on('click', function () {
console.log('I fire every click');
});
map.once('click', function () {
console.log('I fire only once');
});
If you're ever need to unbind a handler yourself you can use .off. Check the reference for event methods: http://leafletjs.com/reference.html#events
As to why your code above isn't working, on first click you're trying remove the marker: map.removeLayer(marker), but the variable marker doesn't contain a L.Marker instance so the map is unable to remove it. You should check if it's defined first and only then remove it:
var marker;
map.on('click', function (e) {
if (marker) { // check
map.removeLayer(marker); // remove
}
marker = new L.Marker(e.latlng); // set
});
Here's a working example on Plunker: http://plnkr.co/edit/iEcivecU7HGajQqDWzVH?p=preview
Use .off() to unbind the on click event.
It should be something like:
var marker;
map.on('click', mapClicked);
function mapClicked(e) {
map.off('click', mapClicked);
map.removeLayer(marker)
marker = new L.Marker(e.latlng, { draggable: true });
marker.bindPopup("<strong>" + e.latlng + "</strong>").addTo(map);
marker.on('dragend', markerDrag);
}
I didn't test it but it should at least put you in the right direction.

Trigger Google map click event with zoom javascript

Is there any way to add an click event with zoom? I am able to perform both individually, but when I use zoom together with a click event it is not working properly.
google.maps.event.trigger(gmarkers[count], "click");
map.setZoom(parseInt(k));
Please refer this jsfiddle: http://jsfiddle.net/Uw9Qy/
An example found here: http://www.geocodezip.com/v3_MW_example_map3_clustered.html
In your fiddle, you have defined the myClick function (which gets triggered as you click one of the text links), but that function doesn't contain any zoom code.
Try this:
Change the onclick on your <b> tags, add a zoomlevel to it
<b onclick="myclick(0, 11)">Berlin</b>-<b onclick="myclick(1, 8)">Paris</b>-<b onclick="myclick(2, 9)">Rome</b>
Then, add a paramter to your myclick function so you can zoom in:
this.myclick = function (i, zoomlevel) {
google.maps.event.trigger(gmarkers[i], 'click');
map.setZoom(zoomlevel);
};
function createMarker() {
var marker = new google.maps.Marker({
position: z,
map: map,
title: title,
html: contentstring
});
google.maps.event.addListener(marker, 'click', function () {
map.setCenter(marker.getPosition());
map.setZoom(10);
infowindow.setContent(this.html);
infowindow.open(map, marker);
});
//google.maps.event.addListener(marker,'click',function(){
//window.location.href = marker.url;
//});
gmarkers[ids] = marker;
};
Specify your desired zoom level in setZoom() :)

Google Maps API v3 resize event

Using Maps API v3. As per Google documentation, if the map container is resized programmatically, the map resize event must be triggered manually.
Resize event: Developers should trigger this event on the map when the div changes size.
Therefore I am using:
google.maps.event.trigger(map, 'resize');
Which listener should I be using to update my markers based on the new bounds of the resized map container?
google.maps.event.addListener(map, 'resize', function() {
console.log(map.getBounds());
});
The above still shows the bounds before resizing.
Whenever the map is resized, the bounds will chage. Therefore, you can use the bounds_changed event:
google.maps.event.addListener(map, 'bounds_changed', function() {
var bounds = map.getBounds();
});
It has the following description:
This event is fired when the viewport bounds have changed.
If you only want the event to be called after the map is resized, you can use a boolean variable to track whether the map has just been resized, like so:
var mapResized = false;
Then, whenever you trigger the resize function, you can set the mapResized variable to true. You can do so using a function:
function resizeMap(map) {
google.maps.event.trigger(map, 'resize');
mapResized = true;
}
Then, in the bounds_changed event, you can only react to call if mapResized is true, and afterwards set mapResized to false:
google.maps.event.addListener(map, 'bounds_changed', function() {
if (mapResized) {
// react here
}
mapResized = false;
}
If you want to know when the bounds change, you need to listen for the "bounds_changed" event
google.maps.event.addListener(map, 'bounds_changed', function() {
console.log(map.getBounds());
});
If you only want the first bounds changed event after you trigger the resize event, you can use:
google.maps.event.addListenerOnce(map, 'bounds_changed', function() {
console.log(map.getBounds());
});
right before you trigger the resize event.
On Angular.js and IONIC I solved by insering this code after the **
declaration of var map = new google..... :
google.maps.event.addListenerOnce(map, 'bounds_changed', function () {
google.maps.event.trigger(map, 'resize');
var bounds = map.getBounds();
});

Google Maps API google.maps.event is undefined

I'm attempting to use the Google Maps API to get a location provided by the user. To do this I'm setting a marker that moves based on 'click' events. The code is as such:
function initialize_google_map(div_id) {
var map = new GMap2(document.getElementById(div_id));
map.setCenter(new GLatLng(45, -105), 2);
map.setUIToDefault();
return map;
}
$(document).ready(function() {
// configure the google maps api
var map = initialize_google_map("map_canvas");
var marker = google.maps.Marker({map: map, title:"Location"});
google.maps.event.addListener(map, "click", function(evt) {
alert("got click event");
marker.setPosition(evt.latLng);
});
$(document).unload(function() {
// unload the google map
GUnload();
});
});
The "got click event" alert is never firing, and my Javascript console (Google Chrome) says this:
Uncaught TypeError: Cannot call method 'addListener' of undefined
The API is included like this:
<script src="http://maps.google.com/maps?file=api&v=3&sensor=true" type="text/javascript"></script>
The problem here is that you are mixing Google Maps version two objects with Version 3. In your initialize_google_map function you are creating and returning a GMap2 object (a version 2 object). You are then passing this object into a google.maps.Marker object constructor (a version 3 object).
You just need to modify your initialize_google_map function to instantiate a google.maps.Map object.
The event is generated before function and it does not recognize, you change this code:
$(document).ready(function() {
google.maps.event.addListener(map, "click", function(evt) {
alert("got click event");
marker.setPosition(evt.latLng);
});
});
for this code:
$(window).load(function(){
google.maps.event.addListener(map, "click", function(evt) {
alert("got click event");
marker.setPosition(evt.latLng);
});
});

Categories