I am making a Leaflet map that gets its marker and popup information from a database.

I have a dropdown that allows me to retrieve a subset of the entire database based on category. The drop-down and map work correctly.

I have 2 problems:

  1. I have been unsuccessful getting fitBounds to work.
  2. When the map loads a category of markers from the dropdown, I want any existing markers on the map from previous searches removed

Here is the code:

<link rel="stylesheet" href="leaflet.css" />
<script src="leaflet-src.js"></script>
<script type="text/javascript" src="leaflet.ajax.js"></script>
<title>Member Map</title>
</head>
<body>
  <div id="options">
    <?php
      $conn = new mysqli("localhost","","","") or die($this->mysqli->error);
      $result = $conn->query("SELECT Bus_categories FROM markers GROUP BY Bus_categories");
      echo "<form>";
      echo "<select name='cs' onchange='showUser (this.value)'>";
      echo "<option style='value=selected'>Select Business Category</option>";
      while ($row = $result->fetch_assoc()) {
        unset($name);
        $name = $row['Bus_categories']; 
        echo '<option  value="'.$name.'">'.$name.'</option>';
      }
      echo "</select></form>";
    ?>
  </div>
  <div id="map"></div>
  <script type="text/javascript">
    var geojsonLayer;
    var bounds;
    var m = L.map('map').setView([39.1, -94.5], 8);
    var mopt = {
      url: 'https://api.mapbox.com/styles/v1/mapbox/streets-v10/tiles/256/{z}/{x}/{y}?access_token=<API KEY HERE>',
      options: {attribution:'© <a href="https://www.mapbox.com/map-feedback/">Mapbox</a> © <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'}
    };
    var mq = L.tileLayer(mopt.url,mopt.options);
    mq.addTo(m);

    function popUp(feature,layer) {
      layer.bindPopup(
        "<h2>"+feature.properties.Member_Name+
        "<h3>"+feature.properties.Address+
        "<br>"+feature.properties.City+
        "<br><br><a href=tel:"+feature.properties.Phone+ ">"+feature.properties.Phone+ "</a>" +
        "<br><br><a href=mailto:"+feature.properties.Email+ ">" +feature.properties.Email+ "</a>" +
        "<br><br><a href=http://"+feature.properties.Website+ ">" +feature.properties.Website+ "</a>" +
        "<br>"
      );
    }

    function showUser(str) {
      geojsonLayer = new L.GeoJSON.AJAX(["geojson.php?cs="+str,true],{onEachFeature:popUp}).addTo(m);
      if(geojsonLayer){ m.removeLayer(geojsonLayer) };
      bounds = geojsonLayer.getBounds().pad(0.2);  
      m.fitBounds(bounds);      
    }
  </script>
</body>

Here is an example of the geojson data the map is getting from geojson.php

 {"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-94.905793,39.416633]},"properties":{"Member_Name":"Angels Rock Bar","Contact":"Pedro Lopez","Address":"1323 Walnut","City":"Kansas City","Phone":"(816) 896-3943","Email":"info@angelsrockbarkc.com","Website":"www.angelsrockbarkc.com"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-94.541461,39.051003]},"properties":{"Member_Name":"Bar K","Contact":"Leib Dodell","Address":"501 Berkley Parkway","City":"Kansas City","Phone":"(816) 225-6961","Email":"wag@barkdogpbar.com","Website":"www.barkdogbar.com"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-94.583506,39.098954]},"properties":{"Member_Name":"The Indie on Main","Contact":"Jamie Pitts","Address":"1228 Main St.","City":"Kansas City","Phone":"(816) 283-9900","Email":"","Website":""}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-94.578476,39.091498]},"properties":{"Member_Name":"International Tap House (iTap)","Contact":"Jonathan Whitaker","Address":"403 E. 18th St.","City":"Kansas City","Phone":"(816) 701-6606","Email":"beer@internationaltaphouse.com","Website":"www.internationaltaphouse.com"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-94.541461,39.051003]},"properties":{"Member_Name":"Kill Devil Club","Contact":"Scott Tipton","Address":"31 E.14th St.","City":"Kansas City","Phone":"(816) 674-4137","Email":"","Website":"www.killdevilclub.com"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-94.603187,39.061865]},"properties":{"Member_Name":"The Monarch Bar, LLC","Contact":"Kenny Cohrs","Address":"4808 Roanoke Pkwy.","City":"Kansas City","Phone":"(816) 437-7912","Email":"info@themonarchbar.com","Website":"www.themonarchbar.com"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-94.581677,39.098391]},"properties":{"Member_Name":"PBR Big Sky","Contact":"Will Kinser","Address":"111 E 13th St.","City":"Kansas City","Phone":"(816) 442-8145","Email":"info@pbrbigskykc.com","Website":"www.pbrbigskykc.com"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-94.581637,39.097872]},"properties":{"Member_Name":"Shark Bar","Contact":"Elliot Duckworth","Address":"1340 Grand Blvd.","City":"Kansas City","Phone":"(816) 377-9442","Email":"elliot@sharkbarkc.com","Website":"www.sharkbarkc.com"}}]}
  • What are the error message? (Press F12 in Firefox or Chrome (?) and look at the console output.) – Stefan Nov 28 at 7:19
  • Please see my comment about errors to @Francisco – dnevels Nov 28 at 20:06

The variable geojsonLayer is local to the function showUser. Each time showUser is called (when the select changes) the value of geojsonLayer will NOT be, the previous layer that you use.

An easy solution for your currently code is convert geojsonLayer to be global variable.

And use removeLayer instead of clearLayers.

<script type="text/javascript">
    var geojsonLayer;  // outside any function it will be global
    var m= L.map('map').setView([39.1, -94.5], 8);

    ...


    function showUser(str) {
        if (geojsonLayer) {
            m.removeLayer(geojsonLayer);  // Remove the object from the map
        }
        geojsonLayer = new L.GeoJSON.AJAX(["geojson.php?cs="+str,true],{onEachFeature:popUp})
        geojsonLayer.addTo(m);
        var bounds = geojsonLayer.getBounds().pad(0.2);  // Extend the bounds a a 10%. Take care if the layer is a single point. Should be a local var
        m.fitBounds(bounds);
     }
  • I updated the code I originally posted to include your code. The console did not show any errors on page load but when I attempt to choose a select, no markers appear and the console shows a TypeError for removeLayer, showUser and onchange. These errors did not occur before addition of the code. I deleted the removeLayer and TypeErrors are the same except removeLayer points to 'leaflet-src.js' instead of where I added it. Still does not show any markers. Did I put the code in the wrong place? – dnevels Nov 28 at 20:02
  • The first time you call showUser, geojsonLayer would be empty. Thus you cannot remove it from the map. You can catch this by writing if(geojsonLayer){m.removeLayer(geojsonLayer)} as the first command of showUser. – Stefan Nov 28 at 21:54
  • @Stefan_Fairphone I updated the code to include your suggestions. If all the code is included then no markers are shown and same TypeErrors as before. If I comment out the removeLayer statement I get markers but the fitBounds does not work and I get the same errors. If I comment out the bounds and just leave the removeLayer then I get no markers and no errors – dnevels Nov 28 at 23:29
  • I update my code. It will be usefull have the geojson that your are getting from your backend – Francisco Puga Nov 29 at 8:27
  • I added some example geojson data the file above is getting when a category is selected from the drop down. – dnevels Nov 30 at 4:53

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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