I'm trying to add a button in googlemap infoWindow but I'm beginner in javascript and I have spent weeks on this and still not working... So I hope one of you will be able to help me.
To explain you a litle bit... I get markers from a bdd to display them on a map. Then on marker click, a infoWindow opens with all info marker on it.
This is all working perfectly but then is when I don't get it.
I have added a submit button to each infoWindow markers and I would like an action on submit button click (save to database). But the button is not responding at all...
I removed all the code containing the save function to keep it all clear as there is a alert("click") to test the button...
<script type="text/javascript">
var bounds;
var markers = [];
var markerCount = 0;
function initialize(){
bounds = new google.maps.LatLngBounds();
var myLatLng = new google.maps.LatLng(46.775090, 2.507969);
var mapOptions={
zoom: 6,
center: myLatLng,
maxZoom: 11,
},
map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
setMarkers(map,marker);
const geocoder = new google.maps.Geocoder();
document.getElementById("submit").addEventListener("click", () => {
geocodeAddress(geocoder, map);
});
}
function setMarkers(map,locations){
for(var i=0; i<locations.length; i++){
var station = locations[i];
var myLatLng = new google.maps.LatLng(station['marker_latitude'], station['marker_longitude']);
var infoWindow = new google.maps.InfoWindow();
var image = 'https://marchad.fr/wp-includes/images/marchad.png';
var description = station['marker_text'];
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: image,
title: station['marker_ville'],
id: station['marker_id']
});
(function(marker, i){
google.maps.event.addListener(marker, "click",function(){
var station = locations[i];
var mId = station['marker_id']; //description input field value
var contentString = ("<div id='infoWindow"+station['marker_id']+">"
+"<p class='texte'><strong>"+station['marker_text']+"</strong><p>"
+"<p class='texte'>Ce staliad est géré par un "+station['marker_user_type']+"<p>"
+"<p class='texte'><strong>Adresse : </strong>"+station['marker_adresse']+"<p>"
+"<p class='texte'><strong>Jour de permanence : </strong>"+station['marker_day']+"<p>"
+"<p class='texte'><strong>Dépôts : </strong>de "+station['marker_depot_start_time']+" à "+station['marker_depot_end_time']+"<p>"
+"<p class='texte'><strong>Retraits : </strong>de "+station['marker_start_time']+" à "+station['marker_end_time']+"<p>"
+"<p class='texte'><strong>Téléphone : </strong>"+station['marker_user_contact']+"<p>"
+"<p class='texte'><strong>Mail : </strong>"+station['marker_contact_mail']+"<p>"
+"<p class='texte'><strong>Commentaire : </strong>"+station['marker_commentaire']+"<p>"
+'<form action="ajax-save.php" method="POST" name="SaveMarker" id="SaveMarker'+station['marker_id']+'">'
+'<input id="idInput'+station['marker_id']+'" type="hidden" name="marker-id" class="marker-id'+station['marker_id']+'" value='+station['marker_id']+' />'+station['marker_id']+'</input>'
+'</form>'
+'<input id="inputButton'+station['marker_id']+'" type="button" id="save-marker'+station['marker_id']+'" name="save-marker" class="save-marker'+station['marker_id']+'" data-id="'+station['marker_id']+'" value="M\'inscrire" />'
+'<div id="test'+station['marker_id']+'">'+vendorId+'</div>'
+'<span class="info-content'+station['marker_id']+'">'
+'<h1 class="marker-heading"></h1>'
+'</span>'
+"</div>"
);
infoWindow.close();
infoWindow.setContent(contentString);
infoWindow.open(map,this);
var class_name_removeBtn = 'remove-marker'+station['marker_id'];
var class_name_saveBtn = 'save-marker'+station['marker_id'];
var removeBtn = document.getElementsByClassName(class_name_removeBtn);
var saveBtn = document.getElementsByClassName(class_name_saveBtn);
console.log(removeBtn);
console.log(saveBtn);
//add click listner to save marker button
google.maps.event.addDomListener(saveBtn, "click", function(event) {
var class_name_mReplace = 'info-content'+station['marker_id'];
var class_name_mName = 'marker-id'+station['marker_id'];
var mReplace = document.getElementsByClassName(class_name_mReplace); //html to be replaced after success
var mName = document.getElementsByClassName(class_name_mName); //name input field value
var mId = station['marker_id'];
var vId = vendorId;
console.log(mReplace);
console.log(mName);
console.log(mId);
console.log(vId);
if(mId !=='')
{
alert("click");
save_marker( mName, mId, mReplace,vId); //call save marker function
}else{
alert("Something went wrong. Please contact admin");
}
});
if(typeof removeBtn !== 'undefined') //continue only when save button is present
{
google.maps.event.addDomListener(removeBtn, "click", function(event) {
var class_name_mName = 'marker-id'+station['marker_id'];
var mName = document.getElementsByClassName(class_name_mName); //name input field value
var vId = vendorId;
remove_marker(mName,vId);
});
}
});
})(marker, i);
}
}
</script>
Your first problem is the saveBtn is not part of the DOM until the InfoWindow has been opened as you are adding as a string in the InfoWindow content.
Relate questions:
using addDomListener with googlemaps not working
Turn off google map's infowindow.open(map) asynchronous behaviour
Adding Event Listener on button - Javascript
The second problem is that document.getElementsByClassName(class_name_saveBtn); returns an array. Instead of:
document.getElementsByClassName(class_name_saveBtn);
for a single marker, you need:
document.getElementsByClassName(class_name_saveBtn)[0];
for multiple markers/infowindows (get the last one created):
var removeBtn = document.getElementsByClassName(class_name_removeBtn);
removeBtn = removeBtn[removeBtn.length-1];
var saveBtn = document.getElementsByClassName(class_name_saveBtn);
saveBtn = saveBtn[saveBtn.length-1];
proof of concept fiddle
code snippet:
var bounds;
var markers = [];
var markerCount = 0;
/* var marker = [{
marker_latitude: 47.394144,
marker_longitude: 0.68484,
marker_id: 1
}] */
var marker = [{"marker_id":"6","marker_user_id":"0","marker_user_type":"","marker_user_stal":null,"marker_categorie":"5","marker_adresse":"","marker_numero_voie":"","marker_voie":"","marker_zip":"","marker_ville":"Toulouse","marker_departement":"31","marker_region":"0","marker_longitude":"1.434917","marker_latitude":"43.573085","marker_day":"","marker_depot_start_time":"00:00:00","marker_depot_end_time":"00:00:00","marker_start_time":"00:00:00","marker_end_time":"00:00:00","marker_text":"Casino Barri\u00e8re","marker_user_contact":"","marker_contact_mail":"","marker_enable_contact_telephone":"","marker_enable_contact_mail":"","marker_commentaire":null,"marker_actif":"Oui","id":null,"mark_id":null,"user_id":null,"user_actif":null},{"marker_id":"7","marker_user_id":"0","marker_user_type":"","marker_user_stal":null,"marker_categorie":"6","marker_adresse":"","marker_numero_voie":"","marker_voie":"","marker_zip":"","marker_ville":"Toulouse","marker_departement":"31","marker_region":"0","marker_longitude":"1.447856","marker_latitude":"43.604573","marker_day":"","marker_depot_start_time":"00:00:00","marker_depot_end_time":"00:00:00","marker_start_time":"00:00:00","marker_end_time":"00:00:00","marker_text":"Cinema Gaumont Wilson","marker_user_contact":"","marker_contact_mail":"","marker_enable_contact_telephone":"","marker_enable_contact_mail":"","marker_commentaire":null,"marker_actif":"Oui","id":null,"mark_id":null,"user_id":null,"user_actif":null},{"marker_id":"8","marker_user_id":"0","marker_user_type":"","marker_user_stal":null,"marker_categorie":"6","marker_adresse":"","marker_numero_voie":"","marker_voie":"","marker_zip":"","marker_ville":"Lab\u00e8ge","marker_departement":"31","marker_region":"0","marker_longitude":"1.511496","marker_latitude":"43.53992","marker_day":"","marker_depot_start_time":"00:00:00","marker_depot_end_time":"00:00:00","marker_start_time":"00:00:00","marker_end_time":"00:00:00","marker_text":"Cinema Gaumont Lab\u00e8ge","marker_user_contact":"","marker_contact_mail":"","marker_enable_contact_telephone":"","marker_enable_contact_mail":"","marker_commentaire":null,"marker_actif":"Oui","id":null,"mark_id":null,"user_id":null,"user_actif":null},{"marker_id":"9","marker_user_id":"0","marker_user_type":"","marker_user_stal":null,"marker_categorie":"6","marker_adresse":"","marker_numero_voie":"","marker_voie":"","marker_zip":"","marker_ville":"Blagnac","marker_departement":"31","marker_region":"0","marker_longitude":"1.373341","marker_latitude":"43.644029","marker_day":"","marker_depot_start_time":"00:00:00","marker_depot_end_time":"00:00:00","marker_start_time":"00:00:00","marker_end_time":"00:00:00","marker_text":"Cinema Mega CGR Blagnac","marker_user_contact":"","marker_contact_mail":"","marker_enable_contact_telephone":"","marker_enable_contact_mail":"","marker_commentaire":null,"marker_actif":"Oui","id":null,"mark_id":null,"user_id":null,"user_actif":null},{"marker_id":"10","marker_user_id":"0","marker_user_type":"","marker_user_stal":null,"marker_categorie":"4","marker_adresse":"","marker_numero_voie":"","marker_voie":"","marker_zip":"","marker_ville":"Toulouse","marker_departement":"31","marker_region":"0","marker_longitude":"1.435198","marker_latitude":"43.62186","marker_day":"","marker_depot_start_time":"00:00:00","marker_depot_end_time":"00:00:00","marker_start_time":"00:00:00","marker_end_time":"00:00:00","marker_text":"Bowling Minimes\r\n108 Bis Avenue des Minimes, 31200 Toulouse \u200e\r\n05 61 47 95 60","marker_user_contact":"","marker_contact_mail":"","marker_enable_contact_telephone":"","marker_enable_contact_mail":"","marker_commentaire":null,"marker_actif":"Oui","id":null,"mark_id":null,"user_id":null,"user_actif":null},{"marker_id":"11","marker_user_id":"0","marker_user_type":"","marker_user_stal":null,"marker_categorie":"4","marker_adresse":"","marker_numero_voie":"","marker_voie":"","marker_zip":"","marker_ville":"Montaudran","marker_departement":"31","marker_region":"0","marker_longitude":"1.496152","marker_latitude":"43.568863","marker_day":"","marker_depot_start_time":"00:00:00","marker_depot_end_time":"00:00:00","marker_start_time":"00:00:00","marker_end_time":"00:00:00","marker_text":"Bowling Montaudran Impasse Louise Lab\u00e9 31400 Toulouse 05 61 20 20 70","marker_user_contact":"","marker_contact_mail":"","marker_enable_contact_telephone":"","marker_enable_contact_mail":"","marker_commentaire":null,"marker_actif":"Oui","id":null,"mark_id":null,"user_id":null,"user_actif":null},{"marker_id":"12","marker_user_id":"0","marker_user_type":"","marker_user_stal":null,"marker_categorie":"4","marker_adresse":"","marker_numero_voie":"","marker_voie":"","marker_zip":"","marker_ville":"Colomiers","marker_departement":"31","marker_region":"0","marker_longitude":"1.304691","marker_latitude":"43.609902","marker_day":"","marker_depot_start_time":"00:00:00","marker_depot_end_time":"00:00:00","marker_start_time":"00:00:00","marker_end_time":"00:00:00","marker_text":"Bowling Stadium Colomiers\r\n29 Chemin du Loudet\r\n33770 Colomiers\r\n05 34 36 42 50","marker_user_contact":"","marker_contact_mail":"","marker_enable_contact_telephone":"","marker_enable_contact_mail":"","marker_commentaire":null,"marker_actif":"Oui","id":null,"mark_id":null,"user_id":null,"user_actif":null},{"marker_id":"13","marker_user_id":"0","marker_user_type":"","marker_user_stal":null,"marker_categorie":"10","marker_adresse":"","marker_numero_voie":"","marker_voie":"","marker_zip":"","marker_ville":"Plaisance-du-Touch","marker_departement":"31","marker_region":"0","marker_longitude":"1.260248","marker_latitude":"43.55854","marker_day":"","marker_depot_start_time":"00:00:00","marker_depot_end_time":"00:00:00","marker_start_time":"00:00:00","marker_end_time":"00:00:00","marker_text":"African Safari\r\n41 Rue des Landes\r\n31830 Plaisance-du-Touch\r\n05 61 86 45 03","marker_user_contact":"","marker_contact_mail":"","marker_enable_contact_telephone":"","marker_enable_contact_mail":"","marker_commentaire":null,"marker_actif":"Oui","id":null,"mark_id":null,"user_id":null,"user_actif":null},{"marker_id":"29","marker_user_id":"2","marker_user_type":"marchand","marker_user_stal":"Aux petits l\u00e9gumes","marker_categorie":"test","marker_adresse":"12 Rue du Bocage, Tr\u00e9gueux, France","marker_numero_voie":"12","marker_voie":"Rue du Bocage","marker_zip":"22950","marker_ville":"Tr\u00e9gueux","marker_departement":"C\u00f4tes-d'Armor","marker_region":"Bretagne","marker_longitude":"-2.7515737","marker_latitude":"48.4831891","marker_day":"Lundi","marker_depot_start_time":"09:00:00","marker_depot_end_time":"12:00:00","marker_start_time":"12:00:00","marker_end_time":"18:46:00","marker_text":"Aux petits l\u00e9gumes","marker_user_contact":"0783312456","marker_contact_mail":"nattydreadnatty#live.fr","marker_enable_contact_telephone":"yes","marker_enable_contact_mail":"yes","marker_commentaire":"test test test test test testing out","marker_actif":"oui","id":null,"mark_id":null,"user_id":null,"user_actif":null},{"marker_id":"30","marker_user_id":"3","marker_user_type":"marchand","marker_user_stal":"Poivrons et compagnie","marker_categorie":"","marker_adresse":"12t Rue du Vau Hello, 22360 Langueux, France","marker_numero_voie":"12","marker_voie":"Rue du Vau Hello","marker_zip":"22360","marker_ville":"Langueux","marker_departement":"C\u00f4tes-d'Armor","marker_region":"Bretagne","marker_longitude":"-2.7262882","marker_latitude":"48.50448799999999","marker_day":"Vendredi","marker_depot_start_time":"08:00:00","marker_depot_end_time":"10:00:00","marker_start_time":"10:00:00","marker_end_time":"18:00:00","marker_text":"Poivrons et compagnie","marker_user_contact":"","marker_contact_mail":"lucbinard4#gmail.com","marker_enable_contact_telephone":"yes","marker_enable_contact_mail":"yes","marker_commentaire":"","marker_actif":"oui","id":null,"mark_id":null,"user_id":null,"user_actif":null}];
var vendorId = "vendorId";
function initialize() {
bounds = new google.maps.LatLngBounds();
var myLatLng = new google.maps.LatLng(46.775090, 2.507969);
var mapOptions = {
zoom: 6,
center: myLatLng,
maxZoom: 11,
},
map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
setMarkers(map, marker);
const geocoder = new google.maps.Geocoder();
document.getElementById("submit").addEventListener("click", () => {
geocodeAddress(geocoder, map);
});
}
function setMarkers(map, locations) {
for (var i = 0; i < locations.length; i++) {
var station = locations[i];
var myLatLng = new google.maps.LatLng(station['marker_latitude'], station['marker_longitude']);
var infoWindow = new google.maps.InfoWindow();
var image = 'https://marchad.fr/wp-includes/images/marchad.png';
var description = station['marker_text'];
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: image,
title: station['marker_ville'],
id: station['marker_id']
});
(function(marker, i) {
google.maps.event.addListener(marker, "click", function() {
var station = locations[i];
var mId = station['marker_id']; //description input field value
var contentString = ("<div id='infoWindow" + station['marker_id'] + ">" +
"<p class='texte'><strong>" + station['marker_text'] + "</strong><p>" +
"<p class='texte'>Ce staliad est géré par un " + station['marker_user_type'] + "<p>" +
"<p class='texte'><strong>Adresse : </strong>" + station['marker_adresse'] + "<p>" +
"<p class='texte'><strong>Jour de permanence : </strong>" + station['marker_day'] + "<p>" +
"<p class='texte'><strong>Dépôts : </strong>de " + station['marker_depot_start_time'] + " à " + station['marker_depot_end_time'] + "<p>" +
"<p class='texte'><strong>Retraits : </strong>de " + station['marker_start_time'] + " à " + station['marker_end_time'] + "<p>" +
"<p class='texte'><strong>Téléphone : </strong>" + station['marker_user_contact'] + "<p>" +
"<p class='texte'><strong>Mail : </strong>" + station['marker_contact_mail'] + "<p>" +
"<p class='texte'><strong>Commentaire : </strong>" + station['marker_commentaire'] + "<p>" +
'<form action="ajax-save.php" method="POST" name="SaveMarker" id="SaveMarker' + station['marker_id'] + '">' +
'<input id="idInput' + station['marker_id'] + '" type="hidden" name="marker-id" class="marker-id' + station['marker_id'] + '" value=' + station['marker_id'] + ' />' + station['marker_id'] + '</input>' +
'</form>' +
'<input id="inputButton' + station['marker_id'] + '" type="button" id="save-marker' + station['marker_id'] + '" name="save-marker" class="save-marker' + station['marker_id'] + '" data-id="' + station['marker_id'] + '" value="M\'inscrire" />' +
'<div id="test' + station['marker_id'] + '">' + vendorId + '</div>' +
'<span class="info-content' + station['marker_id'] + '">' +
'<h1 class="marker-heading"></h1>' +
'</span>' +
"</div>"
);
infoWindow.close();
infoWindow.setContent(contentString);
infoWindow.open(map, this);
var class_name_removeBtn = 'remove-marker' + station['marker_id'];
var class_name_saveBtn = 'save-marker' + station['marker_id'];
google.maps.event.addListenerOnce(infoWindow,'domready', function() {
var removeBtn = document.getElementsByClassName(class_name_removeBtn);
removeBtn = removeBtn[removeBtn.length-1];
var saveBtn = document.getElementsByClassName(class_name_saveBtn);
saveBtn = saveBtn[saveBtn.length-1];
console.log(removeBtn);
console.log(saveBtn);
//add click listner to save marker button
google.maps.event.addDomListener(saveBtn, "click", function(event) {
var class_name_mReplace = 'info-content' + station['marker_id'];
var class_name_mName = 'marker-id' + station['marker_id'];
var mReplace = document.getElementsByClassName(class_name_mReplace); //html to be replaced after success
var mName = document.getElementsByClassName(class_name_mName); //name input field value
var mId = station['marker_id'];
var vId = vendorId;
console.log(mReplace);
console.log(mName);
console.log(mId);
console.log(vId);
if (mId !== '') {
alert("click");
save_marker(mName, mId, mReplace, vId); //call save marker function
} else {
alert("Something went wrong. Please contact admin");
}
});
if (typeof removeBtn !== 'undefined') //continue only when save button is present
{
google.maps.event.addDomListener(removeBtn, "click", function(event) {
var class_name_mName = 'marker-id' + station['marker_id'];
var mName = document.getElementsByClassName(class_name_mName); //name input field value
var vId = vendorId;
remove_marker(mName, vId);
});
}
})
});
})(marker, i);
}
}
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map-canvas {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
<!DOCTYPE html>
<html>
<head>
<title>Simple Map</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<!-- jsFiddle will insert css and js -->
</head>
<body>
<input id="submit" type="button" value="submit" />
<div id="map-canvas"></div>
<!-- Async script executes immediately and must be after any DOM elements used in callback. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initialize&libraries=&v=weekly" async></script>
</body>
</html>
Mine works like this.. detect click event within info window
google.maps.event.addListener(infowindow, 'domready', function() {
$('.classname').click(function(){
// code
});
I try to insert a marker with a form in InfoWindow, but with the first click into the map I got this error:
Uncaught TypeError: Cannot set property 'value' of null
It is because getElementById is NULL, when I click a second time it is matching. I tried some hours but didn't get it :-/
My code (part of):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script>
var map;
var marker;
function initJsMap() {
var vienna = new google.maps.LatLng(48.2134567, 16.3789012);
var mapOptions = {
position: vienna,
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map-canvas"),mapOptions);
google.maps.event.addListener(map, 'dblclick', function(event) {
placeMarker(event.latLng);
});
}
function placeMarker(location) {
if (marker) {
marker.setPosition(location);
} else {
var form = '<div id="form_canvasform">' +
'<form method="POST" action="/addmap" name="form_canvas">' +
'<div style="display:none;">' +
'<input id="csrf_token" name="csrf_token" type="hidden" value="foo">' +
'<input id="latitude" name="latitude" type="hidden" value="">' +
'<input id="longitude" name="longitude" type="hidden" value=""></div>' +
'<label for="link">link</label> <input id="link" name="link" type="text" value="">' +
'<input type="submit" value="Go!">' +
'</form>' +
'</div>';
infowindow = new google.maps.InfoWindow({
content: form
});
marker = new google.maps.Marker({
position: location,
map: map,
draggable: true
});
infowindow.open(map, marker);
marker.addListener('click', function() {
infowindow.open(map, marker);
});
}
console.log("Latitude: " + location.lat());
console.log("Longitude: " + location.lng());
console.log(form);
document.getElementById('latitude').value = location.lat();
document.getElementById('longitude').value = location.lng();
}
</script>
</head>
<body onload="initJsMap()">
<div id="map-canvas" style="width:50%; height:600px;"></div>
</body>
</html>
The form content is generated by jinja2 templating engine (with flask). With the console.log() I get the correct values.
[EDIT]:
This is the jinja code who generate the form:
var form = '<div id="form_canvasform">' +
'<form method="POST" action="{{ request.path }}" name="form_canvas">' +
'{{ form.hidden_tag() }}' +
'{{ form.link.label }} {{ form.link }}' +
'<br/>' +
'<input type="submit" value="Go!">' +
'</form>' +
'</div>';
When you use a string as content for an InfoWindow the elements inside the InfoWindow are not available before the InfoWindow has been opened(is domready)
But you must not use a string as content, youz may also use a DOMNode directly, this node will always be accessible, no matter if it has already been injected into the document or not.
So the solution: create a DOMNode based on the form-string, and use it as infowindow-content
Demo:(I've modified form a little bit for the demonstration, but it will also work with the original string)
function initJsMap() {
var vienna = new google.maps.LatLng(48.2134567, 16.3789012),
mapOptions = {
center: vienna,
zoom: 12,
disableDoubleClickZoom:true
},
map = new google.maps.Map(document.getElementById("map-canvas"),mapOptions),
marker = new google.maps.Marker({draggable: true}),
infowindow = new google.maps.InfoWindow({disableAutoPan:true}),
form = '<div id="form_canvasform">' +
'<form method="POST" action="/addmap" name="form_canvas">' +
'<input id="latitude" name="latitude" value=""><br/>' +
'<input id="longitude" name="longitude" value="">' +
'</form>' +
'</div>';
node = document.createElement('div'),
content;
node.innerHTML = form;
content = node.firstChild
infowindow.setContent(content);
google.maps.event.addListener(map, 'dblclick', function(event) {
marker.setOptions({position:event.latLng,map:map});
infowindow.open(map,marker);
});
google.maps.event.addListener(marker, 'click', function(event) {
marker.setPosition(event.latLng);
infowindow.open(map,marker);
});
google.maps.event.addListener(marker, 'position_changed', function() {
content.querySelector('input[name="latitude"]').value = this.getPosition().lat();
content.querySelector('input[name="longitude"]').value = this.getPosition().lng();
if(infowindow.getMap()){
infowindow.open(map,marker);
}
});
}
html,body,#map-canvas{
padding:0;
margin:0;
height:100%;
}
<div id="map-canvas"></div>
<script src="https://maps.googleapis.com/maps/api/js?v=3&callback=initJsMap" async defer></script>
It has to do with you trying to access the form's hidden elements before the infoWindow has properly opened.
EDIT: Here's one way of doing it, but it requires some re-schuffling.
I am using String.replace to change the values of the form. I don't know if there is an easier way of doing it using vanilla JavaScript (as it is easier to do it with jQuery), but it seems to work.
var map;
var marker;
// regex to look for in HTML string
var latRe = /(<input id="latitude" name="latitude" type="hidden" value=")(.*)("><input id="longitude")/;
var lngRe = /(<input id="longitude" name="longitude" type="hidden" value=\")(.*)(">.*<label)/;
function initJsMap () {
var vienna = new google.maps.LatLng(48.2134567, 16.3789012);
var mapOptions = {
center: vienna, // 'center', not 'position'
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
marker = new google.maps.Marker({ map: map, draggable: true });
infowindow = new google.maps.InfoWindow();
google.maps.event.addListener(map, 'dblclick', function(event) {
placeMarker(event.latLng);
});
marker.addListener('click', function() {
infowindow.open(map, marker);
});
}
function placeMarker (location) {
var form =
'<div id="form_canvasform">' +
'<form method="POST" action="/addmap" name="form_canvas">' +
'<div style="display:none;">' +
'<input id="csrf_token" name="csrf_token" type="hidden" value="foo">' +
'<input id="latitude" name="latitude" type="hidden" value="">' +
'<input id="longitude" name="longitude" type="hidden" value=""></div>' +
'<label for="link">link</label> <input id="link" name="link" type="text" value="">' +
'<input type="submit" value="Go!">' +
'</form>' +
'</div>';
// ugly: replace the values in the HTML string with the new values using regex
form = form.replace(latRe, '$1' + location.lat() + '$3');
form = form.replace(lngRe, '$1' + location.lng() + '$3');
// set the new form
infowindow.setContent(form);
// set the new position of the marker
marker.setPosition(location);
// open infowindow
google.maps.event.trigger(marker, 'click');
}
If you need information about the regular expressions that I used, check this answer.
DEMO
After adding a delete function and adding my markers into an array the save button/ save function is no longer attached to the right infowindow on my google map.
If I open two infowindows, enter the info in both, then click save on the first one I opened it will update the last infowindow created with "You submitted" and it will save it twice. I tried a few different things based on different stack overflow posts including adding an iterator around the initialization of my infowindow and also adding an external function for adding a marker, but this did not work. I also made sure my global variables (like map) are declared before initializing. I am a nube that has been struggling for days.
I'm sure the issue surrounds my confusion about how the infowindow is attached to the markers in the array. My code is in the snippet below.
var markers = [];
var uniqueId = 1;
var marker;
var infowindow;
var map;
var html;
function initialize() {
var mapOptions = {
zoom: 8,
center: {
lat: 48.591130,
lng: -119.682349
},
mapTypeControlOptions: {
mapTypeIds: ['roadmap']
}
};
var map = new google.maps.Map(document.getElementById("dvMap"), mapOptions);
//Attach click event handler to the map.
google.maps.event.addListener(map, 'click', function(e) {
//Determine the location where the user has clicked.
var location = e.latLng;
//Create a marker and placed it on the map.
var marker = new google.maps.Marker({
position: location,
map: map,
});
//Set unique id
marker.id = uniqueId;
uniqueId++;
markers.push(marker);
//Attach click event handler to the marker.
google.maps.event.addListener(marker, "click", function(e) {
html = "<p style='color:#173e43;font-size:120%;font-weight:bold;text-align:center; width:150pxs; margin-top: 2px; margin-bottom:4px' >Add A Comment</p>" +
"<table>" +
"<tr><td>Issue/Idea:</td> <td> <textarea rows='1' cols='26' id='name' style='height: 30px; width:150px' name='reply'></textarea></td> </tr>" +
"<tr><td>Address:</td> <td><input type='text' id='address' style='width:150px'/></td> </tr>" +
"</td></tr>";
html += "<tr><td><input type = 'button' value = 'Delete' onclick = 'DeleteMarker(" + marker.id + ");' value = 'Delete' /></td>" +
"<td><input type='button' value='Submit' onclick='saveData(" + marker.id + ")'/></td></tr>";
infowindow = new google.maps.InfoWindow({
content: html
});
infowindow.setContent(html);
infowindow.open(map, marker);
});
//Add marker to the array.
markers.push(marker);
});
};
function DeleteMarker(id) {
//Find and remove the marker from the Array
for (var i = 0; i < markers.length; i++) {
if (markers[i].id == id) {
//Remove the marker from Map
markers[i].setMap(null);
//Remove the marker from array.
markers.splice(i, 1);
return;
}
}
};
function saveData(id) {
for (var i = 0; i < markers.length; i++) {
if (markers[i].id == id) {
var name = escape(document.getElementById("name").value);
var address = escape(document.getElementById("address").value);
var latlng = markers[i].getPosition();
var url = "phpsqlinfo_addrow.php?name=" + name + "&address=" + address +
"&lat=" + latlng.lat() + "&lng=" + latlng.lng();
downloadUrl(url, function(data, responseCode) {
if (responseCode == 200 && data.length >= 1) {
document.getElementById("message").innerHTML = "Location added. Contents: name=" + name +", address=" + address+ " latlng=" +latlng;
}
});
infowindow.setContent("You submitted Contents: name=" + name +", address=" + address+ " latlng=" +latlng);
}
}
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request.responseText, request.status);
}
};
request.open('GET', url, true);
request.send(null);
function doNothing() {}
}
google.maps.event.addDomListener(window, 'load', initialize);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="http://maps.googleapis.com/maps/api/js?sensor=false">
</script>
<div id="dvMap" style="width: 1000px; height: 490px"></div>
<div id="message"></div>
Ok, so I moved the push statement so that it is pushing the marker to the array after I declare the infowindow. This stopped the save function from saving the html contents multiple times. So the save is working great now, the only problem is my ability to update the right infowindow with the message "You submitted..."
It is still just updating the last infowindow I opened with that message.
var markers = [];
var uniqueId = 1;
var marker;
var infowindow;
var map;
var html;
function initialize() {
var mapOptions = {
zoom: 8,
center: {
lat: 48.591130,
lng: -119.682349
},
mapTypeControlOptions: {
mapTypeIds: ['roadmap']
}
};
var map = new google.maps.Map(document.getElementById("dvMap"), mapOptions);
//Attach click event handler to the map.
google.maps.event.addListener(map, 'click', function(e) {
//Determine the location where the user has clicked.
var location = e.latLng;
//Create a marker and placed it on the map.
var marker = new google.maps.Marker({
position: location,
map: map,
});
//Set unique id
marker.id = uniqueId;
uniqueId++;
//Attach click event handler to the marker.
google.maps.event.addListener(marker, "click", function(e) {
html = "<p style='color:#173e43;font-size:120%;font-weight:bold;text-align:center; width:150pxs; margin-top: 2px; margin-bottom:4px' >Add A Comment</p>" +
"<table>" +
"<tr><td>Issue/Idea:</td> <td> <textarea rows='1' cols='26' id='name' style='height: 30px; width:150px' name='reply'></textarea></td> </tr>" +
"<tr><td>Address:</td> <td><input type='text' id='address' style='width:150px'/></td> </tr>" +
"</td></tr>";
html += "<tr><td><input type = 'button' value = 'Delete' onclick = 'DeleteMarker(" + marker.id + ");' value = 'Delete' /></td>" +
"<td><input type='button' value='Submit' onclick='saveData(" + marker.id + ")'/></td></tr>";
infowindow = new google.maps.InfoWindow({
content: html
});
infowindow.setContent(html);
infowindow.open(map, marker);
});
//Add marker to the array.
markers.push(marker);
});
};
function DeleteMarker(id) {
//Find and remove the marker from the Array
for (var i = 0; i < markers.length; i++) {
if (markers[i].id == id) {
//Remove the marker from Map
markers[i].setMap(null);
//Remove the marker from array.
markers.splice(i, 1);
return;
}
}
};
function saveData(id) {
for (var i = 0; i < markers.length; i++) {
if (markers[i].id == id) {
var name = escape(document.getElementById("name").value);
var address = escape(document.getElementById("address").value);
var latlng = markers[i].getPosition();
var url = "phpsqlinfo_addrow.php?name=" + name + "&address=" + address +
"&lat=" + latlng.lat() + "&lng=" + latlng.lng();
downloadUrl(url, function(data, responseCode) {
if (responseCode == 200 && data.length >= 1) {
document.getElementById("message").innerHTML = "Location added. Contents: name=" + name +", address=" + address+ " latlng=" +latlng;
}
});
infowindow.setContent("You submitted Contents: name=" + name +", address=" + address+ " latlng=" +latlng);
}
}
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request.responseText, request.status);
}
};
request.open('GET', url, true);
request.send(null);
function doNothing() {}
}
google.maps.event.addDomListener(window, 'load', initialize);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="http://maps.googleapis.com/maps/api/js?sensor=false">
</script>
<div id="dvMap" style="width: 1000px; height: 490px"></div>
<div id="message"></div>