Infowindow in Googlemaps wont fill - javascript

I've got the following problem with Googlemaps.
I've created a createMarker function which returns a marker which I publish with addOverlay(). This works perfect, the marker get shown but the only problem is the click event voor the marker, I want a infowindow which is populated with the 'I want this text to be published' text, instead it gets populated with a var called html which I set in the beginning of my code (var html = 'test';), I received earlier a message with 'html is not defined', this is why is set the html var. Every infowindow has the text 'test' in it. I've tried using updateInfoWindow() but that doesn't work, anyone familiar with this problem? I can supply you with the full source but I think the createMarker function should be enough.
function GM_load() {
map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.enableScrollWheelZoom();
map.setMapType(G_HYBRID_MAP);
geocoder = new GClientGeocoder();
GM_showItems();
}
function GM_showItems() {
GDownloadUrl("modules/Googlemaps/ajax/getItems.php", function(data, responseCode) {
var xml = GXml.parse(data);
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
//start
var itemid = markers[i].getAttribute('id');
var title = markers[i].getAttribute('name');
var address = markers[i].getAttribute('address');
var city = markers[i].getAttribute('city');
var x = 0;
if (geocoder) {
geocoder.getLatLng(address + ' ' + city,
function(point) {
if (!point) {
alert(address + ' ' + city + " not found");
} else {
x = x+1;
Marker = createMarker(point, x);
map.addOverlay(Marker);
}
}
);
}
}
});
}
function createMarker(latlng, number) {
var marker = new GMarker(latlng);
marker.value = number;
GEvent.addListener(marker,"click", function() {
map.openInfoWindowHtml(latlng,'i want this text to be published');
});
return marker;
}

Solved.
I overwrite var html. not perfect but it works.

Related

Google Maps marker has to be clicked twice to register

Sometimes, when I click on a marker once, all of the markers disappear for a second and reappear. Then I have to click again on a marker for the click event to register and the Info-Box to display. I am pretty sure this is also the reason why my markers don't disappear when I call the clearMarkers() function if I haven't already clicked on a marker. Here is my code:
var map;
var markersArray = [];
var cat = "restaurants, All";
var C = [...];
var D = [...];
function initMap() {
// Create a map object and specify the Div element to display it on
loc = {lat: 41.902783, lng: 12.496366};
map = new google.maps.Map(document.getElementById('map'), {
center: loc,
zoom: 14,
disableDefaultUI: true
});
// Displays all of the markers when page loads, all restaurants
getJsonData('yelpdata.php?cat=restaurants, All&lat='+loc.lat+'&lng='+loc.lng, map);
var filtersPanel = document.getElementById('filtersPanel');
var textField1 = document.getElementById('userInput');
// Displays the markers according the value the user is typing (cat)
function useValue() {
clearMarkers();
var textFieldVal = textField1.value;
var ind = findIndex(textFieldVal);
if (ind != -1) {
cat = D[ind];
}
getJsonData('yelpdata.php?cat='+cat+'&lat='+loc.lat+'&lng='+loc.lng, map);
}
// Text box event handlers
//textField1.oninput = useValue;
textField1.onchange = useValue;
textField1.addEventListener("awesomplete-selectcomplete", useValue);
google.maps.event.addListener(map, 'click', function(event) {
latitude = event.latLng.lat();
longitude = event.latLng.lng();
newCenter = {lat: latitude, lng: longitude};
map.setCenter(newCenter);
loc = newCenter;
useValue();
});
var autocomplete = new Awesomplete(textField1, {
list: C,
filter: Awesomplete.FILTER_STARTSWITH,
minChars: 1,
autoFirst: true
});
// Displays the filters panel in the top-left of the screen
map.controls[google.maps.ControlPosition.TOP_LEFT].push(filtersPanel);
}
function findIndex(cat) {
for(var i=0; i<C.length; i++) {
if(C[i] == cat)
return i;
}
return -1;
}
function clearMarkers() {
// Clears the markers from the map and array
for (var i=0; i < markersArray.length; i++) {
markersArray[i].setMap(null);
}
markersArray = [];
}
function getJsonData(url, map) {
// Using AJAX to get the JSON data from the 'yelpdata.php' file and display markers with info-boxes on the map
var request = new XMLHttpRequest; // the main object to request the XML
request.onreadystatechange = function() { // when the request changes state
if (request.readyState == 4) { // success, we have recieved the XML object from sending the request
var json = request.responseText;
var obj = JSON.parse(json);
var numMarkers = obj.businesses.length;
document.getElementById("numResults").innerHTML = numMarkers + " results";
for (var i = 0; i < obj.businesses.length; i++) {
(function(index) {
// Getting all of the attributes for each business from the JSON
var business = obj.businesses[index];
var name = business.name;
var catArr = business.categories;
var catStr = "";
for (j=0; j < catArr.length; j++) {
if (j == 0) {
catStr += catArr[j].title;
} else if (j > 0) {
catStr += ", " + catArr[j].title;
}
}
var reviews = business.review_count;
var rating = business.rating;
var address = business.location.address1 + ", " + business.location.city + ", " + business.location.state;
var coord = {lat: business.coordinates.latitude,
lng: business.coordinates.longitude};
var url = business.url;
var img_url = business.image_url;
// Creating the info-box
var markerInfo = document.createElement('div');
var title = document.createElement('strong'); // name
title.textContent = name;
var text0 = document.createElement('text'); // categories
text0.textContent = catStr;
var text1 = document.createElement('text'); // address
text1.textContent = address;
var text2 = document.createElement('text'); // reviews
text2.textContent = reviews + " reviews";
var text3 = document.createElement('text'); // rating
text3.textContent = rating + " stars";
// Appending the text to the info-box
markerInfo.appendChild(title);
markerInfo.appendChild(document.createElement('br'));
markerInfo.appendChild(text0);
markerInfo.appendChild(document.createElement('br'));
markerInfo.appendChild(text1);
markerInfo.appendChild(document.createElement('br'));
markerInfo.appendChild(text2);
markerInfo.appendChild(document.createElement('br'));
markerInfo.appendChild(text3);
// create the marker on its according position and append into array
var marker = new google.maps.Marker({
map: map,
position: coord
});
// change the opacity of the markers according to rating
if (rating >= 4) {
marker.setOpacity(1.0);
} else if (rating >= 2.5 && rating < 4) {
marker.setOpacity(0.8);
} else if (rating < 2.5) {
marker.setOpacity(0.6);
}
// set the info-box to the marker on click
infoWindow = new google.maps.InfoWindow;
marker.addListener('click', function() {
console.log("Registering");
infoWindow.setContent(markerInfo);
infoWindow.open(map, marker);
});
markersArray.push(marker);
})(i);
}
}
};
request.open('GET', url); // initialize the request
request.send(); // send the request
}
Lets see if this helps...
In this batch of code you are building the infobox content but not setting it until the click event.
// set the info-box to the marker on click
infoWindow = new google.maps.InfoWindow;
marker.addListener('click', function() {
console.log("Registering");
infoWindow.setContent(markerInfo);
infoWindow.open(map, marker);
});
try moving the line that sets the content outside the click event. you should only need to set it once anyway
infoWindow = new google.maps.InfoWindow;
infoWindow.setContent(markerInfo);
marker.addListener('click', function() {
console.log("Registering");
infoWindow.open(map, marker);
});

calling functions inside function

I am using google maps and i have working code to display markers on a map. I now want to put this code inside of a function view_maps() and activate this function on click. So far i get the errors Maximum call stack size exceeded and getAddress is not a function. This works but when the code inside of view_maps() function i get these errors.
function view_maps() {
function marker_map() {
var url = "http://example.co.uk/deliveries/map/get_region_orders";
var region = $("ul#regions").children("li[data-active='1']").attr("class");
var data = {
region: region
};
var obj = {};
var locations = [];
var details_array = [];
$.ajax({
type: "POST",
url: "http://example.co.uk/deliveries/map/get_region_orders",
data: data,
async: false,
success: function(response) {
var result = $.parseJSON(response);
jQuery.each(result, function(i) {
var order_id = result[i].order_id;
var customer_name = result[i].customer_name;
var address_1 = result[i].address_1;
var address_2 = result[i].address_2;
var post_code = result[i].post_code;
var address = post_code;
var details = "<b>Order Number: " + order_id + "</b><br>" + address_1 + "<br>" + address_2 + "<br>" + post_code;
details_array.push(details);
locations.push(address);
});
}
});
obj['address'] = locations;
obj['details'] = details_array;
return (obj);
}
// delay between geocode requests - at the time of writing, 100 miliseconds seems to work well
var delay = 70;
// ====== Create map objects ======
var infowindow = new google.maps.InfoWindow();
var latlng = new google.maps.LatLng(53.381021, -2.608138);
var mapOptions = {
zoom: 9,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var geo = new google.maps.Geocoder();
var map = new google.maps.Map(document.getElementById("marker-map"), mapOptions);
var bounds = new google.maps.LatLngBounds();
// ====== Geocoding ======
function getAddress(search, count, next) {
geo.geocode({
address: search
}, function(results, status) {
// If that was successful
if (status == google.maps.GeocoderStatus.OK) {
// Lets assume that the first marker is the one we want
var p = results[0].geometry.location;
var lat = p.lat();
var lng = p.lng();
// Output the data
var msg = 'address="' + search + '" lat=' + lat + ' lng=' + lng + '(delay=' + delay + 'ms)<br>';
document.getElementById("messages").innerHTML += msg;
// Create a marker
createMarker(search, count, lat, lng);
}
// ====== Decode the error status ======
else {
// === if we were sending the requests to fast, try this one again and increase the delay
if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
nextAddress--;
delay++;
} else {
var reason = "Code " + status;
var msg = 'address="' + search + '" error=' + reason + '(delay=' + delay + 'ms)<br>';
//document.getElementById("messages").innerHTML += msg;
}
}
next();
});
}
// ======= Function to create a marker
function createMarker(add, count, lat, lng) {
var contentString = add;
var marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
map: map,
zIndex: Math.round(latlng.lat() * -100000) << 5
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(details_array[count]);
//infowindow.setContent(contentString);
infowindow.open(map, marker);
});
bounds.extend(marker.position);
}
// ======= An array of locations that we want to Geocode ========
//console.log(marker_map());
var locations = marker_map();
var addresses = locations.address;
var details_array = locations.details;
// ======= Global variable to remind us what to do next
var nextAddress = 0;
// ======= Function to call the next Geocode operation when the reply comes back
function theNext() {
if (nextAddress < addresses.length) {
setTimeout('getAddress("' + addresses[nextAddress] + '","' + nextAddress + '",theNext)', delay);
nextAddress++;
} else {
// We're done. Show map bounds
map.fitBounds(bounds);
}
}
// ======= Call that function for the first time =======
theNext();
}
How do i solve? I think this is to do with scope of functions because getAddress is clearly a function.
you have to change your theNext function with this one.
function theNext() {
if (nextAddress < addresses.length) {
setTimeout(getAddress(addresses[nextAddress],nextAddress,theNext), delay);
nextAddress++;
} else {
// We're done. Show map bounds
map.fitBounds(bounds);
}
}
see change in setTimeout, I am Calling function not passing string (which will evaluate later and search in global scope)
I also create a demo for proof of concept. Enjoy :)

how to link sidebar to the markers

I am trying to add sidebar. I am using name variable for links on the sidebar which are fetched from the database and it is available to me as an array. I am not able to loop twice as that puts QUERY_LIMIT to the google database.
Can anybody provide me logic on the way how to work on this functionality?
Here is my script:
<script type="text/javascript">
var markers = [];
var side_html = "";
var icon1 = "prop.png";
var icon2 = "office.png";
var locations = <?php echo $add_js ?>;
var name = <?php echo $name_js ?>
//function that will be used to handle clicks on the links in the sidebar
function myclick(num) {
google.maps.event.trigger(locations[num], "click");
}
function geocodeAddress(i)
{
geocoder.geocode({'address' : locations[i]},
function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
createMarker(results[0].geometry.location, i);
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
function createMarker(latlng,i) {
var marker = new google.maps.Marker({
map : map,
icon : icon1,
position : latlng
});
var infowindow = new google.maps.InfoWindow({
size: new google.maps.Size(150,50),
disableAutoPan: true
});
google.maps.event.addListener(marker, 'mouseover', function() {
marker.setIcon(icon2);
infowindow.setContent(locations[i]);
infowindow.open(map, marker);
});
google.maps.event.addListener(marker, 'mouseout', function() {
marker.setIcon(icon1);
infowindow.setContent(locations[i]);
infowindow.close(map, marker);
});
return marker;
}
var map = new google.maps.Map(document.getElementById('map'), {
zoom : 10,
center : new google.maps.LatLng(28.6139, 77.2089),
mapTypeId : google.maps.MapTypeId.ROADMAP
});
//var infowindow = new google.maps.InfoWindow({size: new google.maps.Size(150,50)});
var geocoder = new google.maps.Geocoder();
for (var i = 0 ; i < locations.length; i++) {
geocodeAddress(i);
// link to the sidebar HTML that will open the info window for the record being processed
side_html += '' + name + '<br />';
document.getElementById("side_bar").innerHTML = side_html;
}//end of for loop
</script>
I am getting proper markers in the output, but as the sidebar links i am getting whole of the name array each time and the link is not responding even to click events.
if "name" is an array, this should work:
for (var i = 0 ; i < locations.length; i++) {
geocodeAddress(i);
// link to the sidebar HTML that will open the info window for the record being processed
side_html += '' + name[i] + '<br />';
}//end of for loop
document.getElementById("side_bar").innerHTML = side_html;
Solved my problem at last!
I needed to split my array of strings first before using them to display in the sidebar link.
var name = names[i].split(",");
Final Soltion code:
for (var i = 0 ; i < locations.length; i++)
{
geocodeAddress(i);
var name = names[i].split(",");
side_html += '' + name + '<br />';
}
document.getElementById("side_bar").innerHTML = side_html;

Update marker in real time

I need fetch the new position from json file which will be updated at regualr intervals in order to update it on the map without reloading the whole page repeatedly. How can I do without using Ajax
if (GBrowserIsCompatible()) {
//==add controls
var map = new GMap(document.getElementById("map"));
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(-29.870879, 30.977258),15);
var htmls = [];
var i = 0;
//create marker and set up infoWindow
function createMarker(point,ID,name) {
var marker = new GMarker(point);
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml(ID+"<br/>Name: " +name);
});
return marker;
}
process_Data = function(doc) {
//parse json file
var jsonData = eval('(' + doc + ')');
// ======== Plots the markers on Google Maps============
for (var i=0; i<jsonData.markers.length; i++) {
var point = new GLatLng(jsonData.markers[i].lat, jsonData.markers[i].lng);
var marker = createMarker(point,jsonData.markers[i].ID,jsonData.markers[i].name);
map.addOverlay(marker);
}
}
GDownloadUrl("points.json", process_Data);
}
var marker;
// every 10 seconds
setInterval(updateMarker,10000);
function updateMarker() {
$.post('/path/to/server/getPosition',{}, function(json) {
var LatLng = new google.maps.LatLng(json.latitude, json.longitude);
marker.setPosition(LatLng);
});
}

How do I use Google Maps geocoder.getLatLng() and store its result in a database?

Hey everybody! Im trying to use getLatLng() to geocode a list of postal/zip codes and store the generated point in the database to be placed on a map later. This is what I've got so far:
$(".geocodethis").click(function () {
var geocoder = new GClientGeocoder();
var postalCode = $(this).siblings(".postal").val();
var id = $(this).siblings(".id").val();
geocoder.getLatLng(postalCode, function (point) {
if (!point) {
alert(postalCode + " not found");
} else {
alert(point);
var serializedPoint = $.param(point);
//Geocode(id, point);
}
});
});
function Geocode(id, point) {
alert(point);
$.post("/Demographic/Geocode/" + id, point, function () {
alert("success?");
});
}
but I'm getting this.lat is not a function in my error console when i try to serialize the point object or use it in $.post()
From my research, I understand that geocoder.getLatLng() is asynchronous, how would that affect what I'm trying to do? I'm not running this code in a loop, and I'm trying to post the point using the anonymous callback function.
How can I save the information from point to use later?
Update
Creating a marker and trying to post that still results in the this.lat is not a function in the error console.
$(".geocodethis").click(function () {
var geocoder = new GClientGeocoder();
var postalCode = $(this).siblings(".postal").val();
var id = $(this).siblings(".id").val();
geocoder.getLatLng(postalCode, function (point) {
if (!point) {
alert(postalCode + " not found");
} else {
alert(point);
var marker = new GMarker(point);
$.post("/Demographic/Geocode/" + id, marker, function () {
alert("success?");
});
}
});
});
** Another Update **
I really need to save the geocoded address for later, even if I store the latitude/longitude values in my database and remake the marker when I'm ready to put it onto a map. Again, serializing or posting - seemingly using the point in any way other than in google maps functions gives the this.lat is not a function exception in my error log.
I'm using asp.net mvc - are there any frameworks out there that would make this easier? I really need help with this. Thanks.
If your stuck for 2 days maybe a fresh v3 start would be a good thing, this snipped does a similair job for me...
function GetLocation(address) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
ParseLocation(results[0].geometry.location);
}
else
alert('error: ' + status);
});
}
}
function ParseLocation(location) {
var lat = location.lat().toString().substr(0, 12);
var lng = location.lng().toString().substr(0, 12);
//use $.get to save the lat lng in the database
$.get('MatchLatLang.ashx?action=setlatlong&lat=' + lat + '&lng=' + lng,
function (data) {
// fill textboss (feedback purposes only)
//with the found and saved lat lng values
$('#tbxlat').val(lat);
$('#tbxlng').val(lng);
$('#spnstatus').text(data);
});
}
Have you tried this?
$(".geocodethis").click(function () {
var geocoder = new GClientGeocoder();
var postalCode = $(this).siblings(".postal").val();
var id = $(this).siblings(".id").val();
geocoder.getLatLng(postalCode, function (point) {
if (!point) {
alert(postalCode + " not found");
} else {
alert(point);
var marker = new GMarker(point);
map.addOverlay(marker);
obj = {lat: marker.position.lat(),
lng: marker.position.lng()};
$.post("/Demographic/Geocode/" + id, obj, function () {
alert("success?");
});
}
});
});
I haven't used V2 in a long time, so I'm not sure about the exact syntax, but the point is to create an object from the information you need (lat/lng) and serialize that.
Also, an upgrade to V3 is much recommended, if plausible.
You need to set a marker on the map, which takes a lat/long. You can save that info however you want or display immediately. (Code truncated for demo purpose)
map = new google.maps.Map(document.getElementById("Map"), myOptions);
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var marker = new google.maps.Marker({
position: results[0].geometry.location
});
marker.setMap(map);
}
}
UPDATE (FOR v2)
$(".geocodethis").click(function () {
var geocoder = new GClientGeocoder();
var postalCode = $(this).siblings(".postal").val();
var id = $(this).siblings(".id").val();
geocoder.getLatLng(postalCode, function (point) {
if (!point) {
alert(postalCode + " not found");
} else {
map.setCenter(point, 13);
var marker = new GMarker(point);
map.addOverlay(marker);
}
});
});
In V3 the coordinates must be first serialized as a string as shown by Arnoldiuss, before sending as json post data.
var lat = latlong.lat().toString().substr(0, 12);
var lng = latlong.lng().toString().substr(0, 12);
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<%# taglib prefix="s" uri="/struts-tags"%>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?key=AIzaSyDS1d1116agOa2pD9gpCuvRDgqMcCYcNa8&sensor=false"></script>
<script type="text/javascript">
function initialize() {
var latitude = document.getElementById("latitude").value;
latitude = latitude.split(",");
var longitude = document.getElementById("longitude").value;
longitude = longitude.split(",");
var locName = document.getElementById("locName").value;
locName = locName.split(",");
var RoadPathCoordinates = new Array();
RoadPathCoordinates.length = locName.length;
var locations = new Array();
locations.length = locName.length;
var infowindow = new google.maps.InfoWindow();
var marker, i;
var myLatLng = new google.maps.LatLng(22.727622,75.895719);
var mapOptions = {
zoom : 16,
center : myLatLng,
mapTypeId : google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
//To Draw a line
for (i = 0; i < RoadPathCoordinates.length; i++)
RoadPathCoordinates[i] = new google.maps.LatLng(latitude[i],longitude[i]);
var RoadPath = new google.maps.Polyline({
path : RoadPathCoordinates,
strokeColor : "#FF0000",
strokeOpacity : 1.0,
strokeWeight : 2
});
//Adding Marker to given points
for (i = 0; i < locations.length; i++)
locations[i] = [locName[i],latitude[i],longitude[i],i+1];
for (i = 0; i < locations.length; i++)
{marker = new google.maps.Marker({
position : new google.maps.LatLng(locations[i][1], locations[i][2]),
map : map
});
//Adding click event to show Popup Menu
var LocAddress ="";
google.maps.event.addListener(marker, 'click', (function(marker, i)
{ return function()
{
GetAddresss(i);
//infowindow.setContent(locations[i][0]);
infowindow.setContent(LocAddress);
infowindow.open(map, marker);
}
})(marker, i));}
function GetAddresss(MarkerPos){
var geocoder = null;
var latlng;
latlng = new google.maps.LatLng(latitude[MarkerPos],longitude[MarkerPos]);
LocAddress = "91, BAIKUNTHDHAAM"; //Intializing just to test
//geocoder = new GClientGeocoder(); //not working
geocoder = new google.maps.Geocoder();
geocoder.getLocations(latlng,function ()
{
alert(LocAddress);
if (!response || response.Status.code != 200) {
alert("Status Code:" + response.Status.code);
} else
{
place = response.Placemark[0];
LocAddress = place.address;
}
});
}
//Setting up path
RoadPath.setMap(map);
}
</script>
</head>
<body onload="initialize()">
<s:form action="mapCls" namespace="/">
<s:hidden key="latitude" id="latitude"/>
<s:hidden key="longitude" id="longitude"/>
<s:hidden key="locName" id="locName"/>
<div id="map_canvas" style="float:left;width:70%;height:100%"></div>
</s:form>
</body>
</html>
I am doing reverse Geocoding, and want address of marker using lat and longitude. M facing problem with function "GetAddresss()", line "geocoder.getLocations(latlng,function ()" is not working properly. what should I Do?

Categories

Resources