Eric Miller
Eric Miller

Reputation: 47

Google Maps function not defined

I am trying to set up a series of checkboxes so multiple Overlays can be toggled on/off individually in a menu. I'm just trying to get one layer working before I move on to developing the rest of them. I am, unfortunately, getting an error when using Dev Tools that states Uncaught ReferenceError: toggleLayers is not defined at HTMLInputElement.onclick

I think I have the function defined but keep getting this error.

    <!DOCTYPE html>
    <html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>Removing Overlays</title>
    <style>
      /* Always set the map height explicitly to define the size of the div
       * element that contains the map. */
      #map {
        height: 100%;
      }
      /* Optional: Makes the sample page fill the window. */
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
      #floating-panel {
        position: absolute;
        top: 10px;
        left: 25%;
        z-index: 5;
        background-color: #fff;
        padding: 5px;
        border: 1px solid #999;
        text-align: center;
        font-family: 'Roboto','sans-serif';
        line-height: 30px;
        padding-left: 10px;
      }
    </style>
    <script>


       var map;

        function initMap() {
          map = new google.maps.Map(document.getElementById('map'), {
            zoom: 5,
            center: {lat: 35.391, lng: -74.447},
            mapTypeId: google.maps.MapTypeId.SATELLITE,
            disableDefaultUI: true,
          });

        var imageBounds = {
          north: 41.68,
          south: 30.43,
          east: -69.26,
          west: -81.91
        };


            var map = null;
            var layers = [];
            layers[0] = new google.maps.GroundOverlay("https://www.saltwx.com/images/A2020022172000.L2_LAC.S3472.nc.MidAtlantic.chlor_a.png", imageBounds);
                {
              preserveViewport: true};


        function toggleLayers(i) {
              if (layers[i].getMap() == null) {
                layers[i].setMap(map);
              } else {
                layers[i].setMap(null);
              }
            }
          }
    </script>
    <script async defer
    src="https://maps.googleapis.com/maps/api/js?key=MY_API_KEY&callback=initMap">
    </script>
  </head>
  <body>
    <div id="floating-panel">
      <input type="checkbox" value="Toggle NOAA Buoy Layer" onclick="toggleLayers(0);">NOAA Buoys</input></a>TURN ON

    </div>
    <div id="map"></div>

  </body>
</html>

Upvotes: 1

Views: 713

Answers (3)

geocodezip
geocodezip

Reputation: 161404

To be used as an HTML click function, the routine needs to be in the global scope. Currently it is local to your initMap function.

You will also need the layers array in the global scope.

proof of concept fiddle

screenshot of map

code snippet:

var map = null;
var layers = [];

function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    zoom: 5,
    center: {
      lat: 35.391,
      lng: -74.447
    },
    mapTypeId: google.maps.MapTypeId.SATELLITE,
    disableDefaultUI: true,
  });

  var imageBounds = {
    north: 41.68,
    south: 30.43,
    east: -69.26,
    west: -81.91
  };

  layers[0] = new google.maps.GroundOverlay("https://www.saltwx.com/images/A2020022172000.L2_LAC.S3472.nc.MidAtlantic.chlor_a.png", imageBounds); {
    preserveViewport: true
  };
}

function toggleLayers(i) {
  if (layers[i].getMap() == null) {
    layers[i].setMap(map);
  } else {
    layers[i].setMap(null);
  }
}
/* Always set the map height explicitly to define the size of the div
       * element that contains the map. */

#map {
  height: 100%;
}


/* Optional: Makes the sample page fill the window. */

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#floating-panel {
  position: absolute;
  top: 10px;
  left: 25%;
  z-index: 5;
  background-color: #fff;
  padding: 5px;
  border: 1px solid #999;
  text-align: center;
  font-family: 'Roboto', 'sans-serif';
  line-height: 30px;
  padding-left: 10px;
}
<div id="floating-panel">
  <input type="checkbox" value="Toggle NOAA Buoy Layer" onclick="toggleLayers(0);" />NOAA Buoys TURN ON
</div>
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap">
</script>

You can leave it inside the initMap function if you apply it to the HTML elements using the google.maps.event.addDomListener function.:

function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    zoom: 5,
    center: {
      lat: 35.391,
      lng: -74.447
    },
    mapTypeId: google.maps.MapTypeId.SATELLITE,
    disableDefaultUI: true,
  });

  var imageBounds = {
    north: 41.68,
    south: 30.43,
    east: -69.26,
    west: -81.91
  };

  layers[0] = new google.maps.GroundOverlay("https://www.saltwx.com/images/A2020022172000.L2_LAC.S3472.nc.MidAtlantic.chlor_a.png", imageBounds); {
    preserveViewport: true
  };

  function toggleLayers(i) {
    if (layers[i].getMap() == null) {
      layers[i].setMap(map);
    } else {
      layers[i].setMap(null);
    }
  }

  google.maps.event.addDomListener(document.getElementById('toggleBuoyLayer'), 'click', function() {
    toggleLayers(0);
  })
}

proof of concept fiddle

code snippet:

var map = null;
var layers = [];

function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    zoom: 5,
    center: {
      lat: 35.391,
      lng: -74.447
    },
    mapTypeId: google.maps.MapTypeId.SATELLITE,
    disableDefaultUI: true,
  });

  var imageBounds = {
    north: 41.68,
    south: 30.43,
    east: -69.26,
    west: -81.91
  };

  layers[0] = new google.maps.GroundOverlay("https://www.saltwx.com/images/A2020022172000.L2_LAC.S3472.nc.MidAtlantic.chlor_a.png", imageBounds); {
    preserveViewport: true
  };

  function toggleLayers(i) {
    if (layers[i].getMap() == null) {
      layers[i].setMap(map);
    } else {
      layers[i].setMap(null);
    }
  }

  google.maps.event.addDomListener(document.getElementById('toggleBuoyLayer'), 'click', function() {
    toggleLayers(0);
  })
}
/* Always set the map height explicitly to define the size of the div
       * element that contains the map. */

#map {
  height: 100%;
}


/* Optional: Makes the sample page fill the window. */

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#floating-panel {
  position: absolute;
  top: 10px;
  left: 25%;
  z-index: 5;
  background-color: #fff;
  padding: 5px;
  border: 1px solid #999;
  text-align: center;
  font-family: 'Roboto', 'sans-serif';
  line-height: 30px;
  padding-left: 10px;
}
<div id="floating-panel">
  <input type="checkbox" id="toggleBuoyLayer" value="Toggle NOAA Buoy Layer" />NOAA Buoys TURN ON
</div>
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap">
</script>

Upvotes: 2

Tnc Andrei
Tnc Andrei

Reputation: 1012

You should load the google maps script before your script.

Because google.maps.Map is a function constructor and you instantiate using the new keyword, it must be defined before you can use it. And you should also move your script at the bottom or use

document.addEventListener('DOMContentLoaded', (event) => {
  // your code
})

Upvotes: 1

Muhammad Afaq Riaz
Muhammad Afaq Riaz

Reputation: 400

You are declaring toggleLayers function inside the initMap function. That's why you are getting this error. Just declare the function outside the initMap function.

Upvotes: 3

Related Questions