Leaflet show popup on hover with the location of the mouse - javascript

I am using leaflet to show my geometry locations on the map. Now I have the popups working fine but when you hover over them, the location of the popup is in the middle of the line/string for example and not on the location of the mouse. Is it possible to change it to the location of the mouse so the map doesn't just suddenly move to a different location?
The code that I am using to open the popups in leaflet is as follows:
function addPopup(feature, layer) {
var popupContent = feature.properties.name;
layer.bindPopup(popupContent);
layer.on('mouseover', function (e) {
this.openPopup();
});
layer.on('mouseout', function (e) {
this.closePopup();
});
}

After #Falke Design pointed out that you could give the latlng coordinates to the openPopup function I made a cleaner version of the code:
function addPopup(feature, layer) {
var popupContent = feature.properties.name;
layer.bindPopup(popupContent);
layer.on('mouseover', function (e) {
this.openPopup(e.latlng);
});
layer.on('mouseout', function (e) {
this.closePopup();
});
}

You can convert the mousepoint to latlng and set the popup there.
layer.on('mouseover', function (e) {
var p = L.point([e.originalEvent.clientX,e.originalEvent.clientY])
var latlng = mymap.containerPointToLatLng(p);
this.openPopup(latlng)
});
layer.on('mousemove', function(e){
var p = L.point([e.originalEvent.clientX,e.originalEvent.clientY])
var latlng = mymap.containerPointToLatLng(p);
this.openPopup(latlng)
})
layer.on('mouseout', function (e) {

Related

How can I stop a map click event from firing when clicking on a layer?

I have a click event that fires when clicking on the map. However, I also have a separate event when clicking on a marker layer. Is it possible to stop the map click event from firing when I click on a marker?
The map click event:
map.on('click', function (e) {
if (isAddingLocations) {
console.log(e.lngLat);
$('#formtable').modal('show');
clickCoords = e.lngLat.toArray();
document.getElementById("latitudef").value = String(clickCoords[1])
document.getElementById("longitudef").value = String(clickCoords[0]);
}
});
The marker click event:
map.on("click", "quebec", function (e) {
map.getCanvas().style.cursor = 'pointer';
var location = e.features[0].properties.location;
var province = e.features[0].properties.province;
var link = e.features[0].properties.link;
var coordinates = e.features[0].geometry.coordinates.slice();
timeadded = e.features[0].properties.timeadded;
document.getElementById("location").innerHTML = location + ", " + province;
document.getElementById("link").innerHTML = '<a class="btn btn-info btn-lg" href="' + link + '"target="_blank" role="button">More Info</a>';
document.getElementById("latitudee").innerHTML = coordinates[1];
document.getElementById("longitudee").innerHTML = coordinates[0];
document.getElementById("locatione").innerHTML = location;
document.getElementById("provincee").innerHTML = province;
document.getElementById("linke").innerHTML = link;
if (isAddingLocations) {
$('#formedit').modal('show');
}
else {
sidedivsize_toggle(sdiv3, sdiv1, sdiv2);
}
});
I was thinking maybe there could be a "not 'quebec'" expression or something in the layer parameter. Or perhaps a if the second event fires prevent the first one. Not sure how one could do any of those things. And of course, any other solution is welcome.
Found a work around in MB github if anyone else comes across this. https://github.com/mapbox/mapbox-gl-js/issues/9875
Essentially though, we stop the click event from doing anything as it bubbles up the dom chain from the Map Layer, to the Map. Example :
map.on('click', 'points', function (e) {
console.log('clicked on layer', e);
e.clickOnLayer = true;
});
map.on('click', function (e) {
if (e.clickOnLayer) {
return;
}
console.log('map clicked', e);
});
There are probably various solutions to this issue. One solution is the clickOneLayer function of Map-GL-Utils which fires different callbacks depending on whether a layer was clicked or whether a click missed everything.

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;
});

ESRI leaflet map, reset style not working

I am working on my first leaflet map and am running into an issue when trying to reset the style onMouseOut. it correctly changes style on mouse over but on mouse out, i keep getting: Object doesn't support property or method 'resetStyle'
This is what i have and what I have tried:
var MAP_ID = 'DISTRICT_MAP';
var map = L.map(MAP_ID).setView([37.71, -99.88], 4);
function showMap() {
var layerConfig = {
....
onEachFeature: onEachFeature,
style: style
};
var districtLayer;
//Add base map layer
L.esri.basemapLayer('Gray').addTo(map);
//Add the District layer
districtLayer = L.esri.featureLayer(layerConfig);
map.addLayer(districtLayer);
}
function highlightFeature(e) {
var layer = e.target;
layer.setStyle({
weight: 5,
color: '#666',
dashArray: '',
fillOpacity: 0.7,
});
if (!L.Browser.ie && !L.Browser.opera12 && L.Browser.edge) {
layer.bringToFront();
}
}
// Can't get this to work!
function resetHighlight(e) {
//L.esri.featureLayer.resetStyle(e.target);
//e.target.resetStyle(e.target);
//e.layer.resetStyle();
}
function onEachFeature(feature, layer) {
layer.on("mouseover", function (e) {
highlightFeature(e);
});
layer.on("mouseout", function (e) {
if (e.target && e.target.feature && e.target.feature.properties) {
resetHighlight(e);
}
});
layer.on("click", function (e) {
....
}
});
}
function style(feature, layer) {
...
}
as per the API reference, that is a method on FeatureLayer itself, and expects you to pass the id of a specific feature.
// because the individual feature is GeoJSON, it has an id, along with properties and geometry
districtLayer.resetStyle(e.layer.feature.id);

leaflet mouse hover popup through array list

i want to display a popup on mouse hover,i want to show names on popup,which will be select from the array list,i placed multiple markers on map at different latlon,now i want to display a popup(which contain name) for particular latlon,this is my code,where i want to show my district name on mouse hover,now i am getting the popup text on mouse hover but i don't know how can i call my array list in popupcontent,any one can suggest what i should do?
var planes = [
["Jodhpur",26.28, 73.02],
["Bikaner",28.0229,73.3119],
["Churu",28.3254,74.4057],
["Ganga Nagar",29.9038,73.8772],
["Hanumangarh",29.1547,74.4995],
["Jaisalmer", 26.9157,70.9083],
["Jalore",25.1257,72.1416],
["Jhunjhunu",28.1289,75.3995],
["Nagaur",27.1854,74.0300],
["Pali",25.7711, 73.3234],
["Sikar",27.6094,75.1399],
["Sirohi",24.7467,72.8043],
["Barmer",25.7532,71.4181],
];
for (var i = 0; i < planes.length; i++) {
marker = new L.marker([planes[i][1],planes[i][2]],{icon: myIcon}).addTo(map).bindPopup('<div id="chart" class="chart"></div>');
marker.on('click', onMarkerClick, this);
/*var currentMarker = planes[i][0];
currentMarker.on('mouseover', currentMarker.openPopup.bind(currentMarker));
*/
marker.on('mouseover', function(e) {
//open popup;
var popup = L.popup()
.setLatLng(e.latlng)
.setContent('Popup')
.openOn(map);
});
}
Filter your array to return the name based on lat and/or lng
marker.on('mouseover', function(e) {
var name = "";
$.each(planes,function(i,v){
if (v.indexOf(e.latlng[0]) > 0) {//test if the lat is in the array
name = v[0];//get the name
}
})
var popup = L.popup()
.setLatLng(e.latlng)
.setContent('District: '+name)
.openOn(map);
})
Note: i am assuming e.latlng is a array of [lat,lng]
You have to change the marker1 name as per your marker name.
var marker1 = L.marker(23.0225, 72.5714).addTo(mymap)
.bindPopup("Demo Content of Popup");
let isClicked = false
marker1.on({
mouseover: function() {
if(!isClicked) {
this.openPopup()
}
},
mouseout: function() {
if(!isClicked) {
this.closePopup()
}
},
click: function() {
isClicked = true
this.openPopup()
}
})
mymap.on ({
click: function() {
isClicked = false
},
popupclose: function () {
isClicked = false
}
})

label for circle marker in leaflet

I am able to add label to circlemarker like this
L.circleMarker(points[i],{title: 'unselected'}).bindLabel('Destination').addTo(map);
This adds label which appears on mouse hover on circle marker.
But I want to add static label which will appear regardless of mouse is on that circle marker or not.
I am referring this demo http://leaflet.github.com/Leaflet.label/ for adding static label to circle marker but some how I am not able to do it.
It is working fine with markers but with circle Markers static label is not working.
Also is there any other method to add label on circle marker ?
L.CircleMarker extended from L.Path not L.Marker, so if you compare https://github.com/Leaflet/Leaflet.label/blob/master/src/Path.Label.js and https://github.com/Leaflet/Leaflet.label/blob/master/src/Marker.Label.js you can find that Path doesn't have any options and this logic you must implement yourself. For example:
L.CircleMarker.include({
bindLabel: function (content, options) {
if (!this._label || this._label.options !== options) {
this._label = new L.Label(options, this);
}
this._label.setContent(content);
this._labelNoHide = options && options.noHide;
if (!this._showLabelAdded) {
if (this._labelNoHide) {
this
.on('remove', this.hideLabel, this)
.on('move', this._moveLabel, this);
this._showLabel({latlng: this.getLatLng()});
} else {
this
.on('mouseover', this._showLabel, this)
.on('mousemove', this._moveLabel, this)
.on('mouseout remove', this._hideLabel, this);
if (L.Browser.touch) {
this.on('click', this._showLabel, this);
}
}
this._showLabelAdded = true;
}
return this;
},
unbindLabel: function () {
if (this._label) {
this._hideLabel();
this._label = null;
this._showLabelAdded = false;
if (this._labelNoHide) {
this
.off('remove', this._hideLabel, this)
.off('move', this._moveLabel, this);
} else {
this
.off('mouseover', this._showLabel, this)
.off('mousemove', this._moveLabel, this)
.off('mouseout remove', this._hideLabel, this);
}
}
return this;
}
});
L.circleMarker([53.902257, 27.541640] ,{title: 'unselected'}).addTo(map).bindLabel('Destination', { noHide: true });
Just wanted to add an update or correction to tbicr's great response (not sure if the API updated after his response).
You can do this like so:
// First add your GeoJSON layer
geojson = L.geoJson(myGeoJson,{
onEachFeature: onEachFeature
}).addTo(map);
// onEachFeature is called every time a polygon is added
var polys = [];
function onEachFeature(layer){
polys.push(layer); // Push the polygons into an array you can call later
}
// Now trigger them after they've been added
$('a').click(function(){
polys[0].fire('click') // clicks on the first polygon
polys[1].fire('click') // clicks on the second polygon
});

Categories