Click on markers mapbox - javascript

I have it so that clicking on the map creates a marker at that point. I am trying to add an event to the markers that will return the lnglat when the marker is clicked. The issue is I can't click the marker, the map just keeps creating new markers.
map.on('click', function(e){
let marker = new mapboxgl.Marker().setLngLat(e.lngLat).addTo(map);
marker.on('click', function(){
console.log('hello');
});
});

Markers are simple HTML elements, so you can add an event listener directly to them by calling addEventListener on their DOM node:
map.on('click', function(e){
var el = document.createElement('div');
el.className = 'marker';
el.style.height = '20px';
el.style.width = '20px';
el.style.backgroundColor = 'black';
el.addEventListener('click', function(e){
// Prevent the `map.on('click')` from being triggered
e.stopPropagation();
console.log('hello');
});
let marker = new mapboxgl.Marker(el).setLngLat(e.lngLat).addTo(map);
});
https://codepen.io/eddydg/pen/gZpbRj?editors=1010

Related

Move marker on click

I am creating a Leaflet-map, where I would like to move the marker by 1) drag and 2) mouse click. The coordinates of 'dragend' or mouse click are written to 'latitude' and 'longitude'. The drag is all well and good, but I am struggling with onclick.
The overall aim is to make the map more suitable for smart phone users.
Code: https://jsfiddle.net/oskjerv/pjgucx75
Docs: https://leafletjs.com/download.html
If you want the lalng when you click on the marker use this:
marker.on('dragend click', function (e) {
document.getElementById('latitude').value = marker.getLatLng().lat;
document.getElementById('longitude').value = marker.getLatLng().lng;
});
if you want the latlng of the marker when you click on the map:
map.on('click', function (e) {
document.getElementById('latitude').value = marker.getLatLng().lat;
document.getElementById('longitude').value = marker.getLatLng().lng;
});
if you want the latlng of the map where you clicked:
map.on('click', function (e) {
document.getElementById('latitude').value = e.latlng.lat;
document.getElementById('longitude').value = e.latlng.lng;
});
Your code doesn't have got a mouse click event code like dragging code.
marker.on('dragend', function (e) {
document.getElementById('latitude').value = marker.getLatLng().lat;
document.getElementById('longitude').value = marker.getLatLng().lng;
//Confirmit.page.getQuestion('R3QX_pin_lat').setValue(marker.getLatLng().lat);
//Confirmit.page.getQuestion('R3QX_pin_lng').setValue(marker.getLatLng().lng);
});
You can write mouse click code similar to drag code
map.on('click', function (e) {
document.getElementById('latitude').value = marker.getLatLng().lat;
document.getElementById('longitude').value = marker.getLatLng().lng;
});

HERE Maps (JS v3) - Add event listener to info bubble

I'm trying to add a pointerenter event to a information bubble but it's not firing. I got it to work with a marker but not with a info bubble.
I've tried to add the eventhandler to the info bubble using addEventHandler like this:
var infoBubble = new H.ui.InfoBubble({lat:48.8567, lng:2.3508}, {
content: "<div>hello</div>"
});
infoBubble.addEventListener('pointerenter', function (evt) {
alert('pointerenter');
});
I've also tried adding the mouseOver event to the info bubble content element and that does not fire either.
var infoBubble = new H.ui.InfoBubble({lat:48.8567, lng:2.3508}, {
content: "<div>hello</div>"
});
mapUI.addBubble(infoBubble);
var infoBubbleContent = infoBubble.getContentElement();
infoBubbleContent.addEventListener('mouseOver', function(evt){
alert('mouse over');
});
Here's the full code.
// Initialize the platform object:
var platform = new H.service.Platform({
'app_id': 'xxx',
'app_code': 'xxx'
});
// Obtain the default map types from the platform object
var maptypes = platform.createDefaultLayers();
// Instantiate (and display) a map object:
var map = new H.Map(
document.getElementById('mapContainer'),
maptypes.normal.map,
{
zoom: 4,
center: {lat:50, lng:5}
});
// Enable the event system on the map instance:
var mapEvents = new H.mapevents.MapEvents(map);
// Behavior implements default interactions for pan/zoom (also on mobile touch environments)
var behavior = new H.mapevents.Behavior(mapEvents);
// create default UI with layers provided by the platform
var mapUI = new H.ui.UI.createDefault(map, maptypes);
var infoBubble = new H.ui.InfoBubble({lat:48.8567, lng:2.3508}, {
content: "<div>hello</div>"
});
infoBubble.addEventListener('pointerenter', function (evt) {
alert('pointerenter');
});
mapUI.addBubble(infoBubble);
/*
var infoBubbleContent = infoBubble.getContentElement();
infoBubbleContent.addEventListener('mouseOver', function(evt){
alert('mouse over');
});
*/
var standardMarker = new H.map.Marker(new H.geo.Point(40.4, -3.6833));
standardMarker.addEventListener('pointerenter', function (evt) {
alert('pointerenter');
});
map.addObject(standardMarker);
While the InfoBubble is an event target, the only event it dispatches itself is 'statechange'. However, after adding the bubble you can get the bubble's HTML element and use plain old HTML events on it:
var bubble = new H.ui.InfoBubble({lat:48.8567, lng:2.3508}, {
content: "<div>hello</div>"
});
ui.addBubble(bubble);
bubble.getElement().addEventListener('mouseover', function(e) {
console.log('hello there');
});
Note: The HTML for the bubble is only built AFTER it is added to the UI. Before the getElement() method return null.

Delete a DrawingManager shape when drawing a new one

I created a custom toggle to init the DrawingManager, and I'm able to delete the current shape (if there is one) when I initialise it using currentShape.setMap(null).
But how to delete a shape created with the DrawingManager at the precise moment the user starts do draw a new one?
As far as I know there's no "drawingstart" event (not in their documentation), for example, that could fire at the moment when the user starts drawing a shape.
I tried using this...
google.maps.event.addListener(map, 'dragstart', function(e) {
if (drawingManager.getDrawingMode() == "circle"){
currentShape.setMap(null);
}
});
...and also using the 'click' event, but those events don't fire when drawingManager.getDrawingMode() == "circle".
function initMap(){
map = new google.maps.Map(mapCanvas, mapOptions);
$toggleDrawing.on('click', function(){
toggleDrawing();
});
}
function toggleDrawing(){
if (!isDrawing){
if (!selectedArea){
// enable drawing mode
isDrawing = true;
$toggleDrawing.addClass('active');
initDrawing();
}else{
// delete selected area
deleteSelectedArea();
}
}else{
// disable drawing mode after drawing a shape
isDrawing = false;
$toggleDrawing.removeClass('active');
drawingManager.setDrawingMode(null);
}
}
function initDrawing(){
drawingManager = new google.maps.drawing.DrawingManager({
drawingMode: google.maps.drawing.OverlayType.CIRCLE,
drawingControl: false
});
drawingManager.setMap(map);
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
selectedArea = e.overlay;
toggleDrawing(false); // will set to false
});
// 'click' or 'dragstart' event are not fired if `drawingManager.getDrawingMode() == "circle"` (or any other shape)
// google.maps.event.addListener(map, 'click', function(e) {
// if (drawingManager.getDrawingMode() == "circle"){
// selectedArea.setMap(null);
// }
// });
// google.maps.event.addListener(map, 'dragstart', function(e) {
// if (drawingManager.getDrawingMode() == "circle"){
// selectedArea.setMap(null);
// }
// });
}
function deleteSelectedArea() {
if (selectedArea) {
selectedArea.setMap(null);
selectedArea = null;
}
}
Too easy. Attach event to the map-canvas instead of map:
// If it's drawing mode, delete the selected area (if there is one)
$('#map-canvas').on('click', function() {
if (drawingManager.getDrawingMode() == "circle"){
deleteSelectedArea();
}
});
Nice tips here.

Cannot click within dynamically inserted content

I have a form that is dynamically inserted into the Google Map. However I cannot click any of the inputs. I believe I need to add a listener somewhere but I'm not sure.
Fiddle
function googlemap() {
// google map coordinates
var posY = 37.765700,
posX = -122.449134,
location = new google.maps.LatLng(posY,posX),
// offset location
posY = posY + 0.055;
offsetlocation = new google.maps.LatLng(posY,posX);
var mapOptions = {
panControl: false,
zoomControl: false,
mapTypeControl: false,
scaleControl: false,
streetViewControl: false,
overviewMapControl: false,
draggable: true,
disableDoubleClickZoom: false,
scrollwheel: false,
zoom: 12,
center: offsetlocation,
// ROADMAP; SATELLITE; HYBRID; TERRAIN;
mapTypeId: google.maps.MapTypeId.ROADMAP
};
overlay.prototype = new google.maps.OverlayView();
// create overlay marker
overlay.prototype.onAdd = function() {
blip = document.createElement('div'),
pulse = document.createElement('div');
blip.className = 'blip';
pulse.className = 'pulse';
// createa dialog and grab contents from #mapcontents
boxText = document.createElement("div");
boxText.className = "dialog";
mapContents = $('#mapcontents').html();
boxText.innerHTML = mapContents;
$('#mapcontents').remove();
blip.appendChild(boxText);
// append 'blip' marker
this.getPanes().overlayLayer.appendChild(blip).appendChild(pulse);
}
// update blip positioning when zoomed
overlay.prototype.draw = function(){
var overlayProjection = this.getProjection(),
bounds = new google.maps.LatLngBounds(location, location),
sw = overlayProjection.fromLatLngToDivPixel(bounds.getSouthWest()),
ne = overlayProjection.fromLatLngToDivPixel(bounds.getNorthEast());
blip.style.left = sw.x + 'px';
blip.style.top = ne.y + 'px';
// shift nav into view by resizing header
var w = $('.dialog').width(),
w = (w / 2) + 25,
w = '-' + w + 'px';
h = $('.dialog').height(),
h = (h) + 100,
h = '-' + h + 'px';
$('.dialog').css({
'margin-top' : h,
'margin-left' : w
});
};
var map = new google.maps.Map(document.getElementsByClassName('map')[0], mapOptions);
// explicitly call setMap on this overlay
function overlay(map) {
this.setMap(map);
}
// center map when window resizes
google.maps.event.addDomListener(window, 'resize', function() { map.setCenter(location) });
// center map when zoomed
google.maps.event.addListener(map, 'zoom_changed', function() { map.setCenter(location) });
// I have nfi what I'm doing but I think this click listener is part of the solution.
google.maps.event.addListener('.dialog', 'click', function() {
alert('ok');
});
// process contact form
google.maps.event.addListener(map, 'domready', function() {
$('button').click(function(e) {
(e).preventDefault();
alert('ok');
return false;
var name = $(".contactform input[name='name']"),
email = $(".contactform input[name='email']"),
message = $(".contactform textarea[name='message']"),
error = false;
// clear validation errors
$('#contact input, #contact textarea').removeClass('error');
if(name.val().length < 1)
name.addClass("error");
if(!/^[a-zA-Z0-9._+-]+#[a-zA-Z0-9-]+\.[a-zA-Z]{2,4}(\.[a-zA-Z]{2,3})?(\.[a-zA-Z]{2,3})?$/.test(email.val()))
email.addClass("error");
if(message.val().length < 1)
message.addClass("error");
// if error class exists
if($(".error").length) return false;
$(this).attr('disabled', true).prepend('<i class="load animate-spin"></i>');
$.ajax({
type: "post",
dataType: "json",
url: "lib/sendmail.php",
data: $("#contactform").serialize()
})
.always(function(data) {
$('h5').animate({opacity:0},function(){
$('h5').text("Email Sent!!")
.animate({opacity:1});
});
$('.contactform').animate({opacity:0},function(){
$('.contactform').html("<p class='success'>Thank You for your form submission. We will respond as soon as possible.</p>")
.animate({opacity:1});
})
});
});
return false;
});
// add overlay
overlay = new overlay(map);
}
Any idea why I can't click the inputs?
You just need to block propagation of mousedown map event to make inputs clickable:
google.maps.event.addDomListener(blip, 'mousedown', function (e) {
e.cancelBubble = true;
if(e.stopPropogation) {
e.stopPropagation();
}
});
And you can do the same for dbclick to prevent map zooming: http://jsfiddle.net/gfKWz/1/
The click-events fire fine for all these inputs, the issue here at first is that your code will never execute, because there is no domready-event for a google.maps.Map
Change this:
google.maps.event.addListener(map, 'domready', function () {
into this:
google.maps.event.addListenerOnce(map, 'tilesloaded', function () {
for observation of the events you may use $.on(), e.g.:
$(map.getDiv()).on('click','button',function (e) {/*some code*/});
Demo: http://jsfiddle.net/doktormolle/jcfDu/
You use $('button').click which is triggered before the button is present on the dom. .click() binds the handler to all the current elements on the dom.
Better use $('button').on('click', function(){}); which binds the click event handler to all the current and future instances of button on your page. This is especially handy if you dynamically add content on the page. Through ajax or otherwise.
Read more about jQuery .on() in here http://api.jquery.com/on/
Your event has to be added in the onAdd function.
Currently, the event handler is created before the element. So it doesn't catch the click on this particular element.
http://jsfiddle.net/NeekGerd/duEEt/4/
Or you could create a new function for your overlay's bindings, just for the sake of clean-code :
overlay.prototype.onAdd = function() {
[...]
this.bindings();
}
overlay.prototype.bindings = function(){
$("button").on("click",function(){
alert("Click");
return false;
}
}
For now I have no real solution to your inputs problem.
Maybe by reattaching mousedownevents to them, and force them to focus():
$("input,textarea").on("mousedown",function(){$(this).focus();});
Same thing with your checkboxes.
On another note, since you use jQuery, why not use it all the way?
Like you can do:
$('#mapcontents')
.clone()
.wrap('<div class="dialog" />')
.wrap('<div class="blip />')
.appendTo( *selector* );
In order to quickly build some html and append it to the selected element. Much more readable (thus easier to maintain) than the DOM code you got there. Since you already use jQuery anyway.

Google Maps API v3 : Click events not triggered in firefox for custom marker

have created a map that I'm trying to have function similar to 'My Maps'. I have two dropdownlists on the right side, based on the selection in those ddl's, you can add a custom marker / icon. You select a marker type, then click the '+' button in the top right corner of the map, and then click where you want the marker added. My issue is, this works fine in IE, Safari, and Chrome, but not in firefox. The click event doesn't seem to fire.
Here is the location of the map : https://ait.saultcollege.ca/Michael.Armstrong/Index.html
The button to add the marker in the top right has an onclick event pointing to my 'placeMarker()' function. Here is the code for placeMarker(), createMarker() ...
function placeMarker() {
select("placeMarker");
var infowindow = new google.maps.InfoWindow({});
var catID = document.getElementById('category');
var typeID = document.getElementById('ddlType');
var category = catID.options[catID.selectedIndex].value;
var markerType = typeID.options[typeID.selectedIndex].value;
if (!markerType) {
alert("You must select an icon type.");
}
else {
var moveListener = google.maps.event.addListener(customMap, 'mousemove', function(event) {
if (mapMarker) {
mapMarker.setPosition(event.latLng);
} else {
mapMarker = createMarker(event.latLng, "test", markerType, "test");
}
});
var clickListener = google.maps.event.addListener(customMap, 'click', function(event) {
if (mapMarker) {
select("hand_b");
google.maps.event.clearListeners(customMap, 'mousemove');
google.maps.event.removeListener(listener);
mapMarker = createMarker(event.latLng, "test2", markerType, "test");
var htmlInfo = "" +
"Category:" + category + "" +
"Item:" + markerType + "" +
"Notes:" +
"Location:" + mapMarker.getPosition().toString() + "" +
"" +
"";
//infowindow.setContent(htmlInfo);
//infowindow.open(customMap, mapMarker);
}
});
}
}
function createMarker(latlng, title, icon, html) {
var mapMarker = new google.maps.Marker({
position: latlng,
map: customMap,
title: title,
icon: 'Images/' + icon + '.png'
});
return mapMarker;
}
function select(buttonId) {
document.getElementById("hand_b").className = "unselected";
document.getElementById("placeMarker").className = "unselected";
document.getElementById(buttonId).className = "selected";
}
Any help or suggestions would be awesome. Could this perhaps be a bug in ff?
I did something very similar for an open-source disaster software package. In this case, lets assume I selected "Fire" in my dropdown menu and this triggers addFire(). The listener on the markers will delete the point on a click or allow you to drag it. The map can only have one listener at a time, but each marker can still have its own listener at the same time.
Here is the code that worked on Chrome, Firefox and IE8:
//This function sets up the map for adding a fire icon
function addFire() {
//Kill old listener
if(listening)
google.maps.event.removeListener(listenerhandle);
//Start new listener
listenerhandle = google.maps.event.addListener(disasterMap, 'click', addFirePoint);
listening = true;
}//end addFire
//This function adds new fire points to the map and controls dragging and clicking
function addFirePoint(event) {
//Create the marker
var fireMarker = new google.maps.Marker({
icon: "./mapimgs/fire.png", position: event.latLng, map: disasterMap, draggable: true });
newFireMarkers.push(fireMarker);
fireMarker.setTitle("Fire");
//Listen for clicks on the new marker
google.maps.event.addListener(fireMarker, 'click', function() {
fireMarker.setMap(null);
//remove the marker from the array
for(i=0;i<newFireMarkers.length;i++) {
if(fireMarker.getPosition() == newFireMarkers[i].getPosition()) {
newFireMarkers.splice(i,1);
break;
}
}
}
); //end click listener
}//end addFirePoint

Categories