If you need to have two different maps for each marker, you need to initialize two maps. There are similar StackOverflow questions: here and here. There is also a Leaflet example here using two maps on the same page.
Here is a very simple example creating two pickers on one page using a custom MapPicker
class:
class MapPicker {
constructor(pickerId) {
this.pickerId = pickerId;
this._init();
}
_init() {
this.pickerElement = document.getElementById(this.pickerId);
this.pickerElement.classList.add('map-picker');
this.mapElement = document.createElement('div');
this.mapElement.classList.add('map');
this.inputElement = document.createElement('input');
this.inputElement.setAttribute('type', 'text');
this.pickerElement.append(this.mapElement, this.inputElement);
this.map = L.map(this.mapElement).setView([-6.175, 106.827], 8);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
// add a link to OpenStreetMap (omitted here for shorter line width)
attribution: '© OpenStreetMap contributors'
})
.addTo(this.map);
this.marker = null;
this.map.on('click', (e) => {
if (this.marker != null) {
this.latlng = e.latlng;
}
else {
this.marker = L.marker(e.latlng, {
id: `${this.pickerId}_marker`,
riseOnHover: true,
draggable: true,
});
this.map.addLayer(this.marker);
this.marker.on('drag', (e) => {
this.inputElement.value = `${e.latlng.lat}, ${e.latlng.lng}`;
});
}
this.inputElement.value = `${e.latlng.lat}, ${e.latlng.lng}`;
});
}
set latlng(latlng) {
this.marker.setLatLng(latlng);
this.inputElement.value = `${latlng.lat}, ${latlng.lng}`;
}
get latlng() {
return this.marker.getLatLng();
}
clear() {
this.marker.removeFrom(this.map);
this.marker = null;
this.inputElement.value = null;
}
}
const picker1 = new MapPicker('picker1');
const picker2 = new MapPicker('picker2');
.map-picker {
display: block;
margin-bottom: 2rem;
}
.map-picker .map {
height: 150px;
margin-bottom: 1rem;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Leaflet Example</title>
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css">
</head>
<body>
<div id="picker1"></div>
<div id="picker2"></div>
</body>
I am not sure where the input field with the ID acff-post-field_66575345d723e
(in your example code) comes from. With some modification, you can also use existing input fields:
class MapPicker {
constructor(pickerId, inputElement=null) {
this.pickerId = pickerId;
this.inputElement = inputElement;
this._init();
}
_init() {
this.pickerElement = document.getElementById(this.pickerId);
this.pickerElement.classList.add('map-picker');
this.mapElement = document.createElement('div');
this.mapElement.classList.add('map');
if (!this.inputElement) {
this.inputElement = document.createElement('input');
this.inputElement.setAttribute('type', 'text');
this.pickerElement.append(this.mapElement, this.inputElement);
}
else {
this.pickerElement.append(this.mapElement);
}
this.map = L.map(this.mapElement).setView([-6.175, 106.827], 8);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
// add a link to OpenStreetMap (omitted here for shorter line width)
attribution: '© OpenStreetMap contributors'
})
.addTo(this.map);
this.marker = null;
this.map.on('click', (e) => {
if (this.marker != null) {
this.latlng = e.latlng;
}
else {
this.marker = L.marker(e.latlng, {
id: `${this.pickerId}_marker`,
riseOnHover: true,
draggable: true,
});
this.map.addLayer(this.marker);
this.marker.on('drag', (e) => {
this.inputElement.value = `${e.latlng.lat}, ${e.latlng.lng}`;
});
}
this.inputElement.value = `${e.latlng.lat}, ${e.latlng.lng}`;
});
}
set latlng(latlng) {
this.marker.setLatLng(latlng);
this.inputElement.value = `${latlng.lat}, ${latlng.lng}`;
}
get latlng() {
return this.marker.getLatLng();
}
clear() {
this.marker.removeFrom(this.map);
this.marker = null;
this.inputElement.value = null;
}
}
const picker1 = new MapPicker('picker1',
document.getElementById('acff-post-field_66575345d723e'));
const picker2 = new MapPicker('picker2', document.getElementById('input2'));
.map-picker {
display: block;
margin-bottom: 2rem;
}
.map-picker .map {
height: 150px;
margin-bottom: 1rem;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Leaflet Example</title>
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css">
</head>
<body>
<input id="acff-post-field_66575345d723e" type="text">
<input id="input2" type="text">
<div id="picker1"></div>
<div id="picker2"></div>
</body>
Below my old answer thinking that you need two markers on one map. I didn't read the title just your description at first.
There are great tutorials on leafletjs.com how to use Leaflet. Unless there is a very good reason to use an old version of Leaflet, go with the most current version 1.9.4 as of June 11, 2024. Before I look at your issue, let's first clean up your code a little bit. (Please note that I am using vanilla JavaScript and not jQuery.)
<!DOCTYPE html>
<html lang="en">
<head>
<!-- ... -->
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css">
<style>
#map { height: 300px; }
</style>
</head>
<body>
<div id="map"></div>
<script>
const map = L.map('map').setView([-6.175, 106.827], 8);
const basemap = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
// add a link to OpenStreetMap (omitted here for shorter line width)
attribution: '© OpenStreetMap contributors',
});
basemap.addTo(map);
</script>
</body>
</html>
This example shows a simple basemap.
I assume that there is somewhere an input field with the ID acff-post-field_66575345d723e
. Let's add simple input fields for this example. I am choosing another ID (location1
for the first input field, and location2
for the second) to simplify the code:
<input type="text" name="location1" id="location1">
<input type="text" name="location2" id="location2">
Next, we'll add a L.layerGroup
for the marker(s):
const markerLayer = L.layerGroup();
markerLayer.addTo(map);
Next, we want to add pins to the map, you'll need to listen to a click
event as you already figured that out.
map.on('click', function(e) {
// ...
});
Now, we add the a marker when a click
event occurs. If I understand your question correctly, you want maximum 2 pins on the map.
map.on('click', (e) => {
const pinNumber = markerLayer.getLayers().length + 1;
if (pinNumber > 2) {
return; // no additional markers allowed
}
const inputElement = document.getElementById(`location${pinNumber}`);
const marker = L.marker(e.latlng, {
id: pinNumber,
title: `Pin ${pinNumber}`,
riseOnHover: true,
draggable: true,
});
markerLayer.addLayer(marker);
inputElement.value = `${e.latlng.lat}, ${e.latlng.lng}`;
});
After a second marker is added to the map, no additional markers will be added.
Finally, as you also figured out, you'll attach a drag
event listener to the marker:
map.on('click', (e) => {
// ...
markerLayer.addLayer(marker);
marker.on('drag', (e) => {
inputElement.value = `${e.latlng.lat}, ${e.latlng.lng}`;
});
inputElement.value = `${e.latlng.lat}, ${e.latlng.lng}`;
});
Here is a runnable example:
const map = L.map('map').setView([-6.175, 106.827], 8);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap contributors', // add a link
}).addTo(map);
const markerLayer = L.layerGroup().addTo(map);
map.on('click', (e) => {
const pinNumber = markerLayer.getLayers().length + 1;
if (pinNumber > 2) { return; }
const inputElement = document.getElementById(`location${pinNumber}`);
const marker = L.marker(e.latlng, {
id: pinNumber,
title: `Pin ${pinNumber}`,
riseOnHover: true,
draggable: true,
});
markerLayer.addLayer(marker);
marker.on('drag', (e) => {
inputElement.value = `${e.latlng.lat}, ${e.latlng.lng}`;
});
inputElement.value = `${e.latlng.lat}, ${e.latlng.lng}`;
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Leaflet Example</title>
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css">
<style>
#map {
height: 150px;
margin-bottom: 1rem;
}
</style>
</head>
<body>
<div id="map"></div>
<input type="text" name="location1" id="location1">
<input type="text" name="location2" id="location2">
</body>
</html>