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>
  <div id="options">
      $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()) {
        $name = $row['Bus_categories']; 
        echo '<option  value="'.$name.'">'.$name.'</option>';
      echo "</select></form>";
  <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);

    function popUp(feature,layer) {
        "<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>" +

    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);  

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 '18 at 7:19
  • Please see my comment about errors to @Francisco
    – dnevels
    Nov 28 '18 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})
        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
  • 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 '18 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 '18 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 '18 at 23:29
  • I update my code. It will be usefull have the geojson that your are getting from your backend Nov 29 '18 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 '18 at 4:53

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.