Search code examples
javascriptgoogle-mapsgoogle-maps-api-3

Google Maps API - ControlPosition with Infowindow


Is it possible to use something similar to maps.controls[google.maps.ControlPosition.TOP_CENTER].push(infoWindow) to have a control window show in the top center of the map?

I have a map with polygons to enable mouseover events. I am trying to also have the infowindow of the polgyon popup in the top-center of the map and disappear on mouseout (I am hoping to avoid using CSS because I would like this to be as pure Google API as possible but I understand that's impossible sometimes).

Polygons are great but the Infowindow keeps displaying at the top left of the screen. Any help would be appreciated! Thank you!

Currently I am getting this error message when I try to mouseover: "Uncaught TypeError: Cannot read property 'zIndex' of undefined"

JS of the part used to create the polygons and add listeners:

function createPolygon(city, url, name){
var infoWindow  = new google.maps.InfoWindow();
    google.maps.event.addListener(city, 'mouseover', function() {

      this.setOptions(
        {
          fillOpacity: 0.4,
        }
      );

      infoWindow.setContent(name);
      console.log(infoWindow);
      console.log("City: " + city + " URL: " + url + " Name: " + name);
      infoWindow.open(map, this);
        map.controls[google.maps.ControlPosition.TOP_CENTER].push(infoWindow);

      console.log("awww yis");
    });

    google.maps.event.addListener(city, 'mouseout', function() {
      this.setOptions(
        {
          fillOpacity: 0.1,
        }
      );
      infoWindow.close();
      console.log("awww no");
    });

    google.maps.event.addListener(city, 'click', function(){
      console.log("aaaawww yis");
      window.location = url;
    });
  }

Solution

  • If you want to create a control on the map rather than the infowindow, you can do this (you could also put the content in some other fixed div on your page outside of the map):

    function createPolygon(city, url, name) {
      var infoWindow = new google.maps.InfoWindow();
      var bounds = new google.maps.LatLngBounds();
      for (var i = 0; i < city.getPath().getLength(); i++) {
        bounds.extend(city.getPath().getAt(i));
      }
      var center = bounds.getCenter();
      google.maps.event.addListener(city, 'mouseover', function() {
        this.setOptions({
          fillOpacity: 0.4,
        });
        var textonome = document.createElement('DIV');
        textonome.className = "caixabranca";
        textonome.innerHTML = "<big><big><b><center>" + name + "</center></big></big></b><br>" + url;
        map.controls[google.maps.ControlPosition.TOP_CENTER].push(textonome);
    
        console.log("City: " + city + " URL: " + url + " Name: " + name);
        console.log("awww yis");
      });
    
      google.maps.event.addListener(city, 'mouseout', function() {
        this.setOptions({
          fillOpacity: 0.1,
        });
        map.controls[google.maps.ControlPosition.TOP_CENTER].clear();
        console.log("awww no");
      });
    
      google.maps.event.addListener(city, 'click', function() {
        console.log("aaaawww yis");
        window.location = url;
      });
    }
    

    working code snippet:

    var map;
    
    function initialize() {
      var mapOptions = {
        zoom: 5,
        center: new google.maps.LatLng(40, -117),
        mapTypeId: google.maps.MapTypeId.ROADMAP
      };
    
      map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
    
      var arr = new Array();
      var polygons = [];
      var bounds = new google.maps.LatLngBounds();
    
      // downloadUrl("subdivision-coordinates.php", function(data) {
      var xml = xmlParse(xmlString);
      var subdivision = xml.getElementsByTagName("subdivision");
      // alert(subdivision.length);
      for (var i = 0; i < subdivision.length; i++) {
        arr = [];
        var coordinates = xml.documentElement.getElementsByTagName("subdivision")[i].getElementsByTagName("coord");
        for (var j = 0; j < coordinates.length; j++) {
          arr.push(new google.maps.LatLng(
            parseFloat(coordinates[j].getAttribute("lat")),
            parseFloat(coordinates[j].getAttribute("lng"))
          ));
    
          bounds.extend(arr[arr.length - 1])
        }
        polygons.push(new google.maps.Polygon({
          paths: arr,
          strokeColor: '#FF0000',
          strokeOpacity: 0.8,
          strokeWeight: 2,
          fillColor: '#FF0000',
          fillOpacity: 0.1
        }));
        polygons[polygons.length - 1].setMap(map);
        createPolygon(polygons[polygons.length - 1], "", "polygon " + polygons.length);
      }
      // });
      map.fitBounds(bounds);
    }
    
    function createPolygon(city, url, name) {
      var infoWindow = new google.maps.InfoWindow();
      var bounds = new google.maps.LatLngBounds();
      for (var i = 0; i < city.getPath().getLength(); i++) {
        bounds.extend(city.getPath().getAt(i));
      }
      var center = bounds.getCenter();
      google.maps.event.addListener(city, 'mouseover', function() {
        this.setOptions({
          fillOpacity: 0.4,
        });
        var textonome = document.createElement('DIV');
        textonome.className = "caixabranca";
        textonome.innerHTML = "<big><big><b><center>" + name + "</center></big></big></b><br>" + url;
        map.controls[google.maps.ControlPosition.TOP_CENTER].push(textonome);
    
        console.log(infoWindow);
        console.log("City: " + city + " URL: " + url + " Name: " + name);
        console.log("awww yis");
      });
    
      google.maps.event.addListener(city, 'mouseout', function() {
        this.setOptions({
          fillOpacity: 0.1,
        });
        map.controls[google.maps.ControlPosition.TOP_CENTER].clear();
        console.log("awww no");
      });
    
      google.maps.event.addListener(city, 'click', function() {
        console.log("aaaawww yis");
        window.location = url;
      });
    }
    
    var xmlString = '<subdivisions><subdivision name="Auburn Hills"><coord lat="39.00748" lng="-92.323222"/><coord lat="39.000843" lng="-92.323523"/><coord lat="39.000509" lng="-92.311592"/><coord lat="39.007513" lng="-92.311378"/><coord lat="39.00748" lng="-92.323222"/></subdivision><subdivision name="Vanderveen"><coord lat="38.994206" lng="-92.350645"/><coord lat="38.985033" lng="-92.351074"/><coord lat="38.984699" lng="-92.343092"/><coord lat="38.981163" lng="-92.342234"/><coord lat="38.984663" lng="-92.3335"/><coord lat="38.993472" lng="-92.333179"/><coord lat="38.994206" lng="-92.350645"/></subdivision><subdivisions>';
    
    /**
     * Parses the given XML string and returns the parsed document in a
     * DOM data structure. This function will return an empty DOM node if
     * XML parsing is not supported in this browser.
     * @param {string} str XML string.
     * @return {Element|Document} DOM.
     */
    function xmlParse(str) {
      if (typeof ActiveXObject != 'undefined' && typeof GetObject != 'undefined') {
        var doc = new ActiveXObject('Microsoft.XMLDOM');
        doc.loadXML(str);
        return doc;
      }
    
      if (typeof DOMParser != 'undefined') {
        return (new DOMParser()).parseFromString(str, 'text/xml');
      }
    
      return createElement('div', null);
    }
    
    google.maps.event.addDomListener(window, 'load', initialize);
    #map-canvas,
    body,
    html {
      height: 100%;
      width: 100%;
    }
    #infotop {
      text-align: center;
      height: 50px;
      /*n usado*/
    }
    #infocontent {
      margin: 30px;
      text-align: justify;
      height: 84%;
    }
    .caixabranca {
        border:solid 1px #cccccc;
        background-color:#FFFFFF;
        font-size:11px;
        font-family:verdana,"sans-serif";
        color:#000;
        padding:5px;
        }
    <script src="http://maps.google.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
    <div id="map-canvas"></div>