Trigger click on leaflet marker - javascript

I have a bunch of leaflet markers on the map. Each marker is held in array markers. The markers are created dynamically (during an ajax call).
var markers = [];
.
.
var marker = L.marker([mar.lat, mar.lng], {
// ...build the marker...
}
marker._leaflet_id = mar.id; // give the marker an id corresponding to the id of its corresponding div
var myHoverIcon = L.icon({
iconUrl: mar.imgUrl,
iconSize: [40, 40],
popupAnchor: [0, 0]
});
marker.on('click', function(e) {
alert('Marker clicked!');
marker.setIcon(myHoverIcon);
});
.
.
markers.push(marker);
Each marker has an id corresponding to a particular div (stored in data-mess_id on the div). The plan is to change the marker's icon when its corresponding div in the feed is clicked on.
$('#feed').on('mouseover', '.message', function() {
var cssid = $(this).attr('data-mess_id').toString();
var baz = $.grep(markers, function(m) {
return (m._leaflet_id == cssid);
});
baz[0].trigger('click'); // doesn't work
alert(baz[0].getLatLng()); // does work
// this also does not work:
var myHoverIcon = L.icon({
iconUrl: baz[0].imgUrl,
iconSize: [40, 40],
popupAnchor: [0, 0]
});
baz[0].setIcon(myHoverIcon);
});
It's all working fine except for the final bit. I just can't trigger a click event on the marker. I definitely have the correct marker because baz[0].getLatLng() is working. But baz[0].trigger('click') doesn't work.
I tried creating a new icon dynamically (myHoverIcon) but it doesn't work.
How do I trigger a click event on the marker?
Is there another way to change the marker icon?

To emulate a mouse click, you can use the fire method (inherited from Evented.fire) on the marker :
marker.fire('click');
And a demo
var map = L.map('map').setView([0, 0], 12);
var icon = L.icon({
iconUrl: 'http://leafletjs.com/examples/custom-icons/leaf-green.png'
});
var marker = L.marker([0, 0], {icon: icon})
.addTo(map);
var myHoverIcon = L.icon({
iconUrl: 'http://leafletjs.com/examples/custom-icons/leaf-red.png'
});
marker.on('click', function(e) {
marker.setIcon(myHoverIcon);
});
document.querySelector('button').addEventListener('click', function() {
marker.fire('click');
});
html, body {
height: 100%;
margin: 0;
}
#map {
width: 100%;
height: 100%;
}
button {position: absolute; left:10 px; top: 70px;}
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.2.0/dist/leaflet.css" integrity="sha512-M2wvCLH6DSRazYeZRIm1JnYyh22purTM+FDB5CsyxtQJYeKq83arPe5wgbNmcFXGqiSH2XR8dT/fJISVA1r/zQ==" crossorigin=""/>
<script src="https://unpkg.com/leaflet#1.2.0/dist/leaflet.js" integrity="sha512-lInM/apFSqyy1o6s89K4iQUKg6ppXEgsVxT35HbzUupEVRh2Eu9Wdl4tHj7dZO0s1uvplcYGmt3498TtHq+log==" crossorigin=""></script>
<div id='map'></div>
<button>Click me</button>

Related

Change icon of marker clicked when you have multiple markers

I am trying to change the marker icon when the marker is clicked the problem is the code below only changes the last marker I added to the map not the marker I am clicking on, so if I only had one marker it would work fine. I tried looking it up but all the examples I could find only work with 1 marker loaded in the map. I tried the listener two different ways the second one is commented out below the the first way and both just change the icon of the the last marker loaded.
<html>
<head>
<title>Simple Map</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 95%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 95%;
margin: 0;
padding: 0;
}
<script src="https://maps.googleapis.com/maps/api/js?key=KEY&callback=initMap"
async defer></script>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<script src="https://unpkg.com/#google/markerclustererplus#4.0.1/dist/markerclustererplus.min.js"></script>
<script>
let markers = [];
let map;
function loadMarkers(ssStr)
{
$.getJSON(ssStr, function(data) {
for (var i = 0; i < data.feed.entry.length; i++)
{
var latLng = new google.maps.LatLng(data.feed.entry[i]['gsx$lat']['$t'],
data.feed.entry[i]['gsx$long']['$t']);
var marker = new google.maps.Marker({
position: latLng,
map: map,
label:data.feed.entry[i]['gsx$structure']['$t'],
icon: { url: "http://maps.google.com/mapfiles/ms/icons/red.png" }
});
markers.push(marker);
google.maps.event.addListener(marker, 'click', function() {
//Change the marker icon
marker.setIcon('http://maps.google.com/mapfiles/ms/icons/green.png');
});
/* marker.addListener("click", (event) => {
marker.setIcon('http://maps.google.com/mapfiles/ms/icons/green.png');
}); */
}
var latLng = new google.maps.LatLng(data.feed.entry[0]['gsx$lat']['$t'],
data.feed.entry[0]['gsx$long']['$t']);
map.setCenter(latLng);
});
}
function initMap() {
console.log("initMap");
var mapOptions = {
zoom: 10,
center: new google.maps.LatLng(41.5, -72)
};
map = new google.maps.Map(document.getElementById('map'), mapOptions);
loadMarkers("http://spreadsheets.google.com/feeds/list/SSID/od6/public/values?alt=json");
}
</script>
</head>
<body>
<div id="map"></div>
</body>
</html>

Remove /Hide Marker from search result after search is finished -Leaflet

In my current code, I am able to search and display a marker on the search location but when I remove text from the search bar or close search bar marker is still visible on map .until I refresh the page I can visualize the search result marker on the map. how can I hide or remove the search result marker from the map once I close the search bar or remove text from the search bar?
//add Search Control so load the Geojson of point of interest
var featuresLayer = new L.GeoJSON(data);
var Icon = L.icon({
iconUrl: 'icon-red.png',
iconSize: [25, 41], // size of the icon
iconAnchor: [13, 38], // point of the icon which will correspond to marker's location
popupAnchor: [1, -34], // point from which the popup should open relative to the iconAnchor
shadowSize: [41, 41] // shadow casting of icon
});
var searchControl = new L.Control.Search({
layer: featuresLayer,
propertyName: 'name',
autoCollapse: false,
collapsed:false,
autoType: false,
position:'topright',
moveToLocation: function(latlng, title, map) {
map.setView(latlng, 17); // access the zoom
console.log(latlng);
L.marker(latlng, {icon: Icon}).addTo(map).bindPopup('<h4>'+ latlng.layer.feature.properties.name +'</h4>').openPopup();
},
});
//inizialize search control
map.addControl(searchControl);
Save your marker to a variable and remove it after the event 'search:collapsed' is fired:
var searchMarker = null;
var searchControl = new L.Control.Search({
layer: featuresLayer,
propertyName: 'name',
autoCollapse: false,
collapsed:false,
autoType: false,
position:'topright',
moveToLocation: function(latlng, title, map) {
map.setView(latlng, 17); // access the zoom
console.log(latlng);
searchMarker = L.marker(latlng, {icon: Icon}).addTo(map).bindPopup('<h4>'+ latlng.layer.feature.properties.name +'</h4>').openPopup();
},
});
searchControl.on('search:cancel',()=>{
if(searchMarker && map.hasLayer(searchMarker)){
searchMarker.removeFrom(map);
searchMarker = null;
}
});

How to use custom icons on a leaflet-omnivore layer?

I'm trying to change the default marker for one of my KML layers. I'm using leaflet-omnivore for this.
This is the code I already have. The markers are not changing to the image and the layer control is only displaying the text, even though the img bit is in the code.
Marker Code:
var redIcon = L.icon({
iconUrl: 'icon.png',
iconSize: [20, 24],
iconAnchor: [12, 55],
popupAnchor: [-3, -76]
});
var nissanLayer = omnivore.kml('icons.kml')
.on('ready', function() {
map.fitBounds(customLayer.getBounds());
//change the icons for each point on the map
// After the 'ready' event fires, the GeoJSON contents are accessible
// and you can iterate through layers to bind custom popups.
customLayer.eachLayer(function(layer) {
// See the `.bindPopup` documentation for full details. This
// dataset has a property called `name`: your dataset might not,
// so inspect it and customize to taste.
layer.icon
layer.bindPopup('<img src="icon.png" height="24"><br><h3>'+layer.feature.properties.name+'</h3>');
});
})
.addTo(map);
var marker = new L.Marker(customLayer, {icon:redIcon});
map.addLayer(marker);
You seem to have overlooked the setIcon() method of L.Marker. I'd also check that a L.Layer is in fact a L.Marker before calling any L.Marker functionality, just for code sanity. e.g.:
var redIcon = L.icon({ /* ... */ });
var omnivoreLayer = omnivore.kml('icons.kml')
.on('ready', function() {
omnivoreLayer.eachLayer(function(layer) {
if (layer instanceof L.Marker) {
layer.setIcon(redIcon);
}
});
})
.addTo(map);
However, the Leaflet-Omnivore documentation says that the better way to apply custom styling to an Omnivore layer is to create a L.GeoJSON instance with the desired filters and styling, and then pass that to the Omnivore factory method. I suggest you read the Leaflet tutorial on GeoJSON to become familiar with this.
So instead of relying on a on('ready') event handler (which would change the markers after they are created), this would save a tiny bit of time by creating the markers directly with the desired style:
var omnivoreStyleHelper = L.geoJSON(null, {
pointToLayer: function (feature, latlng) {
return L.marker(latlng, {icon: redIcon});
}
});
var omnivoreLayer = omnivore.kml('icons.kml', null, omnivoreStyleHelper);
I haven't used leaflet that much but I did a small project where I set the icons to an image.
var redIcon = L.icon({
iconUrl: 'red-x.png',
iconSize: [25, 25], // size of the icon
iconAnchor: [12, 55], // point of the icon which will correspond to
marker's location
popupAnchor: [-3, -76] // point from which the popup should open
relative to the iconAnchor
});
var marker = new L.Marker(markerLocation, {icon:redIcon});
mymap.addLayer(marker);
Not sure how helpful this is really.
Links got a guide to follow which might be more use https://leafletjs.com/examples/custom-icons/

LeafletJS how to display HTML Elements/DIV/Input Box/Button on specific position using LongLat

I'd like to ask about if it is possible or how do I add a "HTML Element" on spefic location on the map using Long Lat?
My goal is to add a Label and Text Input or a Text and Button pair sort of thing of specific position on the map.
Like for example:
Displaying a html + css control that displays a name and hobby:
Like this
Given the longitude and latitude place it on the map.
Is there a way doing this? How to do this?
Then maybe add something like a alert when clicking it.
You have many options:
Using L.popup's
Using L.tooltip's
Using an L.marker with an L.divIcon
Example:
var popup = L.popup({
closeButton: false,
autoClose: false,
closeOnClick: false
})
.setLatLng([48.85, 2.30])
.setContent(makeHtml(0));
var tooltip = L.tooltip({
permanent: true,
direction: 'left'
})
.setLatLng([48.84, 2.34])
.setContent(makeHtml(1));
var divIcon = L.divIcon({
html: makeHtml(2),
className: 'divIcon',
iconSize: [200, 50],
iconAnchor: [0, 0]
});
var marker = L.marker([48.85, 2.35], {
icon: divIcon
});
var map = L.map('map').setView([48.85, 2.35], 12);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
popup.openOn(map);
map.openTooltip(tooltip);
marker.addTo(map);
function makeHtml(id) {
return '<label for="input_' + id + '">Input:</label><input type="text" value="my value…" id="input_' + id + '" />'
}
#map {
height: 200px;
}
.divIcon {
background-color: orange;
border: 1px solid black;
}
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.2.0/dist/leaflet.css">
<script src="https://unpkg.com/leaflet#1.2.0/dist/leaflet-src.js"></script>
<div id="map"></div>
I can think about one way. I've used the L.divIcon for the same purpose. Here is a part of my code :
var yourPoint = L.divIcon({
className: 'map-marker-yourClassHere',
iconSize: null,
iconAnchor: [17, 35],
html:'<div class="text-marker">'+ txt +'</div>'
});
L.marker(latlng, {icon: yourPoint}).addTo(map);
You can simply put everything you want into this html option.

Change position of leaflet label

I'd like to add labels to my leaflet-markers, and then position them above and horizontally centered for the marker icon.
With the labelAnchor option in the Leaflet.label plugin I can manually adjust every label so that I get what I want, and for now I've added a fixed width to my labels so that I know the text will be centered. But there must be a better way to achieve this?
http://jsfiddle.net/NYGvibeke/frUf4/3/
<style type="text/css">
.labeltext { width: 120px; text-align: center; border:none; }
</style>
<script type="text/javascript">
var myIcon = L.icon({
iconUrl: 'http://icons.iconarchive.com/icons/visualpharm/icons8-metro- style/512/Maps-and-Geolocation-Marker-icon.png',
iconSize: [18, 30],
iconAnchor: [10, 30],
labelAnchor: [-80, -40]
});
var layer = new L.StamenTileLayer("toner-lite", {maxZoom: 10});
var map = new L.Map("map", {
center: new L.LatLng(30, 100),
zoom: 4,
maxZoom: 12,
minZoom: 2
});
map.addLayer(layer);
var marker1 = L.marker([25, 100], {icon: myIcon}).bindLabel('This is a label text', { noHide: true, className: 'labeltext'}).addTo(map);
</script>
Change
.labeltext { width: 120px}
to
.labeltext { width: auto}
The auto value will dynamically size the width of the label.
UPDATE
Actually, that's only part of it. Here's the rest in a jsfiddle. Basically, you need to dynamically assign the position based on the number of characters. It takes a little bit of calibration (depending on font typeface/size), but here's what I came up with for labelAnchor:
[-label[0].length*2.5-20, -40]

Categories

Resources