Leaflet popupclose event fires whilst dragging marker - popup

In my app I add a temporary dragable marker to a map and open its popup. I found that when the marker is dragged the popup closes. To get around this I added the code as per Force Leaflet popup to stay open when a draggable marker is moved
var marker = new L.Marker([setLat, setLng], {icon:questionIcon, draggable:true});
marker.bindPopup("popup content").addTo(map).openPopup();
marker.on('dragend', function(e) {
marker.openPopup();
});
However, I also want to make sure that if the user closes the popup manually (using the standard 'x' top-right) that the temporary marker is removed from the map. So I added ...
marker.on('popupclose', function(e) {
map.removeLayer(marker);
});
... but, this also fires when dragging the marker. So as soon as the user tries to reposition the marker by dragging it, it completely disappears.
Is there a way to distinguish between the two events so I can handle them differently? Or back to the original question, disable the popupclose from happening when the marker is dragged?

I met the same issue ,
and I solved it by doing this inorder to distinguish between the two events :
marker._popup._closeButton.onclick = function( ){
console.log("click closed ");
map.removeLayer(marker);
}
http://jsfiddle.net/Zoubir/v71Lhn5s/

I met the similar issue. Here's my solution
var IsDragging = false;
marker.on('dragstart', function (event) {
IsDragging = true;
});
marker.on('dragend', function (event) {
marker.openPopup();
IsDragging = false;
});
map.on('popupclose', function(e) {
setTimeout(function(){
if(LS.Send.IsDragging == false){
map.removeLayer(LS.Send.Marker);
}
},300);
});

Related

Leaflet-geoman remove button not working after bind a new layer click function

I need to bind a custom click function on the drawn shapes. I'm using the following code for that:
map.on('pm:create', function(e) {
e.layer.on('click', function(e) {
document.getElementById('info-pane').style.display = 'block';
});
});
When I bind this new click function, I'm not able to remove the shape anymore. When I am in the remove mode, the click is triggering the show info-pane instead of remove the shape.
How can I bind a custom click function to the shapes without "deactivate" any leaflet-geoman functionality such as the Remove ?
Well,
Including this L.DomEvent.stopPropagation(e); seems to be working now.
map.on('pm:create', function(e) {
e.layer.on('click', function(e) {
document.getElementById('info-pane').style.display = 'block';
});
L.DomEvent.stopPropagation(e);
});

leafletDirectiveMarker disable focus when user click outside the map

I have a click function on the marker which will enable the marker popup. But when the user clicks outside the map I want to disable this focus. How to do this?
$scope.$on('leafletDirectiveMarker.click', function (event, args) {
$scope.markers['m' + args.model.value.id].focus = true;
createTemplateForPopup(args.model.value);
});
You can simply listen to a window event and disable all focus on click:
$window.addEventListener('click', function(e) {
$scope.markers.forEach(function(marker) {
marker.focus = false;
});
});
You might prevent default to not trigger the window click when someone selects a marker:
$scope.$on('leafletDirectiveMarker.click', function (event, args) {
event.preventDefault();
$scope.markers['m' + args.model.value.id].focus = true;
createTemplateForPopup(args.model.value);
});
The only problem is that this will always trigger. So it is good practice to remove the EventListner when the map is destroyed.

Double on click event with mapbox gl

I am redrawing layers on style.load event and removing the layers
map.on('style.load', function() {
loadByBounds(tempBounds)
});
function loadByBounds(b) {
if (map.getLayer("cluster-count")) {
map.removeLayer("cluster-count");
}
...
map.on('click', 'unclustered-point', function(e) {
var popup = new mapboxgl.Popup()
.setLngLat(e.features[0].geometry.coordinates)
.setHTML(text)
.addTo(map);
})}
But how to remove map.on('click') events? As when I click the point the Popup() displays 2 times. And when I change layer one more time the onclick event fires 3 times and so on. So I think I have to remove the click event but how? Thanks
You might wanna use map.once(). This will add a listener that will be called only once to a specified event type. However after 1 click event got fired this event listener won't listen to any further click events.
https://www.mapbox.com/mapbox-gl-js/api/#evented#once
With map.off() it's basically the opposite of map.on() and you can use it to unregister any applied event listeners. However you would need to add event listeners without an anonymous function in order to use map.off().
https://www.mapbox.com/mapbox-gl-js/api/#map#off
// you would need to use a named function
function clickHandler(e) {
// handle click
}
map.on('click', clickHandler);
// then you can use
map.off('click', clickHandler);
// With an anonymous function you won't be able to use map.off
map.on('click', (e) => {
// handle click
});
To prevent your app from registering multiple listeners you maybe need to set a flag that gets set after your first event listener got applied.
let notListening = true;
function loadByBounds(b) {
// ....
if (notListening) {
notListening = false;
map.on('click', (e) => {
// do something
});
}
}

can't unregister click event in openlayers

I am having issues with OpenLayers and unregistering the click events that are added to a layer. Basically, what I need to do is this:
When a user clicks on a marker, they get a bubble that has an "edit" link in it. The user clicks that and it creates a new layer on the map and then registers a click event to the map waiting for the user to click on the map. When they click somewhere on the map, it then moves the marker to where they clicked. This all works perfectly.
However, the issue is when the user clicks to edit the marker and then clicks on a button OUTSIDE OF THE MAP to cancel the action and NOT move the marker, the unregister of the click event doesn't work. They can still click on the map and it moves the marker.
Here is a sample of the code:
function move_marker(marker) {
lmLayer = new OpenLayers.Layer.Markers("Landmark Creation",{displayInLayerSwitcher: false});
map.addLayer(lmLayer);
map.events.register("click", lmLayer, function(evt){
var pixel = new OpenLayers.Pixel(evt.clientX,evt.clientY);
position = map.getLonLatFromPixel(pixel);
marker.lonlat = pixel;
marker.moveTo(pixel);
marker.draw();
lmLayer.redraw();
OpenLayers.Event.stop(evt);
});
}
function cancel_move() { // this function is triggered by a button outside of the map element
lmLayer = map.getLayersByName('Landmark Creation');
lmLayer[0].events.unregister("click");
map.events.unregister("click");
map.removeLayer(lmLayer[0]);
}
As you can see in the cancel function, I am getting the layer by the layer name, which according to the console.log it is finding at index 0. I added the unregister to the lmLayer in hopes that would help, but so far, no luck. Then on the map element I add the unregister call and then finally I remove that new layer because we don't want it interfering.
I'd appreciate some feedback on this. I'm losing my mind.
Thanks!
I think you need to tell OpenLayers which click event you want it to unregister:
var method = function() {
// Do stuff...
}
map.events.register('click', map, method);
map.events.unregister('click', map, method);
According to the OpenLayers.Events source it checks whether the scope and the method is present in the listener stack:
unregister: function (type, obj, func) {
if (obj == null) {
obj = this.object;
}
var listeners = this.listeners[type];
if (listeners != null) {
for (var i=0, len=listeners.length; i<len; i++) {
HERE --> if (listeners[i].obj == obj && listeners[i].func == func) { <-- HERE
listeners.splice(i, 1);
break;
}
}
}
},
I hope that works for you :)

Bing map AJAX Control V7 - How does one detect clicks but not drags?

I have a Bing map on my web page, and I want to detect when the user clicks in the window. However, I do not wish to detect when the user drags the map (this also generates a "click" event) . What is the best way to get only "pure" click events?
My solution ended up beeing a manual check if the click position was close to the position where the mouse was pushed down.
Microsoft.Maps.Events.addHandler(map, "click", clickHandler);
Microsoft.Maps.Events.addHandler(map, "mousedown", function(me) { lastMouseDownPoint = new Microsoft.Maps.Point(me.getX(), me.getY());});
function clickHandler(mouseEventArgs){
var point = new Microsoft.Maps.Point(mouseEventArgs.getX(), mouseEventArgs.getY());
//Drag detection
// Edited since the comma is incorrect, should be a plus as per pythagorean theorem
var dist = Math.sqrt(Math.pow(point.x-lastMouseDownPoint.x,2) + Math.pow(point.y-lastMouseDownPoint.y,2));
if(dist > 5) {
// We call this a drag
return;
}
// We have a "pure" click and can process it
}
Very simple:
Microsoft.Maps.Events.addHandler(map, 'click', onClick);
function onClick(e) {
if (e.mouseMoved === false && e.isPrimary === true) {
// Left click not being a drag
...
}
}
mouseMoved is true with a drag and drop and false otherwise.
The MouseEventArgs documentation http://msdn.microsoft.com/en-us/library/gg406731.aspx does not reference mouseMoved :/