-4

Does anyone have any suggestions on how to automatically close info windows when another marker is clicked? Currently the user has to manually close the info box when clicking another marker. I was hoping there was a method I could easily incorporate into my code. It looks like I'm creating separate infoboxes for each marker. When we go to scale this project up we are going to have 10k plus markers that will be separated by different categories.

I read about the suggestion of creating one infoWindow and then changing the contents, but if I understand my code correctly I'm creating individual infoboxes for each marker since they are coming out of the XML file. How could I incorporate this technique with my current code?

You can find a live example of my project here: http://www.officerage.com/maps/ Here is my example code:

 <!DOCTYPE html>
<html lang="en">
<head>

<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <meta charset="UTF-8">
    <title>A Basic Map</title>
    <style>
        #map {
            height: 100%;
        }
        /* Optional: Makes the sample page fill the window. */
        html, body {
            height: 100%;
            margin: 0;
            padding: 0;
        }
    </style>

    </head>

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

    function infoCallback(infowindow, marker) {
    return function() { infowindow.open(map, marker); }; 
}
    function initMap() {
        var mapOptions = {
            zoom: 3,
            center: new google.maps.LatLng(37.5, -122),
            mapTypeId: 'roadmap'
        };


        var map = new google.maps.Map(document.getElementById('map'), mapOptions);





        $.ajax({
    type: "GET",
    async: true,
    url: "testxml.xml",
    dataType: "xml",
    success:
    function (xml) {


    var places = xml.documentElement.getElementsByTagName("place");


    for (var i = 0; i < places.length; i++) {
    var lat = places[i].getAttribute('latitude');
    var long = places[i].getAttribute('longitude');
    var category = places[i].getAttribute('Info');
    var latLng = new google.maps.LatLng(lat, long);

    var marker = new google.maps.Marker({
        position:  latLng,
        map: map,
        category:places[i].info,
        label:places[i].name

    });

    var infowindow = new google.maps.InfoWindow({
    content:category});
    google.maps.event.addListener(marker, 'click', infoCallback(infowindow,marker));


}



    }



}


);

    }
    </script>


<script async defer
        src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCz_-TAwsP-dL_dsEkmz8sGEU1hyPYKHik&callback=initMap">
</script>
</body>
</html>
geocodezip
  • 158,664
  • 13
  • 220
  • 245
H H
  • 1
  • 1
  • 4
    possible duplicate of [Google Map V3 - Allow only one infobox to be displayed at a time](https://stackoverflow.com/questions/10908132/google-map-v3-allow-only-one-infobox-to-be-displayed-at-a-time) – geocodezip Oct 09 '18 at 21:12
  • 4
    possible duplicate of [Google maps: infowindow is not closing](https://stackoverflow.com/questions/12953332/google-maps-infowindow-is-not-closing) – geocodezip Oct 09 '18 at 21:13
  • 4
    possible duplicate of [Google Maps API - only one infowindow open at once](https://stackoverflow.com/questions/33713676/google-maps-api-only-one-infowindow-open-at-once) – geocodezip Oct 09 '18 at 21:14
  • 3
    Possible duplicate of [Google Maps: Auto close open InfoWindows?](https://stackoverflow.com/questions/2223574/google-maps-auto-close-open-infowindows) – Dženis H. Oct 10 '18 at 00:16
  • 2
    Possible duplicate of [Google Maps API - only one infowindow open at once](https://stackoverflow.com/questions/33713676/google-maps-api-only-one-infowindow-open-at-once) – Marcello B. Oct 10 '18 at 00:58
  • Possible duplicate of [Google Map V3 - Allow only one infobox to be displayed at a time](https://stackoverflow.com/questions/10908132/google-map-v3-allow-only-one-infobox-to-be-displayed-at-a-time) – MrUpsidown Oct 10 '18 at 10:28

1 Answers1

0

To modify your code to use a single infowindow, moving it to the clicked marker and updating its content to reflect the data for that marker, change your infoCallback to take the content as the first argument:

function infoCallback(content, marker) {
  return function() {
    infowindow.setContent(content);
    infowindow.open(map, marker);
  };
}
var infowindow;
function initMap() {
  infowindow = new google.maps.InfoWindow();
  // ...

Then use it like this:

var places = xml.documentElement.getElementsByTagName("place");
for (var i = 0; i < places.length; i++) {
  var lat = places[i].getAttribute('latitude');
  var long = places[i].getAttribute('longitude');
  var category = places[i].getAttribute('Info');
  var latLng = new google.maps.LatLng(lat, long);

  var marker = new google.maps.Marker({
    position: latLng,
    map: map,
    category: places[i].info,
    label: places[i].name
  });
  google.maps.event.addListener(marker, 'click', infoCallback(category, marker));
}

proof of concept fiddle

code snippet:

html,
body,
#map {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<div id="map"></div>
<script>
  function infoCallback(content, marker) {
    return function() {
      infowindow.setContent(content);
      infowindow.open(map, marker);
    };
  }
  var infowindow;

  function initMap() {
    infowindow = new google.maps.InfoWindow();
    var mapOptions = {
      zoom: 3,
      center: new google.maps.LatLng(37.5, -122),
      mapTypeId: 'roadmap'
    };
    var map = new google.maps.Map(document.getElementById('map'), mapOptions);
    var bounds = new google.maps.LatLngBounds();
    var xml = parseXml(xmlStr);
    var places = xml.documentElement.getElementsByTagName("place");
    for (var i = 0; i < places.length; i++) {
      var lat = places[i].getAttribute('latitude');
      var long = places[i].getAttribute('longitude');
      var category = places[i].getAttribute('Info');
      var latLng = new google.maps.LatLng(lat, long);

      var marker = new google.maps.Marker({
        position: latLng,
        map: map,
        category: places[i].info,
        label: places[i].name
      });
      google.maps.event.addListener(marker, 'click', infoCallback(category, marker));
      bounds.extend(marker.getPosition());
    }
    map.fitBounds(bounds);
  }

  var xmlStr = '<places><place latitude="37.4529598" longitude="-122.1817252" Info="Menlo Park, CA"/><place latitude="37.43355" longitude="-122.2030209" Info="West Menlo Park, CA 94025"/><place latitude="37.424106" longitude="-122.1660756" Info="Stanford, CA"/></places>';

  function parseXml(str) {
    if (window.ActiveXObject) {
      var doc = new ActiveXObject('MicrosoftXMLDOM');
      doc.loadXML(str);
      return doc;
    } else if (window.DOMParser) {
      return (new DOMParser).parseFromString(str, 'text/xml');
    }
  };
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap"></script>
geocodezip
  • 158,664
  • 13
  • 220
  • 245