Making Google maps marker array global breaks marker click event - javascript

In this page I use the following script:
function initialize() {
var mapCanvas = document.getElementById('map');
var mapOptions = {center:new google.maps.LatLng(latitudeMid,longitudeMid),zoom:15,mapTypeId:google.maps.MapTypeId.ROADMAP,streetViewControl:false,mapTypeControl:true,scaleControl:true,scaleControlOptions:{position:google.maps.ControlPosition.TOP_RIGHT}};
var map = new google.maps.Map(mapCanvas, mapOptions);
var markers=[]; //<=========================================== inside function initialize()
var i;
var insertion;
var previousMarker;
for (i = 0; i < fotoCount; i++) {
var myLatLng=new google.maps.LatLng(Latituden[i], Longituden[i]);
var marker = new StyledMarker({styleIcon:new StyledIcon(StyledIconTypes.MARKER,{color:'00ff00',text:Letters[i]}),position:myLatLng,map:map});
marker.set('zIndex', -i);
marker.myIndex = i;
markers.push(marker);
google.maps.event.addListener(marker, 'click', function() {
var insertion="";
insertion='<img src=\"http://www.pdavis.nl/Ams/'.concat(Bestanden[this.myIndex],'.jpg\"></img>');
insertion=insertion.concat('<table class=width100><tr><td>Bestand: ',Bestanden[this.myIndex],'</td><td class=pright>Lokatie: ',Latituden[this.myIndex],' °N., ',Longituden[this.myIndex],' °E. (',Letters[this.myIndex],')</td>');
insertion=insertion.concat('<td class=pright>Genomen: ',Datums[this.myIndex],'</td></tr><td colspan=3>Object: ',Objecten[this.myIndex],'</td></table>');
$('#photo').html(insertion);
if(previousMarker!=null){previousMarker.styleIcon.set('color', '00ff00')};
this.styleIcon.set('color', 'ff0000');
thisMarker=this.myIndex;
previousMarker=this;
});
}
google.maps.event.trigger(markers[0], 'click');
}
google.maps.event.addDomListener(window, 'load', initialize);
Clicking on a marker highlights the selected marker (turns red) and shows the relevant photo. The two buttons Vorige and Volgende (Previous and Next, to select previous or next photo) obviously don't work because the array markers[] is local to function initialize():
function Next() {
thisMarker++;
if (thisMarker>=fotoCount) {thisMarker=0};
// following line not working
google.maps.event.trigger(markers[thisMarker], 'click');
}
function Previous() {
thisMarker--;
if (thisMarker==0) {thisMarker=fotoCount-1};
// following line not working
google.maps.event.trigger(markers[thisMarker], 'click');
}
The obvious fix is to move "var markers=[]" outside function initialize() (this page) to make this array global, but now the button highlighting (button "A" red upon start; clicked button goes red) does not work. What am I doing wrong here?

The only weird thing is not that when you pass the index 0 to the maximum the click event explodes because he is sending a negative value, then change that and wonder if it is -1, if true passes the greater index - 1 (Excepcion: Cannot read property '__e3ae_' of undefined)
function Previous() {
thisMarker--;
if (thisMarker==-1) {thisMarker=fotoCount-1};
// following line not working
google.maps.event.trigger(markers[thisMarker], 'click');
}
Fiddle example
sorry for my English

Related

Generate an array of markers in one loop and assign different popup to all of them

I load an array of markers from a JSON string. The JSON string contains marker location and information that needs to be displayed on each marker's popup.
I have the following code
function AddAllMarkers(markersJSON){
var tempArray = JSON.parse(markersJSON);
infoWindow = new google.maps.InfoWindow();
for(var i = 0; i < tempArray.Locations.length; i++){
var obj = tempArray.Locations[i];
var point = new google.maps.LatLng(obj.Latitude, obj.Longitude);
var contentString = <!--CONTENT STRING GETS SET HERE PER MARKER-->;
var markerTemp = new google.maps.Marker({
position: point,
icon:obj.Icon
});
google.maps.event.addListener(markerTemp, 'click', function() {
infoWindow.close();
infoWindow = new google.maps.InfoWindow();
infoWindow.setContent(contentString);
infoWindow.open(map, this);
});
markerArray.push(markerTemp);
}
}
When this function gets called I load all the markers correctly but all markers show the popup of the last marker loaded. What am I doing wrong? I did try moving the declaration of infoWindow around but either that does not solve the problem or it causes multiple balloons to be opened at the same time.
How can I solve this?
The reason for the observed behavior is that at the time the event listener function is executed - that is at the time of a mouse click - the loop has finished. Therefore, the contentString variable will hold the value from the last loop iteration.
As a workaround you could attach the content string to the marker itself and access it using the this reference within the event handler.
function AddAllMarkers(markersJSON){
var tempArray = JSON.parse(markersJSON);
infoWindow = new google.maps.InfoWindow();
for(var i = 0; i < tempArray.Locations.length; i++){
var obj = tempArray.Locations[i];
var point = new google.maps.LatLng(obj.Latitude, obj.Longitude);
var contentString = <!--CONTENT STRING GETS SET HERE PER MARKER-->
var markerTemp = new google.maps.Marker({
position: point,
icon:obj.Icon
});
markerTemp.contentString = contentString;
google.maps.event.addListener(markerTemp, 'click', function() {
infoWindow.close();
infoWindow = new google.maps.InfoWindow();
infoWindow.setContent(this.contentString);
infoWindow.open(map, this);
});
markerArray.push(markerTemp);
}
}

text input to a global infowindow

This question extends an answer here that uses domready. The extension is an attempt to include a second infowindow with a slightly different name: inwindow vs infowindow. The first question is, given the answerer's first "rule" -- "Create only one instance of the infowindow object and use setContent() method to modify its content." -- can there be a second infowindow object?
If so, then what is wrong with my attempt at creating inwindow as shown below? inwindow appears when the map is clicked, but clicking its "Submit" button does not seem to do anything.
A working JSFiddle.com version is here (at least it shows a map).
Some global vars and objects are next.
var map
var infowindow = new google.maps.InfoWindow();
var inwindow = new google.maps.InfoWindow();
var markers = [];
var counter = 0;
initialize() is excerpted next.
google.maps.event.addListener(map, 'click', function (event) {
addMarker(event.latLng);
});
google.maps.event.addListener(inwindow, 'domready', function () {
var button = document.getElementById('inputButton');
var input = document.getElementById('nameinput').value;
button.onsubmit = function() {
marker.title = input;
inwindow.close();
};
});
google.maps.event.addListener(infowindow, 'domready', function () {
var button = document.getElementById('deleteButton');
var id = parseInt(button.getAttribute('data-id'));
button.onclick = function() {
deleteMarker(id);
};
});
}
function addMarker(location) {
counter++;
var inputForm = 'Name: <input type="text" id="nameinput" size="31" maxlength="31" tabindex="1"/>' + '<input type="button" id="inputButton" value="Submit">';
var marker = new google.maps.Marker({
position: location,
map: map,
id: counter
});
inwindow.setContent(inputForm);
inwindow.open(map, marker);
markers.push(marker);
var deleteButton = '<button id="deleteButton" data-id="' + counter + '">Delete</button>';
google.maps.event.addListener(marker, 'rightclick', function () {
infowindow.setContent(deleteButton);
infowindow.open(map, marker);
});
}
function deleteMarker(markerId) {
for (var i=0; i<markers.length; i++) {
if (markers[i].id === markerId) {
markers[i].setMap(null);
}
}
}
You can have as many infowindows as you want. The rules I gave you there were more like hints (hence the italic font). You can always adapt it to your needs.
Now you have a few issues in your code:
onsubmit event is triggered when the submit button in a form is clicked. The action should be on the form, not on the button. But you don't have a form here. You can use onclick event instead (like for the delete button).
You get the input value when the infowindow is ready (domready) not after the user has filled the field. Therefore it will always be empty.
You set marker.title = xxx but marker is not available here, plus, you should use the setTitle() method to change a marker title.
Why didn't you use the same technique that I (and you) used for the delete button action? (using the Id, etc.) I suggest that you try to understand what happens there and adapt it to the part where you set the marker title.
If you are still stuck, let me know and I will explain further!
Edit:
JSFiddle demo
Note that there is no tabindex defined on the inputs and buttons, and that I used .focus() to set the focus on the input or button when the infowindow opens.
Hope this helps.

Google Maps v3 markers not refreshing

So I have 3 Divs with hidden Lat Lng inputs, and some ajax pagination to change them out. On the initial load, I have a script that turns each one of the three pairs of Lat Lng inputs into a marker and pushes them into an array. All of this works good.
Now, when I update the 3 divs with my script file, and then try to use the provided v3 API method to clear and redraw the markers, I get the same spots on the map. And then, if I tell it to go back to page one results, it does delete the page 1 markers and I get the markers from page 2 on my map.
Here is the javascript:
var map;
var markers = [];
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(37.09024, -96.712891),
zoom: 3
};
map = new google.maps.Map(document.getElementById("map-canvas"),
mapOptions);
setRGBmarkers();
}
function setRGBmarkers() {
markers.push(new google.maps.Marker({
position: new google.maps.LatLng(
Number(document.getElementById("address-0-Lat").value),
Number(document.getElementById("address-0-Lng").value)
),
map: map
}));
//removed other markers for brevity
}
function setAllMap(map) {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(map);
}
}
function clearMarkers() {
setAllMap(null);
}
function deleteMarkers() {
clearMarkers();
markers = [];
}
var getPage = function () {
var $a = $(this);
var options = {
url: $a.attr("href"),
type: "get"
};
$.ajax(options).done(function (data) {
var target = $a.parents("div.pagedList").attr("data-nerd-target");
$(target).replaceWith(data);
});
deleteMarkers();
setRGBmarkers();
alert('done');
return false;
}
$(".body-content").on("click", ".pagedList a", getPage);
So it successfully goes out and gets the results. I'm guessing it somehow is running delete and set before its actually done replacing the markers so its setting the 'unreplaced data' again, hence why going back to page one results finally in page 2's markers showing up? Here's a snippet of what the div looks like if needed:
<div class="panel-body">
Event Description
<input id="address-0-Lat" type="hidden" value="34.0519079">
<input id="address-0-Lng" type="hidden" value="-118.24389300000001">
</div>
Well, Anto is correct, and upon investigating the jQuery documentation for the ajax() function, I see the correct place to put the code would be like so:
var getPage = function () {
var $a = $(this);
var options = {
url: $a.attr("href"),
type: "get"
};
$.ajax(options).done(function (data) {
var target = $a.parents("div.pagedList").attr("data-nerd-target");
$(target).replaceWith(data);
deleteMarkers();
setRGBmarkers();
alert('done');
});
return false;
}
$(".body-content").on("click", ".pagedList a", getPage);
Where the 'done' function is executed once the response comes back. Documenation and examples can be found here: http://api.jquery.com/jquery.ajax/

google maps api v3 multiple markers infowindow onclick works but not when called outside

I have a weird problem and maybe I am just not seeing it clearly. It definitely always helps to have others look at my code. Anyways, I have a drop down menu with options in it, needless to say, onchange it calls a function to open an infowindow. The listener for the click works perfectly fine when displaying the info window, but the handleSelected() function does not display anything.:
<select size='37' id='dpMenu' onchange='handleSelected(this)'>
Now I have an array for my markers outside of my function that creates the markers.
var gmarkers = [];
var oldInfoWin;
var map;
function createEpiMarker(map,point,epi_icon,html,name,detail,iqrid) {
var epimarker = new google.maps.Marker({
position: point,
map: map,
icon: epi_icon
});
epimarker.infowindow = new google.maps.InfoWindow({content: html });
google.maps.event.addListener(epimarker, "click", function() {
epimarker.infowindow.open(map, epimarker);
oldInfoWin = epimarker.infowindow;
infoWindowOpen = true;
});
gmarkers.push(epimarker);
}
This code here handles the dropdown menu selection:
function handleSelected(opt){
var i = opt[opt.selectedIndex].index - 1;
if(i != -1){
gmarkers[i].infowindow.open(map, gmarkers[i]);
oldInfoWin = gmarkers[i].infowindow;
infoWindowOpen = true;
}
}

Google Maps v3 event click in cycle

I have problem with script, can someone help me?
//Add event to google maps click => open marker.infobox
for(var marker in markersWithArray){
var lastInfoWindow; //Get lastInfoWindow for close google maps infowindow
var markerI = markersWithArray[marker]; //Get marker from loop
var infoWindow = markerI.infoWindow; //get infoWindow from marker, work prefectly
console.log(infoWindow) // => all time good, object with
// info box. All time unique id and content.
google.maps.event.addListener(markerI, 'click', function() {
console.log(infoWindow); //Problem here, object too, but id and content have
//a last value what recorded on top (console.log)
//last value of cycle
if(lastInfoWindow)
lastInfoWindow.close();
infoWindow.open(map, this);
lastInfoWindow = infoWindow;
});
}
Can anyone tell me how to get value in cycle to event "google.maps.event.addListener" ??
Thx :).
If your marker has an infowindow as a property (I don't think it is a documented property, but your question implies it exists), this should work:
google.maps.event.addListener(markerI, 'click', function() {
console.log(this.infoWindow);
if(lastInfoWindow)
lastInfoWindow.close();
this.infoWindow.open(map, this);
lastInfoWindow = this.infoWindow;
});

Categories

Resources