2

I am trying to create a map with multiple selection option of multiple L.GeoJSON.AJAX layers. I have difficulty incorporating specific style and onEachFeature functions to each layer. Can anyone please help me and see where I went wrong in my coding. So basically, when a user selects one or more geojson layers from a Bootstrap Navbar multiselect bar, s/he needs to be able to see and interact with the selected layers' style and other functions. Here is the section of my code with which I need help:

<body>
  <li class="nav-item">
    <select multiple="multiple" id="donnees">
      <option value="ecoterritoires.geojson">Écoterritoires</option>
      <option value="grands-parcs.geojson">Grands parcs</option>
      <option value="friches.geojson">Friches</option>
      <option value="densite-de-construction.geojson">Densité urbain</option>
    </select>
  </li>
</body>
<script>
  $(document).ready(function () {
    $("#donnees").multiselect({
      buttonClass: "custom-select",
      nonSelectedText: "Sélectionnez une ou plusieurs couches",
      allSelectedText: "Toutes les couches",
      onChange: function () {
        // Retirer la couche précédemment chargée
        myMap.eachLayer(function (layer) {
          if (layer instanceof L.GeoJSON) myMap.removeLayer(layer);
        });
        var couches_selectionnees = this.$select.val();
        for (var i = 0; i < couches_selectionnees.length; i++) {
          new L.GeoJSON.AJAX("data/" + couches_selectionnees[i], {
            style: function (feature) {
              if (couches_selectionnees[i] === "ecoterritoires.geojson") {
                return {
                  color: "#006600",
                  fillColor: "#00ff00",
                  fillOpacity: 0,
                  dashArray: 1,
                  weight: 0.8,
                };
              } else if (couches_selectionnees[i] === "friches.geojson") {
                return {
                  color: "#006600",
                  fillColor: "#00cc00",
                  fillOpacity: 1,
                  dashArray: 3,
                  weight: 0.5,
                };
              } else if (couches_selectionnees[i] === "grands-parcs.geojson") {
                return {
                  color: "#006600",
                  fillColor: "#b3b300",
                  fillOpacity: 0.6,
                  dashArray: 2,
                  weight: 0.3,
                };
              } else if (couches_selectionnees[i] === "densite-de-construction.geojson") {
                return {
                  color: "grey",
                  fillColor: classifier(feature.properties.indice),
                  fillOpacity: 0.8,
                  dashArray: 1,
                  weight: 0.5,
                };
              }
            },
          }).addTo(myMap);
        }
      },
    });
  });
</script>
IvanSanchez
  • 18,272
  • 3
  • 30
  • 45
  • So what's the problem exactly? What's the expected outcome and the actual outcome? – IvanSanchez Apr 23 '21 at 17:48
  • The problem is the specific styles do not appear upon selection of that specific layer. The polygons are all represented by default color and fill color blue, as if there is no style added to the layers in the code. For some reason, the styles doesn't get associated with the layers. – Farkhunda Rezaie Apr 23 '21 at 17:54
  • You'll have to be specific about the versions of jquery and bootstrap being used. As of now, your code isn't reproducible. Do read https://stackoverflow.com/help/minimal-reproducible-example – IvanSanchez Apr 23 '21 at 18:39

1 Answers1

1

Similarly to Using an iterator within L.marker, you should be good by simply replacing for (var i by for (let i

With var i, you have a function scope variable, so it is actually the same one for all your loops. In particular, at the end of the loop, i is equal to couches_selectionnees.length. And once your GeoJSON data arrives and executes your style function callback, it does not match any of your conditions, hence does not return anything, hence you only get the default style.

With let i, you now have a block scope variable, i.e. a different one for each of your loops block.

BTW you could also use for (const i in JavaScript, but TypeScript would complain that the later increment i++ is illegal.

ghybs
  • 47,565
  • 6
  • 74
  • 99
  • 1
    Thank you so very much. I am new to all this. The difference between 'let' and 'var' is quite significant contrary to what I believed. You have been a great help. – Farkhunda Rezaie Apr 26 '21 at 15:19
  • Thank you for your nice feedback! Please note that the SO way to thank people is also to _accept_ the answer that helped you. It also signals to others that your issue is solved. – ghybs Apr 30 '21 at 03:00