I’m attempting to create a map that allows users to report a trailwork
problem by clicking and filling a form in an infowindow (similar to
seeclickfix.com). I haven’t built in the php/SQL that will actually
save the information provided by the user yet.
The problem: I have a button in the html of my infowindow for users to
submit information and close the window. Instead of just closing the
window though, my event listener for new markers receives clicks
through the infowindow, creating an unwanted marker behind the button.
Google avoids this problem somehow; no click is registered on their
top right-exit ‘x’.
I’ve attempted to create a Boolean signal variable (‘infopen’) to let
my addMarker function know if an infowindow is open, but it’s not
functioning…. Any ideas why?
Any other suggestions regarding the code would be appreciated!
(My task is creating a system to organizing and store multiple
infowindows/markers…)
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test Reporter </title>
<script type="text/javascript" src="http://maps.google.com/maps/
api/js?sensor=false"></script>
<script type="text/javascript">
var map;
var marker;
var markers = [];
var infowindow;
var infopen = false;
var edit = true;
var pos = new google.maps.LatLng(44.021, -71.831102);
function initialize() {
var mapOptions = {
zoom: 14,
center: pos,
mapTypeControl: true,
panControl: false,
zoomControl: true,
mapTypeId: google.maps.MapTypeId.TERRAIN
};
map = new google.maps.Map(document.getElementById("map_canvas"),
mapOptions);
var table = "<table>" +
"<tr><td>Problem:</td> <td><input type='text'
id='prob'/> </td> </tr>" +
"<tr><td>Description:</td> <td><input type='text'
size='30' id='desc'/></td> </tr>" +
"<tr><td align=right ><input type='button'
value='Save & Close' onclick='saveData()' /></td>" +
"<td><input type='button' value='Cancel & Delete'
onclick='cancel()' /></td></tr>";
infowindow = new google.maps.InfoWindow({
content: table
});
google.maps.event.addListener(map, "click", function(event) {
addMarker(event.latLng);
});
} //end initialize
// Add a marker to the map and push to the array, open an infowindow listener.
function addMarker(location) {
if (editon.editT[0].checked) edit = true; //check 'edit' radio buttons
if (editon.editT[1].checked) edit = false;
alert('infopen is ' + infopen);
if (edit== true && infopen== false) {
//if edit toggle is selected and infowindow not open
marker = new google.maps.Marker({
position: location, //from event.latLng
map: map,
draggable: true,
});
markers.push(marker); //add to markers array
google.maps.event.addListener(marker, "click", function() {
//listener for infowindow
infowindow.open(map, marker);
infopen = true; // stop the creation of new markers *in theory...
//alert('infopen is ' + infopen);
});
}// end if
} //end addMarker()
// Sets the map on all markers in the array. (only used when clearing)
function setAllMap(map) {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(map);
}
}
// Deletes all markers in the array by removing references to
them.
function deleteOverlays() {
setAllMap(null);
markers = [];
}
//would passes along info to php... not yet
function saveData() {
infowindow.close();
infopen = false; //reallow marker creation from click
}
//closes window and clears marker
function cancel() {
infowindow.close();
infopen = false; // reallow marker creation ***click still
heard by event listener***
marker.setMap(null); //just clears from map
}
</script>
</head>
<body onload="initialize()">
<br> </br>
<form name="editon"> Turn on editing:
<input type="radio" name="editT" value='true' checked/>Yes
<input type="radio" name="editT" value='false' />No
</form>
<div id="map_canvas" style="width:100%; height:70%"></div>
<p>If too cluttered:
<input onclick="deleteOverlays();" type=button value="Clear Map"/>
</body>
</html>
My contrived hack: add a setTimeout() around infowindow.close(). There is a rationale, explained below.
100 ms seems reasonable. Strangely, setting the marker to a null map in cancel() also has to be timed out. I don’t think you need infopen anymore.
I got the idea from this code sample:
http://code.google.com/apis/maps/articles/phpsqlinfo_v3.html
In this sample, the infoWindow is only closed (in a callback) after a database request is made and ensuring the response was good. Of course, this must take some milliseconds. So, under these assumptions, once you have your DB part working, you can replace the ugly setTimeout and everything should work! 🙂