Search code examples
javascripthtmlinputleafletopenstreetmap

Is there a way to open a popup input text after a polygon is created in leaflet?


I'm trying to make a web app that uses leaflet to display a map, users should be able to draw and edit polygons over the map and they should have the ability to name each polygon they create.

I want to open a popup when a polygon is created that asks for a name and then set it to a property in a geojson feature.

I tried to follow this example Leaflet popup form but I couldn't get it to work with the leaflet draw created event.

Here's what I got.

// Map center
var center = [-32.692825, -62.104689];

// Map creation
var map = L.map('map').setView(center, 14);

// Map tile layer
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
  maxZoom: 19,
  attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);

// Initialise the FeatureGroup to store editable layers
var editableLayers = new L.FeatureGroup();
map.addLayer(editableLayers);

// Draw plugin options
var drawPluginOptions = {
  position: 'topleft',
  draw: {
    polygon: {
      allowIntersection: false, // Restricts shapes to simple polygons
      drawError: {
        color: '#e1e100', // Color the shape will turn when intersects
        message: '<strong>Oh snap!<strong> you can\'t draw that!' // Message that will show when intersect
      },
      shapeOptions: {
        color: '#97009c'
      }
    },
    // disable toolbar item by setting it to false
    polyline: false,
    circle: false, // Turns off this drawing tool
    rectangle: false,
    marker: false,
  },
  edit: {
    featureGroup: editableLayers,
    polygon: {
      allowIntersection: false
    } //REQUIRED!!
  }
};

// Initialise the draw control and pass it the FeatureGroup of editable layers
var drawControl = new L.Control.Draw(drawPluginOptions);
map.addControl(drawControl);

var editableLayers = new L.FeatureGroup();
map.addLayer(editableLayers);

// draw created event handler
function polygonCreateHandler(e) {

  var type = e.layerType;
  var layer = e.layer;

  if (type != 'polygon') {
    alert("ESTO NO ES UN POLIGONO");
    return;
  }

  editableLayers.addLayer(layer);
}

// draw created event
map.on('draw:created', function(e) {
  polygonCreateHandler(e);
});

//Ignore this

/*jshint multistr: true */
var template = '<form id="popup-form">\
  <label for="input-speed">New speed:</label>\
  <input id="input-speed" class="popup-input" type="number" />\
  <button id="button-submit" type="button">Save Changes</button>\
</form>';

/*
** fetch geojson example
let geojson_url = "https://raw.githubusercontent.com/delineas/leaflet-flyto-webpack-bulma/master/src/data/arboles_singulares_en_espacios_naturales.geojson"
fetch(
  geojson_url
).then(
  res => res.json()
).then(
  data => {
    let geojsonlayer = L.geoJson(data, {
      onEachFeature: function(feature, layer) {
        layer.bindPopup(feature.properties['arbol_nombre'])
        layer.setIcon(treeMarker)
      }
    }).addTo(map) 
    map.fitBounds(geojsonlayer.getBounds())
  }
)

** layer polygon example

var geojson_msjz_polygon = {
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": { "name": "Test Distrito electoral"},
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              -62.103266716003425,
              -32.687209099455636
            ],
            [
              -62.13047504425048,
              -32.68211618935444
            ],
            [
              -62.133564949035645,
              -32.693746380985395
            ],
            [
              -62.106142044067376,
              -32.698838627713116
            ],
            [
              -62.103266716003425,
              -32.687209099455636
            ]
          ]
        ]
      }
    }
  ]
};

let geojsonlayer = L.geoJson(geojson_msjz_polygon, {
      onEachFeature: function(feature, layer) {
        let text = L.tooltip({
          permanent: true,
          direction: 'center',
          className: 'text'
        })
        .setContent(feature.properties.name)
        .setLatLng(layer.getBounds().getCenter());
        text.addTo(map);
      }
    }).addTo(map);

map.fitBounds(geojsonlayer.getBounds())
*/
#map {
  height: 98vh;
  width: 100hw;
}

body {
  margin: 0;
}

html,
body,
#leaflet {
  height: 100%;
}

.popup-table {
  width: 100%;
}

.popup-table-row {
  background-color: grey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.0-beta.2.rc.2/leaflet.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.0-beta.2.rc.2/leaflet.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.2.3/leaflet.draw.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.2.3/leaflet.draw.css" rel="stylesheet" />
<div id="map"></div>


Solution

  • Just bind a popup on the created layer and open it once it is created

    function polygonCreateHandler(e) {
    
      var type = e.layerType;
      var layer = e.layer;
    
      if (type != 'polygon') {
        alert("ESTO NO ES UN POLIGONO");
        return;
      }
    
      editableLayers.addLayer(layer);
      
      layer.bindPopup(template).openPopup(); // here create and open the popup with your form
    }
    

    // Map center
    var center = [-32.692825, -62.104689];
    
    // Map creation
    var map = L.map('map').setView(center, 14);
    
    // Map tile layer
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      maxZoom: 19,
      attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);
    
    // Initialise the FeatureGroup to store editable layers
    var editableLayers = new L.FeatureGroup();
    map.addLayer(editableLayers);
    
    // Draw plugin options
    var drawPluginOptions = {
      position: 'topleft',
      draw: {
        polygon: {
          allowIntersection: false, // Restricts shapes to simple polygons
          drawError: {
            color: '#e1e100', // Color the shape will turn when intersects
            message: '<strong>Oh snap!<strong> you can\'t draw that!' // Message that will show when intersect
          },
          shapeOptions: {
            color: '#97009c'
          }
        },
        // disable toolbar item by setting it to false
        polyline: false,
        circle: false, // Turns off this drawing tool
        rectangle: false,
        marker: false,
      },
      edit: {
        featureGroup: editableLayers,
        polygon: {
          allowIntersection: false
        } //REQUIRED!!
      }
    };
    
    // Initialise the draw control and pass it the FeatureGroup of editable layers
    var drawControl = new L.Control.Draw(drawPluginOptions);
    map.addControl(drawControl);
    
    var editableLayers = new L.FeatureGroup();
    map.addLayer(editableLayers);
    
    var template = '<form id="popup-form">\
      <label for="input-speed">New speed:</label>\
      <input id="input-speed" class="popup-input" type="number" />\
      <button id="button-submit" type="button">Save Changes</button>\
    </form>';
    
    var createdPolygonTemplate = '<form id="popup-form">\
       <label for="input-speed">Name:</label>\
       <input id="name" type="text" />\
    </form>';
    
    // draw created event handler
    function polygonCreateHandler(e) {
    
      var type = e.layerType;
      var layer = e.layer;
    
      if (type != 'polygon') {
        alert("ESTO NO ES UN POLIGONO");
        return;
      }
    
      editableLayers.addLayer(layer);
    
      layer.bindPopup(createdPolygonTemplate).openPopup()
    }
    
    // draw created event
    
    map.on('draw:created', function(e) {
      polygonCreateHandler(e);
    });
    
    //Ignore this
    
    /*jshint multistr: true */
    
    
    /*
    ** fetch geojson example
    let geojson_url = "https://raw.githubusercontent.com/delineas/leaflet-flyto-webpack-bulma/master/src/data/arboles_singulares_en_espacios_naturales.geojson"
    fetch(
      geojson_url
    ).then(
      res => res.json()
    ).then(
      data => {
        let geojsonlayer = L.geoJson(data, {
          onEachFeature: function(feature, layer) {
            layer.bindPopup(feature.properties['arbol_nombre'])
            layer.setIcon(treeMarker)
          }
        }).addTo(map) 
        map.fitBounds(geojsonlayer.getBounds())
      }
    )
    
    ** layer polygon example
    
    var geojson_msjz_polygon = {
      "type": "FeatureCollection",
      "features": [
        {
          "type": "Feature",
          "properties": { "name": "Test Distrito electoral"},
          "geometry": {
            "type": "Polygon",
            "coordinates": [
              [
                [
                  -62.103266716003425,
                  -32.687209099455636
                ],
                [
                  -62.13047504425048,
                  -32.68211618935444
                ],
                [
                  -62.133564949035645,
                  -32.693746380985395
                ],
                [
                  -62.106142044067376,
                  -32.698838627713116
                ],
                [
                  -62.103266716003425,
                  -32.687209099455636
                ]
              ]
            ]
          }
        }
      ]
    };
    
    let geojsonlayer = L.geoJson(geojson_msjz_polygon, {
          onEachFeature: function(feature, layer) {
            let text = L.tooltip({
              permanent: true,
              direction: 'center',
              className: 'text'
            })
            .setContent(feature.properties.name)
            .setLatLng(layer.getBounds().getCenter());
            text.addTo(map);
          }
        }).addTo(map);
    
    map.fitBounds(geojsonlayer.getBounds())
    */
    #map {
      height: 98vh;
      width: 100hw;
    }
    
    body {
      margin: 0;
    }
    
    html,
    body,
    #leaflet {
      height: 100%;
    }
    
    .popup-table {
      width: 100%;
    }
    
    .popup-table-row {
      background-color: grey;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.0-beta.2.rc.2/leaflet.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.0-beta.2.rc.2/leaflet.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.2.3/leaflet.draw.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.2.3/leaflet.draw.css" rel="stylesheet" />
    <div id="map"></div>