problem with openInfoWindowHtml for multiple points using events - google-maps

I am a beginner and using openInfoWindowHtml to show the balloon text. my application has an option to show single location and multiple location.
My single location balloon text works fine using openInfoWindowHtml();
But when i go in for multiple, it always shows the last points text and the click event for all the points never happens.
code snippet:
var markers =[];
for(var i=0;i<(geoList.length)-1;i++)
{
var geo = (geoList[i]).split(',');
map.setCenter(new GLatLng(geo[3], geo[4]), 2);
var ip_point = new GLatLng(geo[3], geo[4]);
//creating a marker
marker = new GMarker(ip_point);
map.addOverlay(marker);
markers[i] = marker;
// The ballon text which shows the details of the ip address
var ip = "<div style=\"font-family:Verdana;font-size:10px;text-align:left\">";
//var dbName = base64_decode(geo[5]); // added on 14Dec2009
//If IP is not found it goes to else loop
if(geo.length== 9){
ip += "<span class=\"FSColorBold\">"+geo[5]+"</span><br /> ";
ip += "<?php __('IP:'); ?>"+geo[6]+"<br />";
ip += "<?php __('ID:'); ?>"+geo[7]+"<br />";
ip += "<?php __('Last Accessed: '); ?>"+geo[8]+"<br />";
ip += geo[2]+","+geo[1]+"<br />";
}
}
// shows IP details info by default
map.openInfoWindow(map.getCenter(),ip);
// Reloads the IP details info on clicking the marker
GEvent.addListener(marker, "click", function(){
marker.openInfoWindowHtml(ip+'');});
The points are in a loop and the event listeners are outside the loop.
Can anyone tell me exactly what went wrong?

You are only associating the click event with the last marker. You need call GEvent.addListener for each marker that you are adding to the map.
You also need to make sure that when the event is fired the marker in the callback is the marker that you associated with the event. You can do that by moving your marker creation code into a separate function (takes advantage of Javascript Closures to ensure the marker in the callback is the marker in scope in the outer function).
Check out this example based on your sample (code).

Related

Open Google Maps InfoWindow based on certain criteria

I want to open a Google Maps InfoWindow based on whether or not one of my buildings is throwing a building alarm. The buildings I have the markers on all have alarm states (on or off), and if they are in alarm state, I am changing the color of the marker to yellow or red, depending on the severity of the alarm. When the alarms are "red" alarms, the marker is animated with the google.maps.Animation.BOUNCE effect.
The bounce effect is sometimes not enough to garner attention (we leave this screen open on a wall, and the data in the $(this).children(".alarm-count") div below changes dynamically due to another script we have running on the site in the background.
I already know how to change the markers based on the alarm state, can I also open an InfoWindow within the same condition? I have tried this:
google.maps.event.addListener(map,'idle',(function(marker,i){
return function(){
infowindow.setContent(
'<div class="infowindow-inner">'+
'<a href="'+bldgGfx[i]+'" onclick="window.open('+bldgGfx[i]+');return false;" target="_blank" title="'+bldgName[i]+' ('+bldgAddr[i]+')">'+
'<h2>'+bldgName[i]+'</h2>'+
'<h4>'+bldgAddr[i]+'</h4>'+
'<p>'+mainMeter[i]+' kW</p>'+
'<p>'+alarmCount[i]+' Alarms</p>'+
'</div>'
);infowindow.open(map,marker);
}
})(marker,i));
but it doesn't seem to be working.
The long and short of it is I need to evaluate one value per marker in my page, and open (or not open) the InfoWindow for each building based on that value.
Here is my code:
$(".building").each(function(i){
bldgNo[i] = $(this).children(".bldg-no").html().slice(1);
bldgName[i] = $(this).children(".bldg-name").html();
bldgAddr[i] = $(this).children(".bldg-address").html();
bldgGfx[i] = $(this).children(".bldg-graphic").html();
mainMeter[i] = $(this).children(".main-meter").html();
alarmCount[i] = $(this).children(".alarm-count").html();
latitude[i] = $(this).children(".latitude").html();
longitude[i] = $(this).children(".longitude").html();
if (alarmCount[i]!="N/A"){alarmCount[i]=alarmCount[i].slice(0,-3);}
if (alarmCount[i]>"0" && alarmCount[i]!="N/A"){
marker=new google.maps.Marker({position:new google.maps.LatLng(latitude[i],longitude[i]),map:map,shadow:shadow,icon:redIcon,title:bldgName[i]+" \n"+bldgAddr[i],optimized:false});marker.setAnimation(google.maps.Animation.BOUNCE);
////
//// THE COMMAND TO OPEN THE INFOWINDOW WILL GO HERE, RIGHT?
////
}
else if ($(this).hasClass("new")||(mainMeter[i]=="N/A")||(!isNumber(mainMeter[i]))) {
marker=new google.maps.Marker({position:new google.maps.LatLng(latitude[i],longitude[i]),map:map,shadow:shadow,icon:yellowIcon,title:bldgName[i]+" \n"+bldgAddr[i],optimized:false});marker.setAnimation(google.maps.Animation.NULL);}
else {
marker=new google.maps.Marker({position:new google.maps.LatLng(latitude[i],longitude[i]),map:map,shadow:shadow,icon:greenIcon,title:bldgName[i]+" \n"+bldgAddr[i],optimized:false});marker.setAnimation(google.maps.Animation.NULL);}
markersArray.push(marker);
google.maps.event.addListener(marker,'click',(function(marker,i){
return function(){
infowindow.setContent(
'<div class="infowindow-inner">'+
'<a href="'+bldgGfx[i]+'" onclick="window.open('+bldgGfx[i]+');return false;" target="_blank" title="'+bldgName[i]+' ('+bldgAddr[i]+')">'+
'<h2>'+bldgName[i]+'</h2>'+
'<h4>'+bldgAddr[i]+'</h4>'+
'<p>'+mainMeter[i]+' kW</p>'+
'<p>'+alarmCount[i]+' Alarms</p>'+
'</div>'
);infowindow.open(map,marker);
}
})(marker,i));
i++;
});
Since many buildings may be "on alert", you'll want a InfoWindow array (in my demo it's a global because I use an inline call); however, the screen may get cluttered very easily. I wrote a Z-Index routine to bring a clicked InfoWindow to front. You might also want to consider MarkerWithLabel or InfoBubble because in my opinion they look better than the vanilla InfoWindow.
Please see the demo
demo side-by-side with code
I'll only copy some of the parts that are very different.
var infowindows = [];
function initialize() {
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
// MANY LINES SKIPPED
// ...
$(this).children(".longitude").html();
infowindows[i] = new google.maps.InfoWindow({
content:'<div class="infowindow"
onclick="bringToFront('+i+')">'+bldgName[i]+'</div>'});
if (alarmCount[i]>0 && alarmCount[i]!="N/A"){
// marker=new google.maps.Marker({position:new google.maps.LatLng(latitude[i],longitude[i]),map:map,shadow:shadow,icon:redIcon,title:bldgName[i]+" \n"+bldgAddr[i],optimized:false});marker.setAnimation(google.maps.Animation.BOUNCE);
marker = new google.maps.Marker({position:new google.maps.LatLng(latitude[i],longitude[i]),map:map,title:"red"});
infowindows[i].open(map,marker);
//// THE COMMAND TO OPEN THE INFOWINDOW WILL GO HERE, RIGHT?
}
...
google.maps.event.addListener(marker,'click',(function(marker,i){
return function(){
infowindows[i].open(map,marker);
bringToFront(i);
}
})(marker,i));
});
}
function bringToFront(windowIndex) {
console.log(windowIndex);
for (var i = infowindows.length-1, n = 0; i >= n; i--) {
infowindows[i].setZIndex(0);
}
infowindows[windowIndex].setZIndex(1);
}

getting the right variables in a foreach loop (flex - googlemaps)

I'm trying to get specific variables out of a for each loop. These variables are used to display a click event on a marker on a map. If you click the marker on the map, the details pop over it. Now these details are being overwritten each time the loop starts (50 times). The solution I'm looking for, let's me select a marker on the map with the according detail attached to it.
There might be an easy solution but I haven't found it yet.
The code :
for each(artistXML in artistList.events.event)
{
var gLat:int = artistXML.venue.location.*::point.*::lat;
var gLong:int = artistXML.venue.location.*::point.*::long;
var evntLng:LatLng = new LatLng(gLat,gLong);
var title:String = artistXML.title;
var wanneer:String = artistXML.startDate;
var waar:String = artistXML.venue.location.city;
var pic:String = artistXML.venue.image.(#size=="medium");
var marker:Marker = new Marker(new LatLng(gLat, gLong));
var info:InfoWindowOptions = new InfoWindowOptions();
marker.addEventListener(MapMouseEvent.CLICK, function(event:Event):void {
var marker:Marker = event.target as Marker;
marker.openInfoWindow(new InfoWindowOptions({contentHTML: "<p><b>" + title + "</b></p><br/><p>" + wanneer + "</p> <br/> <p>" + waar + "</p>"}));
});
map.addOverlay(marker);
Goverlay++;
}
Thanks
You need to store a reference to the values somewhere before you start the next loop.
I'm not sure what the structure of your Marker and InfoWindowOptions classes are, so there might be a better way, but here's a naive solution:
Create 2 arrays called mapMarkers and infoWindows. For each loop push the new Marker and the new InfoWindowOptions instances into the appropriate arrays. You'll need to set those variables on the InfoWindowOptions too. Then in your click handler you can lookup the index of the Marker that was clicked (mapMarkers.indexOf(marker)) and use that index to get the corresponding InfoWindowOptions.

How to make openInfoWindowHtml work in Google Maps 2

I'm setting up a extjs panel with a GMap2 embedded. Here's the setup:
map = new GMap2(document.getElementById("gmappanel"));
map.setCenter(new GLatLng(58.019257, -115.572402), 3);
map.setUIToDefault();
I'm using the example from here so that when I click a marker, I get an info window. The problem is, the event fires and I can see the proper HTML in the console, but nothing else happens. The info window simply doesn't open. no error, nothing.
Here's the code for that:
function createMarker(point, val) {
var marker = new GMarker(point);
var name = val.data.name;
var html = "<table class='marker'>";
html += "<tr><td>Name: </td><td>" + name + "</td></tr>";
html += "</table>";
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml(html);
debug("Marker fired");
});
return marker;
}
Here's how I call it:
var marker = createMarker(point,store.getAt(i));
Any ideas?
Sounds like your HTML is not valid. Can you dump some example html data that you are passing to the openInfoWindowHtml? Your createMarker function works just fine with :
var html = "<table class='marker'><tr><td>Name: </td><td> sometext </td></tr></table>";
what version of the api are you using? 2.x?
Possibly you want bindInfoWindowHtml, not openInfoWindowHtml.
Something along the lines of..
function createMarker(point, val) {
var marker = new GMarker(point);
var name = val.data.name;
var html = "<table class='marker'>";
html += "<tr><td>Name: </td><td>" + name + "</td></tr>";
html += "</table>";
marker.bindInfoWindowHtml(html);
return marker;
}
You also have two marker variables defined in different scopes, check to make sure you have the listener on the right "marker".

How to get markers after calling drive directions in Google Maps API?

I just started working using Google Maps API yesterday, and trying to set up drive directions to my map. My problem is: when I call the function load,
// [...]
gdir = new GDirections(map, directionsPanel);
// [...]
gdir.load("from: " + fromAddress + " to: " + toAddress);
it returns a map whose markers are not draggable. So, I need to make them draggable in order to recalculate the directions, but I can't get the markers objects.
Someone knows how can I do it?
You need to add a handler on the GDirections object for the addoverlay event:
GEvent.addListener(gdir, "addoverlay", onGDirectionsAddOverlay);
When your onGDirectionsAddOverlay handler is called you can iterate through the new markers and replace them with draggable copies:
for (var i = 0; i <= gdir.getNumRoutes(); i++)
{
var originalMarker = gdir.getMarker(i);
latLngs[i] = originalMarker.getLatLng();
icons[i] = originalMarker.getIcon();
newMarkers[i] = new GMarker(latLngs[i], { icon: icons[i], draggable: true, title: 'Kan flyttes' });
map.addOverlay(newMarkers[i]);
// add stuff to your newMarkers[i] drag end event...
// ...
//Bind 'click' event to original markers 'click' event
copyClick(newMarkers[i], originalMarker);
// Now we can remove the original marker safely
map.removeOverlay(originalMarker);
}
You can find a working example of this here (source).

Customize Google Maps info window?

I'm working on a website of a client, a local church. I've embedded a Google Map using the Link feature on the Maps page. The info window on the map includes "Reviews," and the church is concerned about this. Is there a way to remove that from the info window? I don't want to remove any reviews themselves, just that link on the info window?
Is this possible? Are there any other customization options (besides the size) one can manipulate via the query string?
Nearly 2 years ago, I created a custom map with complete control over the contents of the bubble, using the API and some code manipulation. Click on the above link for a demo. I've cleaned up the code for this answer, although to implement you'll need to replace all YOUR__BLANK__HERE text with the appropriate values.
Step 1: Call the gMaps API
<script src="http://maps.google.com/maps?file=api&v=2&key=YOUR_API_KEY_HERE"
type="text/javascript">
</script>
Step 2: In the body of your document, create an element with id "map". Size and position it with CSS. It requires a height and width.
<div id="map" class="content"></div>
Step 3: After the div has been defined in the DOM, it is safe to insert the following script tag:
<script type="text/javascript">
//<![CDATA[
// Check to see if this browser can run the Google API
if (GBrowserIsCompatible()) {
var gmarkers = [];
var htmls = [];
var to_htmls = [];
var from_htmls = [];
var i=0;
// A function to create the marker and set up the event window
function createMarker(point,name,html) {
var marker = new GMarker(point);
// The info window version with the "to here" form open
to_htmls[i] = html +
'<br />Start address:<form action="http://maps.google.com/maps" method="get">' +
'<input type="text" SIZE=40 MAXLENGTH=40 name="saddr" id="saddr" value="" /><br>' +
'<INPUT value="Get Directions" TYPE="SUBMIT">' +
'<input type="hidden" name="daddr" value="' + point.lat() + ',' + point.lng() +
// "(" + name + ")" +
'"/>';
// The inactive version of the direction info
html = html + '<br><a href="javascript:tohere('+i+')">Get Directions<'+'/a>';
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml(html);
});
gmarkers[i] = marker;
htmls[i] = html;
i++;
return marker;
}
// functions that open the directions forms
function tohere(i) {
gmarkers[i].openInfoWindowHtml(to_htmls[i]);
}
// Display the map, with some controls and set the initial location
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(
YOUR_LATITUDE_HERE,
YOUR_LONGITUDE_HERE
),
YOUR_ZOOM_LEVEL_HERE // a value of 13 worked for me
);
// Set up one marker with an info window
var marker = createMarker(
new GLatLng(
YOUR_LATITUDE_HERE,
YOUR_LONGITUDE_HERE
),
'YOUR_MARKER_NAME_HERE',
'<i>YOUR_HTML_HERE<'+'/i>');
/* repeat the process to add more markers
map.addOverlay(marker);
var marker = createMarker(
new GLatLng(
YOUR_LATITUDE_HERE,
YOUR_LONGITUDE_HERE
),
'YOUR_MARKER_NAME_HERE',
'<i>YOUR_HTML_HERE<'+'/i>');
map.addOverlay(marker);*/
}
// display a warning if the browser was not compatible
else {
alert("Sorry, the Google Maps API is not compatible with this browser");
}
// This Javascript is based on code provided by the
// Blackpool Community Church Javascript Team
// http://www.commchurch.freeserve.co.uk/
// http://www.econym.demon.co.uk/googlemaps/
//]]>
</script>
Using this code, the bubble contains the html you specify in YOUR_HTML_HERE plus a link to Get Directions, which (when clicked) turns into a textbox asking for a starting address. The result of the query, unfortunately, opens in a new browser window (since, at time of original publishing the API did not include directions capabilities)
I think I found the answer to my own question. The info window itself can't be modified, but by linking to the map for the address itself rather than the church as a business entity does the trick. The driving directions link is still there and that's mostly all they wanted.