2

I have a Leaflet map with markers that originate from two places: Stored coordinates in a database, retrieved as JSON and loaded to a GeoJSON object. The other is markers created from leaflet.Draw plugin.

With the database stored coordinates, I use pointToLayer to make them show up as circlemarkers, and associate a markerID property to them so I can track their database ID for future editing and Ajax calls to the server:

    //load markers from database
    $.getJSON("markers", function(data){
    //create markers
    var markers = L.geoJson(data, {
        //add each marker to drawnItems layer so they are editable with the draw plugin
        pointToLayer: function(feature, latlng) {
            return new L.CircleMarker(latlng, markerOptions);
        },
        onEachFeature: function (feature, layer) {
            layer.markerId = feature.properties.id; //add ID to properties to reference later
            layer.name=feature.properties.name;
            attachPopup(layer);
            layer.bindTooltip(layer.name, {permanent: true, direction: 'right', className: 'custom'});
            drawnItems.addLayer(layer);
        }
    });
});

In the attachPopup() logic, I have a popup form template that I attach to each marker to show form inputs with the name of the marker and some other information. I have a 'save' button on that popup. In the script I have a delegated listener for the '.save' being clicked and I fire off an update to the database:

$('body').on('click', '.save', function(){
        //get form data
        const form = document.querySelector('form');
        var data = Object.fromEntries(new FormData(form).entries());
        //send to server via ajax call (removed for brevity)
    });

The problem: On success from the Ajax database call - how do I update the layer.name property of the circlemarker whose name I am editing? I cannot figure out how to do this without refreshing the page/map and refetching and redrawing all the markers. I want the edited name to show in the popup form AND on the tooltip label. I am trying to figure out how to find that particular marker by its markerID that I assigned so I can update its properties.

A related question is this: When I add a marker using leaflet.Draw I immediately save it to the database and then display the popup form for further editing. When the form is submitted by clicking the save button - how do I set the layer.name for the marker?

EDIT: attachPopup() code added

function attachPopup(layer)
{
    var popupContent ='<form role="form" id="form" method="POST" enctype="multipart/form-data" class="form-horizontal">'+
      '<div class="form-group">'+
          '<label class="control-label"><strong>Marker Type: </strong></label>'+
          '<select class="form-control" id="type" name="type">'+
            '<option value="stand">Type 1</option>'+
            '<option value="parking">Type 2</option>'+
            '<option value="Other">Other</option>'+
          '</select>'+ 
      '</div>'+
      '<div class="form-group">'+
          '<label class="control-label"><strong>Name: </strong></label>'+
          '<textarea class="form-control" rows="1" id="descrip" name="descript">'+layer.name+'</textarea>'+
      '</div>'+
      '<input style="display: none;" type="text" id="Unique_id" name="unique_id" value="'+layer._leaflet_id+'" />'+
      '<input style="display: none;" type="text" id="id" name="id" value="'+layer.markerId+'" />'+
      '<input style="display: none;" type="text" id="lat" name="lat" value="'+layer.getLatLng().lat+'" />'+
      '<input style="display: none;" type="text" id="lng" name="lng" value="'+layer.getLatLng().lng+'" />'+
      '<div class="form-group">'+
        '<div style="text-align:center;" class="col-xs-4 col-xs-offset-2"><button type="button" class="btn">Cancel</button></div>'+
        '<div style="text-align:center;" class="col-xs-4"><button type="button" class="btn btn-primary save">Save</button></div>'+
      '</div>'+
      '</form>';
    
    layer.bindPopup(popupContent, {
        keepInView: true,
        closeButton: true,
        minWidth: 180
    }).openPopup();
}
2

In Leaflet each member of a group layer (marker is member of GeoJSON group layer) gets internal id, which can be retrieved with .getLayerId method. This id can later be used to retrieve desired member (marker) with the .getLayer method.

When you construct your popup with attachPopup(layer), you can retrieve marker layer id with

var layerId = markers.getLayerId(layer);

You can save this id somewhere in your popup object and later use it to retrieve desired marker and change it's name property:

var marker = markers.getLayer(savedId);
marker.name = newMarkerName;

To use this, you can add data-layer-id data attribute to the form element, with the value of layer id:

function attachPopup(layer)
{
    var layerId = markers.getLayerId(layer);
    var popupContent ='<form role="form" id="form" data-layer-id="' + layerId + '" method="POST" enctype="multipart/form-data" class="form-horizontal">'+
.
.
.

Then you can retrieve value of this attribute in your click event callback:

$('body').on('click', '.save', function(){
  const form = document.querySelector('form');
  var layerId = form.getAttribute('data-layer-id');
  var markerLayer = markers.getLayer(layerId);
  var data = Object.fromEntries(new FormData(form).entries());
});
4
  • thank you. I edited OP to include the code for attachPopup() – DanN Feb 8 at 18:50
  • Answer updated accordingly. – TomazicM Feb 8 at 19:15
  • One more follow up question for you - are markers created from Leaflet.Draw plugin handled differently than markers created from geoJSON? – DanN Feb 8 at 19:47
  • No, they aren't. – TomazicM Feb 8 at 20:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.