0

I'm implementing an application where, using a very large display, the user can select one of several markers that appear on the screen and its information is printed on an infowindow. This selection can happen using a Microsoft Surface on one use case. I'm running into the following problem, though.

This is what happens when the user touches the marker

And this is what happens when the user touches the location itself, not the marker

I overrode the behavior of the marker like this

google.maps.event.addListener(marker, 'click', function () {
    requestMarkerDetails(this);
    infoWindow.open(map, this);
});

And

function requestMarkerDetails(mkr) {
    var details_service = new google.maps.places.PlacesService(map);
    details_service.getDetails({
        placeId: mkr.place.placeId
    }, function (result, status) {
        if (status != google.maps.places.PlacesServiceStatus.OK) {
            alert(status);
            return;
        }
        var contentStr = '<div id="bodyContent">' + '<font size = "12">' +
                '<p>' + result.name + "<br>" + result.formatted_address + "<br>" +
                result.formatted_phone_number + '</p>' + '</div>';

        infoWindow.setContent(contentStr);
    });
}

So basically what I need is to either make it so tapping the icon itself, not the marker does nothing, or I need to make it so tapping the icon brings up the larger infowindow, rather than the default one.

2 Answers2

2

So, I did some digging, thanks to Emmanuel, who linked me to this question, which eventually led me to this issue. At first it seemed hopeless, because google had marked it as "won't solve". But I kept reading on, and they did eventually solve it, by [edit: allowing us to set] clickableIcons tofalse, on the map.

Of course, what I hoped to do was actually change the infoWindow so it would show the larger window I made, and this only disables clicking on them.

Community
  • 1
  • 1
1

Here is my updated answer.

So I have 5 markers, of Railway stations. Those are also default markers on the map. If you click on a default marker, the script will see if the marker is close to a custom marker. If it is, the default infoWindow will be closed, and the custom infoWindow will appear instead.

So try clicking on any default marker, nothing unusual happens. Now click on one of the default (blue train icon) station marker underneath a custom marker, see what happens

<!DOCTYPE html>
<html>
  <head>
    <title>Simple Map</title>
    <meta name="viewport" content="initial-scale=1.0">
    <meta charset="utf-8">
    <style>
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
      #map {
        height: 90%;
      }
    </style>
  </head>
  <body>
    <div id="map"></div>
    <script>
      var map;
      // DATA
      var stationsData =[ 
        {"name": "South", "position": [50.83644109999999,4.334787799999958], "content": "Brussels South Station"},
        {"name": "Chapelle", "position": [50.84125179999999,4.348515700000007], "content": "Brussels Chapelle Station"},
        {"name": "Central", "position": [50.8454658,4.3571134999999686], "content": "Brussels Central Station"},
        {"name": "Congres", "position": [50.85212929999999,4.361864999999966], "content": "Brussels Congres Station"},
        {"name": "North", "position": [50.8605262,4.36178730000006], "content": "Brussels North Station"}
      ];
      var stationsMarkers = [];
      var infowindow;

      function initMap() {
        map = new google.maps.Map(document.getElementById('map'), {
          center: new google.maps.LatLng(50.846624929308994,4.352617979049667),  // Brussels
          zoom: 14
        });
        // add the markers
        for(var i in stationsData) {
          var marker = new google.maps.Marker({
            position: new google.maps.LatLng(stationsData[i].position[0], stationsData[i].position[1]),
            title: stationsData[i].name,
            map: map
          });
          // store this object in stationsMarkers
          stationsMarkers.push(marker);
          // add a click event
          google.maps.event.addListener(marker, 'click', function (e) { 
            // first we need to know whitch marker got clicked on
            var index = stationsMarkers.indexOf(this);
            setInfoWindow(index);

          });
        }

        initDetectClick(function(position, parentOfInfowindow) {
          console.log(position.lat() +','+ position.lng());

          if(parentOfInfowindow) {
              // We will search if this position is close to one of our markers.  Let's say within 20 meter
              // notice: we need &libraries=geometry in the script url, see below
              for(var i in stationsMarkers) {
                var distance = google.maps.geometry.spherical.computeDistanceBetween (position, stationsMarkers[i].getPosition());
                if(distance < 20) {
                  // open the correct infoWindow
                  setInfoWindow(i);
                  // we will induce a click on the close button of the default infowindow
                  // This way the infowindow is visible a few milliseconds, then disappears, every click on a POI
                  parentOfInfowindow.find('div>img').click();
                  break;
                }
              }
          }
        });
      }
      function setInfoWindow(index) {
        // if needed, close the previous infoWindow
        if(infowindow) {
          infowindow.setMap(null);
        }
        // create the infoWindow
        infowindow = new google.maps.InfoWindow({
          content: stationsData[index].content,
          position: new google.maps.LatLng(stationsData[index].position[0], stationsData[index].position[1]),
          map: map
        });
      }
    </script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script src="https://maps.googleapis.com/maps/api/js?callback=initMap&libraries=geometry" async defer></script>
    <script>
    var parentOfInfowindow;
    var POI_hidden = false;
    function initDetectClick(callback) {
      //https://stackoverflow.com/questions/8902829/disable-click-behavior-of-poi-markers-in-google-maps-v3-6
      //keep a reference to the original setPosition-function
      var fx = google.maps.InfoWindow.prototype.setPosition;
      //override the built-in setPosition-method
      google.maps.InfoWindow.prototype.setPosition = function () {
        //this property isn't documented, but as it seems
        //it's only defined for InfoWindows opened on POI's
        if (this.logAsInternal) {
          if (this.getPosition()) {
            console.log(this.getPosition());
            google.maps.event.trigger(map, 'click', {latLng: this.getPosition()});
          }
          else{
            google.maps.event.addListener(this, 'map_changed', function (e) { // Once
              console.log(this.getPosition());
              google.maps.event.trigger(map, 'click', {latLng: this.getPosition()});
                // //the infoWindow will be opened, usually after a click on a POI
                //trigger the click
                var removeInfoWindow = null;
                var self = this;
                // let's limit our 
                //console.log(jj);
                if(POI_hidden) {
                  callback(self.getPosition()); 
                }
                else {
                  removeInfoWindow = setInterval(function() {
                    if($('.gm-style-iw').parent().length) {
                      //console.log('clicked on POI @ ' + self.getPosition().lat() +''+ self.getPosition().lng()); // +e.latLng.toString()
                      parentOfInfowindow = $('.gm-style-iw').parent();
                      clearInterval(removeInfoWindow);
                      // now we call the callback
                      callback(self.getPosition(), parentOfInfowindow); 
                    };
                  }, 5);
                }
            });
          };
        }
        //call the original setPosition-method
        fx.apply(this, arguments);
      };

      google.maps.event.addListener(map,'click',function(e){
        //console.log('clicked on map @'+e.latLng.toString());
        callback(e.latLng); 
      });
    }
    </script>
  </body>
</html>

EDIT: original answer

I kind of need this myself.

I combined the script of Tun Lin Thu, shown here: Disable click behavior of POI markers in Google Maps JS API

I put it in a function, changed a few things ...

So, with this callback (starting on line 27) you detect the clicks, either on the map, or on a POI (point of interest).

You could then see if any marker is close to that location, given in the callback, ... it's getting a little late for me to finish this

<!DOCTYPE html>
<html>
  <head>
    <title>Simple Map</title>
    <meta name="viewport" content="initial-scale=1.0">
    <meta charset="utf-8">
    <style>
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
      #map {
        height: 90%;
      }
    </style>
  </head>
  <body>
    <div id="map"></div>
    <script>
      var map;
      function initMap() {
        map = new google.maps.Map(document.getElementById('map'), {
          center: new google.maps.LatLng(50.846624929308994,4.352617979049667),  // Brussels
          zoom: 14
        });
        initDetectClick(function(position, parentOfInfowindow) {
          console.log(position.lat() +','+ position.lng());

          if(parentOfInfowindow) {
          // two choises.  just comment out the solution you don't want.

              // we will hide the infowindow, once and for all
              // but then you will not detect further clicks on the POI
            //parentOfInfowindow.hide();

              // we will induce a click on the close button of the infowindow
              // This way the infowindow is visible a few milliseconds, then disappears, every click on a POI
            parentOfInfowindow.find('div>img').click();
          }
        });
      }
    </script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script src="https://maps.googleapis.com/maps/api/js?callback=initMap"
    async defer></script>
    <script>
    var parentOfInfowindow;
    var POI_hidden = false;
    function initDetectClick(callback) {
      //https://stackoverflow.com/questions/8902829/disable-click-behavior-of-poi-markers-in-google-maps-v3-6
      //keep a reference to the original setPosition-function
      var fx = google.maps.InfoWindow.prototype.setPosition;
      //override the built-in setPosition-method
      google.maps.InfoWindow.prototype.setPosition = function () {
        //this property isn't documented, but as it seems
        //it's only defined for InfoWindows opened on POI's
        if (this.logAsInternal) {
          if (this.getPosition()) {
            console.log(this.getPosition());
            google.maps.event.trigger(map, 'click', {latLng: this.getPosition()});
          }
          else{
            google.maps.event.addListener(this, 'map_changed', function (e) { // Once
              console.log(this.getPosition());
              google.maps.event.trigger(map, 'click', {latLng: this.getPosition()});
                // //the infoWindow will be opened, usually after a click on a POI
                //trigger the click
                var removeInfoWindow = null;
                var self = this;
                // let's limit our 
                //console.log(jj);
                if(POI_hidden) {
                  callback(self.getPosition()); 
                }
                else {
                  removeInfoWindow = setInterval(function() {
                    if($('.gm-style-iw').parent().length) {
                      // POI_hidden = true;
                      //alert($('.gm-style-iw').parent().length);
                      //console.log('clicked on POI @ ' + self.getPosition().lat() +''+ self.getPosition().lng()); // +e.latLng.toString()
                      parentOfInfowindow = $('.gm-style-iw').parent();
                      //$('.gm-style-iw').parent().hide();
                      //$('.gm-style-iw').parent().find('div>img').click();
                      clearInterval(removeInfoWindow);
                      // now we call the callback
                      callback(self.getPosition(), parentOfInfowindow); 
                    };
                  }, 5);
                }
            });
          };
        }
        //call the original setPosition-method
        fx.apply(this, arguments);
      };

      google.maps.event.addListener(map,'click',function(e){
        //alert('clicked @'+e.latLng.toString())
        //console.log('clicked on map @'+e.latLng.toString());
        //infowindow.setMap(null);
        callback(e.latLng); 
      });
    }
    </script>
  </body>
</html>
Community
  • 1
  • 1
Emmanuel Delay
  • 3,619
  • 1
  • 11
  • 17