Handle click events

Overview

You can make a feature layer respond to user click events, to get the place ID, display name, and feature type for the boundary that was clicked. The following example map shows the boundaries for Administrative Area Level 2, and shows an event handler that styles the clicked polygon, and displays an info window with the event data.

Enable feature layer events

Take the following steps to enable events on a feature layer:

  1. Register a feature layer for click event notifications by calling addListener(), passing the type of event (click) and the name of the event handler function.

    TypeScript

    // Add the feature layer.
    //@ts-ignore
    featureLayer = map.getFeatureLayer('ADMINISTRATIVE_AREA_LEVEL_2');
    // Add the event listener for the feature layer.
    featureLayer.addListener('click', handlePlaceClick);

    JavaScript

    // Add the feature layer.
    //@ts-ignore
    featureLayer = map.getFeatureLayer("ADMINISTRATIVE_AREA_LEVEL_2");
    // Add the event listener for the feature layer.
    featureLayer.addListener("click", handlePlaceClick);

  2. Apply a fill style with fillOpacity of 0.1 or greater to make a feature respond to events. Only visible features are clickable.

    TypeScript

    // Stroke and fill with minimum opacity value.
    //@ts-ignore
    const styleDefault: google.maps.FeatureStyleOptions = {
        strokeColor: '#810FCB',
        strokeOpacity: 1.0,
        strokeWeight: 2.0,
        fillColor: 'white',
        fillOpacity: 0.1 // Polygons must be visible to receive click events.
    };
    
    // Style for the clicked Administrative Area Level 2 polygon.
    //@ts-ignore
    const styleClicked: google.maps.FeatureStyleOptions = {
        ...styleDefault,
        fillColor: '#810FCB',
        fillOpacity: 0.5
    };

    JavaScript

    // Stroke and fill with minimum opacity value.
    //@ts-ignore
    const styleDefault = {
      strokeColor: "#810FCB",
      strokeOpacity: 1.0,
      strokeWeight: 2.0,
      fillColor: "white",
      fillOpacity: 0.1, // Polygons must be visible to receive click events.
    };
    // Style for the clicked Administrative Area Level 2 polygon.
    //@ts-ignore
    const styleClicked = {
      ...styleDefault,
      fillColor: "#810FCB",
      fillOpacity: 0.5,
    };
    

  3. Add code to handle the event. In this example, the event handler styles the selected polygon, and displays an info window.

    TypeScript

    // Handle the click event.
    function handlePlaceClick(event) {
        let feature = event.features[0];
        console.log(event);
        if (!feature.placeId) return;
        // Apply the style to the feature layer.
        applyStyleToSelected(feature.placeId);
        // Add the info window.
        let content = '<span style="font-size:small">Display name: ' + feature.displayName +
            '<br/> Place ID: ' + feature.placeId +
            '<br/> Feature type: ' + feature.featureType +
            '</span>';
        updateInfoWindow(content, event.latLng);
    }

    JavaScript

    // Handle the click event.
    function handlePlaceClick(event) {
      let feature = event.features[0];
    
      console.log(event);
      if (!feature.placeId) return;
    
      // Apply the style to the feature layer.
      applyStyleToSelected(feature.placeId);
    
      // Add the info window.
      let content =
        '<span style="font-size:small">Display name: ' +
        feature.displayName +
        "<br/> Place ID: " +
        feature.placeId +
        "<br/> Feature type: " +
        feature.featureType +
        "</span>";
    
      updateInfoWindow(content, event.latLng);
    }
    

Complete example code

TypeScript

let map: google.maps.Map;
let featureLayer;
let infoWindow: google.maps.InfoWindow;
function initMap() {
    map = new google.maps.Map(document.getElementById('map') as HTMLElement, {
        center: { lat: 39.23, lng: -105.73 }, // Park County, CO 
        zoom: 8,
        // In the cloud console, configure this Map ID with a style that enables the
        // "Administrative Area Level 2" Data Driven Styling type.
        mapId: 'a3efe1c035bad51b', // <YOUR_MAP_ID_HERE>,
    });
    // Add the feature layer.
    //@ts-ignore
    featureLayer = map.getFeatureLayer('ADMINISTRATIVE_AREA_LEVEL_2');
    // Add the event listener for the feature layer.
    featureLayer.addListener('click', handlePlaceClick);
    infoWindow = new google.maps.InfoWindow({});
    // Apply style on load, to enable clicking.
    applyStyleToSelected();
}
// Handle the click event.
function handlePlaceClick(event) {
    let feature = event.features[0];
    console.log(event);
    if (!feature.placeId) return;
    // Apply the style to the feature layer.
    applyStyleToSelected(feature.placeId);
    // Add the info window.
    let content = '<span style="font-size:small">Display name: ' + feature.displayName +
        '<br/> Place ID: ' + feature.placeId +
        '<br/> Feature type: ' + feature.featureType +
        '</span>';
    updateInfoWindow(content, event.latLng);
}
// Stroke and fill with minimum opacity value.
//@ts-ignore
const styleDefault: google.maps.FeatureStyleOptions = {
    strokeColor: '#810FCB',
    strokeOpacity: 1.0,
    strokeWeight: 2.0,
    fillColor: 'white',
    fillOpacity: 0.1 // Polygons must be visible to receive click events.
};

// Style for the clicked Administrative Area Level 2 polygon.
//@ts-ignore
const styleClicked: google.maps.FeatureStyleOptions = {
    ...styleDefault,
    fillColor: '#810FCB',
    fillOpacity: 0.5
};
// Apply styles to the map.
function applyStyleToSelected(placeid?) {
    // Apply styles to the feature layer.
    featureLayer.style = (options) => {
        // Style fill and stroke for a polygon.
        if (placeid && options.feature.placeId == placeid) {
            return styleClicked;
        }
        // Style only the stroke for the entire feature type.
        return styleDefault;
    };
}
// Helper function to create an info window.
function updateInfoWindow(content, center) {
    infoWindow.setContent(content);
    infoWindow.setPosition(center);
    infoWindow.open({
        map,
        shouldFocus: false,
    });
}
declare global {
    interface Window {
        initMap: () => void;
    }
}
window.initMap = initMap;

JavaScript

let map;
let featureLayer;
let infoWindow;

function initMap() {
  map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 39.23, lng: -105.73 },
    zoom: 8,
    // In the cloud console, configure this Map ID with a style that enables the
    // "Administrative Area Level 2" Data Driven Styling type.
    mapId: "a3efe1c035bad51b", // <YOUR_MAP_ID_HERE>,
  });
  // Add the feature layer.
  //@ts-ignore
  featureLayer = map.getFeatureLayer("ADMINISTRATIVE_AREA_LEVEL_2");
  // Add the event listener for the feature layer.
  featureLayer.addListener("click", handlePlaceClick);
  infoWindow = new google.maps.InfoWindow({});
  // Apply style on load, to enable clicking.
  applyStyleToSelected();
}

// Handle the click event.
function handlePlaceClick(event) {
  let feature = event.features[0];

  console.log(event);
  if (!feature.placeId) return;

  // Apply the style to the feature layer.
  applyStyleToSelected(feature.placeId);

  // Add the info window.
  let content =
    '<span style="font-size:small">Display name: ' +
    feature.displayName +
    "<br/> Place ID: " +
    feature.placeId +
    "<br/> Feature type: " +
    feature.featureType +
    "</span>";

  updateInfoWindow(content, event.latLng);
}

// Stroke and fill with minimum opacity value.
//@ts-ignore
const styleDefault = {
  strokeColor: "#810FCB",
  strokeOpacity: 1.0,
  strokeWeight: 2.0,
  fillColor: "white",
  fillOpacity: 0.1, // Polygons must be visible to receive click events.
};
// Style for the clicked Administrative Area Level 2 polygon.
//@ts-ignore
const styleClicked = {
  ...styleDefault,
  fillColor: "#810FCB",
  fillOpacity: 0.5,
};

// Apply styles to the map.
function applyStyleToSelected(placeid) {
  // Apply styles to the feature layer.
  featureLayer.style = (options) => {
    // Style fill and stroke for a polygon.
    if (placeid && options.feature.placeId == placeid) {
      return styleClicked;
    }
    // Style only the stroke for the entire feature type.
    return styleDefault;
  };
}

// Helper function to create an info window.
function updateInfoWindow(content, center) {
  infoWindow.setContent(content);
  infoWindow.setPosition(center);
  infoWindow.open({
    map,
    shouldFocus: false,
  });
}

window.initMap = initMap;

CSS

/* 
 * 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;
}

HTML

<html>
  <head>
    <title>Handle Region Boundary Click Event</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="map"></div>

    <!-- 
     The `defer` attribute causes the callback to execute after the full HTML
     document has been parsed. For non-blocking uses, avoiding race conditions,
     and consistent behavior across browsers, consider loading using Promises
     with https://www.npmjs.com/package/@googlemaps/js-api-loader.
    -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=beta"
      defer
    ></script>
  </body>
</html>

Try Sample

Learn more about events