-1

Is a closeclick event triggered when a google map POI information window is closed?

If so, how do I listen for it?

If not, is there are way to learn when a POI information window is closed?

geocodezip
  • 158,664
  • 13
  • 220
  • 245
RichardZ
  • 345
  • 2
  • 6
  • 18

1 Answers1

-1

There is no closeclick event on the "native" POI infowindow.

Related question: click event listener on styled map icons and labels

You can create your own InfoWindow when those icons are clicked and add the closeclick listener to those.

Note: that will require a call to the places service to get the information to display in the InfoWindow (and deciding what you want to display and how you want to format the information displayed).

Proof of concept fiddle

code snippet:

let map;

function initMap() {
  map = new google.maps.Map(document.getElementById("map"), {
    // New York, NY, USA (40.7127753, -74.0059728)
    center: {
      lat: 40.7127753,
      lng: -74.0059728
    },
    zoom: 14,
  });
  const infowindow = new google.maps.InfoWindow();
  google.maps.event.addListener(infowindow, 'closeclick', function() {
    alert("closeclick");
  });
  google.maps.event.addListener(map, 'click', function(e) {
    if (e.placeId) {
      // Calling e.stop() on the event prevents the default info window from
      // showing.
      // If you call stop here when there is no placeId you will prevent some
      // other map click event handlers from receiving the event.
      e.stop();
      console.log(e.placeId);
      const request = {
        placeId: e.placeId,
        fields: ["name", "formatted_address", "place_id", "geometry"],
      };
      const service = new google.maps.places.PlacesService(map);
      service.getDetails(request, (place, status) => {
        if (status === google.maps.places.PlacesServiceStatus.OK) {
          infowindow.setContent(
            "<div><strong>" +
            place.name +
            "</strong><br>" +
            "Place ID: " +
            place.place_id +
            "<br>" +
            place.formatted_address +
            "</div>"
          );
          infowindow.setPosition(place.geometry.location);
          infowindow.setOptions({
            pixelOffset: new google.maps.Size(0, -10)
          })
          infowindow.open(map);
        }
      });
    }
  })
}
/* 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;
}
<!DOCTYPE html>
<html>
  <head>
    <title>Simple Map</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=places&v=weekly"
      defer
    ></script>
    <!-- jsFiddle will insert css and js -->
  </head>
  <body>
    <div id="map"></div>
  </body>
</html>

second (more dangerous) option

A more dangerous option (depends on overriding the .setContent method of the InfoWindow as described in the related question: click event listener on styled map icons and labels).

  1. Overwrite either the .setContent or .open method on the InfoWindow class
  2. capture a reference to the infowindow that is opened when the IconMouseEvent fires
  3. add a closeclick listener on the captured InfoWindow
  4. remove the event listener function and replace the overridden method with the original

Note: this will only capture the InfoWindow closeclick that is fired when the 'x' is clicked on the InfoWindow, not when it is closed because another InfoWindow opens.

Code:

  var iconIw;
  //store the original setContent-function
  var fx = google.maps.InfoWindow.prototype.setContent;
  var listener = google.maps.event.addListener(map, 'click', function(e) {
    // if infowindow for Icon, override setContent, add closeclick listener, replace setContent
    if (e.placeId) {
      console.log(e.placeId);
      //override the built-in setContent-method
      google.maps.InfoWindow.prototype.setContent = function(content) {
        iconIw = this;
        google.maps.event.addListener(iconIw, 'closeclick', function() {
          alert("closeclick");
        });
        listener.remove();
        //run the original setContent-method
        fx.apply(this, arguments);
        google.maps.InfoWindow.prototype.setContent = fx;
      };
    }
  })

proof of concept fiddle

code snippet:

let map;

function initMap() {
  map = new google.maps.Map(document.getElementById("map"), {
    // New York, NY, USA (40.7127753, -74.0059728)
    center: {
      lat: 40.7127753,
      lng: -74.0059728
    },
    zoom: 14,
  });
  var marker = new google.maps.Marker({
    position: map.getCenter(),
    map: map
  });
  var infowindow = new google.maps.InfoWindow();
  marker.addListener('click', function(e) {
    infowindow.setContent("<b>Test</b>");
    infowindow.open(map,marker);
  })
  var iconIw;
  //store the original setContent-function
  var fx = google.maps.InfoWindow.prototype.setContent;
  var listener = google.maps.event.addListener(map, 'click', function(e) {
    // if infowindow for Icon, override setContent, add closeclick listener, replace setContent
    if (e.placeId) {
      console.log(e.placeId);
      //override the built-in setContent-method
      google.maps.InfoWindow.prototype.setContent = function(content) {
        iconIw = this;
        google.maps.event.addListener(iconIw, 'closeclick', function() {
          alert("closeclick");
        });
        listener.remove();
        //run the original setContent-method
        fx.apply(this, arguments);
        google.maps.InfoWindow.prototype.setContent = fx;
      };
    }
  })
}
/* 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;
}
<!DOCTYPE html>
<html>
  <head>
    <title>Simple Map</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=places&v=weekly"
      defer
    ></script>
    <!-- jsFiddle will insert css and js -->
  </head>
  <body>
    <div id="map"></div>
  </body>
</html>
geocodezip
  • 158,664
  • 13
  • 220
  • 245