0

I am building an app in Leaflet where a user can click on a GeoJSON feature and it will show the unique value of the feature in the popup. The attributes shown are each in an input box so that the user can edit them. Originally my table was inside my popup with the value of each property set to feature.properties.property but that didn't seem editable so I put it in a <div> element. I'm a novice to HTML and JavaScript so it's possible I'm taking the wrong approach. But when I click on a feature instead of it pulling that feature's unique attributes, it appears to be picking up the attributes of the last feature in my GeoJSON.

I know that it won't update automatically without a web server. I don't know if I would be allowed to set one up if I knew how, so I have a workaround where I added a button that exports the GeoJSON. Previously I copied the code in this Plunker but pointed it to one of my feature attributes: http://plnkr.co/edit/VzUfSD?p=preview.

Clicking a feature gave me its unique value and upon editing it and clicking the button, it downloaded a new GeoJSON file with the edited value changed, so I know my workaround works (but it doesn't permanently change my GeoJSON until I save my downloaded file over it).

So why won't it give me the attributes of the feature I click but (apparently) those of the last feature in my GeoJSON file?

Here is the HTML code for the popup:

<div id="popup">
<table>
   <tr>
      <td colspan="2"><strong>Pipe Size:</strong><br /><input id="PS1"></td>
   </tr>
   <tr>
      <td colspan="2"><strong>Pipe Type:</strong><br /><input id="PS2"></td>
   </tr>
   <tr>
      <td colspan="2"><strong>Pipe Material:</strong><br /><input id="PS3"></td>
   </tr>
   <tr>
      <td colspan="2"><strong>Mylar File Name:</strong><br /><input id="PS4"></td>
   </tr>
   <tr>
      <td colspan="2"><a id="PS5" target="_blank">Mylar Tablet</a></td>
   </tr>
   <tr>
      <td colspan="2"><a id="PS6" target="_blank">Mylar Desktop</a></td>
   </tr>
</table>
</div>

And here is the JavaScript Code for the popup:

function pop_WaterPipe(feature, layer) {
    var popupContent = document.getElementById("popup");
    PS1 = document.getElementById("PS1");
    PS1.value = feature.properties['PipeSize'];
    PS1.addEventListener('change', function () {
        feature.properties['PipeSize']= PS1.value;
    });
    PS2 = document.getElementById("PS2");
    PS2.value = feature.properties['PipeType'];
    PS2.addEventListener('change', function () {
        feature.properties['PipeType'] = PS2.value;
    });
    PS3 = document.getElementById("PS3");
    PS3.value = feature.properties['PipeMateri'];
    PS3.addEventListener('change', function () {
        feature.properties['PipeMateri'] = PS3.value;
    });
    PS4 = document.getElementById("PS4");
    PS4.value = feature.properties['Service_Ca'];
    PS4.addEventListener('change', function () {
        feature.properties['Service_Ca'] = PS4.value;
    });
    PS5 = document.getElementById("PS5");
    PS5.href = '"W:/DPW' + '/' + 'Water_&_Sewer' + '/' + 'App' + '/' + 'Street Mylars' + '/' + (feature.properties['Service_Ca'] !== null ? Autolinker.link(String(feature.properties['Service_Ca'])) : 'None') + '"';
    PS6 = document.getElementById("PS6");
    PS6.href = '"W:/DPW' + '/' + 'Water_&_Sewer' + '/' + 'App' + '/' + 'Street Mylars' + '/' + (feature.properties['Service_Ca'] !== null ? Autolinker.link(String(feature.properties['Service_Ca'])) : 'None') + '"';
    layer.bindPopup(popupContent);
    }
  • tl;dr, major issue: editing data clientside is not as simple as you might expect. in fact, to permanently edit static data retrieved from the server (e.g. your GeoJSON), you will need the server to make those edits (i.e. send the edits to an accepting backend); the browser is neither allowed to access files on disc (95% true) nor the server per se. sorry to say you are touching a very complex topic here... – ThingumaBob Jul 27 '18 at 20:18
  • Basically you need a database on the web server, using something like PHP you create a web service to server your layers data as GeoJSON. Then in your web page you use ajax to send the updated data to a PHP page that writes back to the servers database(server side). The way you have it is client side, and your edits are only in your browser not on the server. No one else would see them. – Bill Chappell Jul 27 '18 at 23:02
  • @ThingumaBob I have edited my question. The web server isn't the issue as I have a workaround and everything else works the way I want it to. My problem is that it's not getting each individual feature's unique attributes, just the last one in the file's. – Ryan Norton Jul 30 '18 at 12:36
  • @BillChappell I have edited my question. The web server isn't the issue as I have a workaround and everything else works the way I want it to. My problem is that it's not getting each individual feature's unique attributes, just the last one in the file's. – Ryan Norton Jul 30 '18 at 12:39
0

In your layer definition, in it's onEachFeature function, you use a layer.on.click event to get that features information. Below I would take it's PipeSize value and stick it in the table element "PS1".

function forEachFeature(feature, layer) {
        var popupContent = document.getElementByID("popup");  
        layer.bindPopup(popupContent);
        layer.on('click', function (e) {
            PS1 = document.getElementById("PS1");
            PS1.value = e.target.feature.properties.PipeSize;
            })
        };

Then

var pipe = L.geoJSON(null, {
            onEachFeature: forEachFeature,
            color:'blue'
           });
  • Thanks, just a slight modification, before the layer.on I add var popupContent = document.getElementByID("popup"); and add layer.bindPopup(popupContent); just before the end. But then it works! The only problem is now when I click the layer the second time it gives me a "Cannot set property 'value' of null" error, but that's minor and I'm sure I'll figure that out. – Ryan Norton Jul 30 '18 at 15:13
  • If your getting it from the popup, it has to close before you click the second time. Here is an example i used for getting the feature click to show in the html table.. gistechsolutions.com/leaflet/DEMO/baseball/BaseballPanel.html – Bill Chappell Jul 30 '18 at 15:54
  • Okay, I had the layer.bindPopup(popupContent); line in the wrong spot. Moving it up to there solved my problem. – Ryan Norton Aug 2 '18 at 15:40

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.