Codeblooded Saiyan
Codeblooded Saiyan

Reputation: 1497

Dynamic Google Maps Polygon - How can I set to editable when clicked

I've been successfully created dynamic polygons on google maps given the sets of latlngs.

  <script>
  map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: 25.774252, lng: -80.190262},
    zoom: 2
  });

  var latlngs = [
    [
      {lat:25.774252,lng:-80.190262},
      {lat:18.466465,lng:-66.118292},
      {lat:32.321384,lng:-64.757370},
      {lat:25.774252,lng:-80.190262},
    ],
    [
      {lat:59.677361,lng:-2.469846},
      {lat:59.299717,lng:-6.314917},
      {lat:57.877247,lng:-9.314917},
      {lat:54.428078,lng:-11.638861},
      {lat:51.784554,lng:-11.702241}
    ]
  ];
  for(var y=0; y<latlngs.length; y++) {

    var sample=[];

    for(var z=0; z<latlngs[y].length; z++) {
      sample.push(new google.maps.LatLng(parseFloat(latlngs[y][z].lat), parseFloat(latlngs[y][z].lng)));
    }

    var boundary = new google.maps.Polygon({
      paths: sample,
      strokeColor: 'black',
      strokeWeight: 2,
      fillColor: 'black',
      fillOpacity: 0.2,
      zIndex: 1,
      content: 'AREA '+y
    });
    boundary.setMap(map);

    var infoWindow = new google.maps.InfoWindow;
    boundary.addListener('click', function(event){
      boundary.setEditable(true); // <- HERE IS THE PROBLEM
      infoWindow.setContent(this.content);
      infoWindow.setPosition(event.latLng);
      infoWindow.open(map);
    });
  }
</script>

The problem of the above codes is that, only the last polygon will set as editable even if I've clicked the first one.

What should be the code so that, only the polygon that was clicked will set to editable?

Upvotes: 1

Views: 3746

Answers (1)

geocodezip
geocodezip

Reputation: 161334

Common problem usually seen with the association of InfoWindows with Markers that are created in a loop (related question demonstrating that: Google Maps JS API v3 - Simple Multiple Marker Example). The last element created ends up with the listener. One way to solve it is by using function closure to associate the listener with each individual polygon:

  1. make a "createEditablePolygon" function to hold closure on the polygon/listener:
function createEditablePolygon(latlngs, index) {
  var sample = [];
  for (var z = 0; z < latlngs.length; z++) {
    sample.push(new google.maps.LatLng(parseFloat(latlngs[z].lat), parseFloat(latlngs[z].lng)));
  }

  var boundary = new google.maps.Polygon({
    paths: sample,
    strokeColor: 'black',
    strokeWeight: 2,
    fillColor: 'black',
    fillOpacity: 0.2,
    zIndex: 1,
    content: 'AREA ' + index
  });
  boundary.setMap(map);

  var infoWindow = new google.maps.InfoWindow;
  boundary.addListener('click', function(event) {
    // toggle editable state
    boundary.setEditable(!boundary.getEditable());
    infoWindow.setContent(this.content);
    infoWindow.setPosition(event.latLng);
    infoWindow.open(map);
  });
}
  1. use that in the loop:
for (var y = 0; y < latlngs.length; y++) {
  createEditablePolygon(latlngs[y], y);
}

proof of concept fiddle

code snippet:

var map;

function initialize() {
  map = new google.maps.Map(document.getElementById('map'), {
    center: {
      lat: 25.774252,
      lng: -80.190262
    },
    zoom: 2
  });

  for (var y = 0; y < latlngs.length; y++) {
    createEditablePolygon(latlngs[y], y);
  }
}

function createEditablePolygon(latlngs, index) {
  var sample = [];
  for (var z = 0; z < latlngs.length; z++) {
    sample.push(new google.maps.LatLng(parseFloat(latlngs[z].lat), parseFloat(latlngs[z].lng)));
  }

  var boundary = new google.maps.Polygon({
    paths: sample,
    strokeColor: 'black',
    strokeWeight: 2,
    fillColor: 'black',
    fillOpacity: 0.2,
    zIndex: 1,
    content: 'AREA ' + index
  });
  boundary.setMap(map);

  var infoWindow = new google.maps.InfoWindow;
  boundary.addListener('click', function(event) {
    // toggle editable state
    boundary.setEditable(!boundary.getEditable());
    infoWindow.setContent(this.content);
    infoWindow.setPosition(event.latLng);
    infoWindow.open(map);
  });
}
google.maps.event.addDomListener(window, "load", initialize);
var latlngs = [
  [{
    lat: 25.774252,
    lng: -80.190262
  }, {
    lat: 18.466465,
    lng: -66.118292
  }, {
    lat: 32.321384,
    lng: -64.757370
  }, {
    lat: 25.774252,
    lng: -80.190262
  }, ],
  [{
    lat: 59.677361,
    lng: -2.469846
  }, {
    lat: 59.299717,
    lng: -6.314917
  }, {
    lat: 57.877247,
    lng: -9.314917
  }, {
    lat: 54.428078,
    lng: -11.638861
  }, {
    lat: 51.784554,
    lng: -11.702241
  }]
];
html,
body,
#map {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map"></div>

Upvotes: 3

Related Questions