Google Maps: load markers from JSON - javascript

I have the following JS which processes a form, returns the results as JSON and then should plot the json as markers on the map. Although I do get a json response, nothing is plotted. I'm not very familiar with Javascript, so could someone let me know what the error is below?
Thanks
The JSON:
[
{
"lat": "53.598660370500596",
"lng": "-113.59166319101564"
}
]
The Javascript
$(function () {
$('#search').click(function () {
var projectNumber = $('#project_number').val();
var setdistance = $('#setdistance').val();
var companyType = $('#company_type').val();
//syntax - $.post('filename', {data}, function(response){});
$.post('business_location_get_map.php', {
project_number: projectNumber,
setdistance: setdistance,
company_type: companyType
}, function (ret) {
$('#result').html(ret);
});
});
});
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(53.5435640000, -113.5),
zoom: 8
};
var map = new google.maps.Map(document.getElementById("map_canvas"),
mapOptions);
}
google.maps.event.addDomListener(window, 'load', initialize);
function plot() {
$.getJSON('business_location_get_map.php', function (data) {
var location;
$.each(data, function (key, val) {
addMarker(key.lat, key.lng);
});
});
}
function addMarker(lat, lng) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
map: map,
icon: redImage
});
markersArray.push(marker);
}
google.maps.event.addDomListener('search', 'click', plot);
EDIT:
I've changed
(key.lat, key.lng)
to
(val.lat, val.lng)
I still have the same results,

The problem is about $.each()
You are passing key.lat and key.lng to addMarker(), however key is the index of the current element in array. You must use val as it's the real value:
$.each(data, function (key, val) {
addMarker(val.lat, val.lng);
});
More info about the usage of $.each(): https://api.jquery.com/each/

Related

Call function for content of infowindow when opening not only on init

I have some objects with markers. These objects have dynamic data and I would like to output them in the infowindow of the marker of the object.
So far this is what I have:
function createRandomObjectWithAMarker() {
var marker;
var aData = "dataToDisplay";
var infowindow = new google.maps.InfoWindow({
content:callThisFunctionWhenOpenWindow(aData)
});
marker.addListener('click', function() {
infowindow.open(map, marker);
});
randomObject = {
/*
someData
*/
marker: marker
};
return randomObject;
}
And I would like that this function to be called when I click the marker to show the return modifiedData as the content of the infoWindow.
function callThisFunctionWhenOpenWindow(aData){
/*
do some stuff on aData
*/
return modifiedData;
}
But actually, this function is called once: only when I init the randomObject with the call of createRandomObjectWithAMarker(). So if I show the infoWindow after some time, when the datas would not be the same as when the script starter, it will still display the same output.
Is there any way to do that? If yes how?
Try something like this?
This way the infowindow (and it's data) is only created when you click the marker
function createRandomObjectWithAMarker() {
var marker;
var aData = "dataToDisplay";
marker.addListener('click', function() {
var infowindow = new google.maps.InfoWindow({
content:callThisFunctionWhenOpenWindow(aData)
});
infowindow.open(map, marker);
});
randomObject = {
/*
someData
*/
marker: marker
};
return randomObject;
}

How to make function run, then wait for user input, then another function run?

I'm having a problem with figuring out how to make a function run - and then wait for user input (I.E: If user selects to share location), and then run another function. When the "getUserLocation" function runs, the "addLocationArrayToMap" function runs before the user has a chance to make any input on the alert window.
Some debugging returns "userPos is not defined" which makes me think that my guess as to why it's not working is accurate..?
Code below:
var markers =[];
var myLocationIconArray = [];
var infoWindowContentString = '';
var addInfowindow;
var distanceArray = [];
var addInfowindow;
function runAll() {
getUserLocation(addLocationArrayToMap);
}
function getUserLocation() {
map.setOptions({draggable: true, zoomControl: true, scrollwheel: true, disableDoubleClickZoom: false});
// Another function that deletes 'dummy' markers before adding Real Markers to the map
deleteMarkers();
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
centerPos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
map.setCenter(centerPos);
addMarker(centerPos);
}, function() {
handleLocationError(true, map.getCenter());
});
} else {
//Browser doesn't support Geolocation
handleLocationError(false, map.getCenter());
}
}
function handleLocationError(browserHasGeolocation, defaultPos) {
infoWindowContentString = "Sorry, we can't get your location.";
addInfowindow = new google.maps.InfoWindow({
content: infoWindowContentString
});
map.setCenter(defaultPos);
addMarker(defaultPos, addInfowindow);
}
function addMarker(location, addInfowindow) {
var marker = new google.maps.Marker({
position: location,
map: map,
animation: google.maps.Animation.DROP,
icon: yourLocation,
draggable: false,
clickable: true
});
if (addInfowindow == null) {
var myLocationInfowindow = new google.maps.InfoWindow({
content: "Your location"
});
myLocationInfowindow.open(map, marker);
myLocationIconArray.push(marker);
} else {
myLocationIconArray.push(marker);
}
}
function addLocationArrayToMap() {
userPos = new google.maps.LatLng(centerPos.lat, centerPos.lng);
for (var z = 0; z < dabblersArray.length; z++) {
// dabblersArray is an array of Lat & Lng coords.
dabblerLocation = new google.maps.LatLng(dabblersArray[z].lat, dabblersArray[z].lng);
calculateDistance(userPos, dabblerLocation);
markers.push(new google.maps.Marker({
position: dabblersArray[z],
map: map,
icon: dabblers,
draggable: false,
clickable: true
}));
// Some logic to add the distance from the user and the dabblersArray as an alert window above each marker - haven't done this yet.
}
}
function calculateDistance(userPos, dabblerLocation) {
distance = google.maps.geometry.spherical.computeDistanceBetween(userPos, dabblerLocation);
distanceArray.push(distance);
}
JavaScript has no concept of making a user wait. The way to accomplish this is using callbacks, exactly like navigator.geolocation.getCurrentPosition exemplifies. It has success and error callbacks, which you are already using.
And you're already passing in addLocationArrayToMap to getUserLocation, but not using it. It should be invoked as a callback function in the navigator.geolocation.getCurrentPosition success handler. Mission accomplished.
function runAll() {
getUserLocation(addLocationArrayToMap);
}
function getUserLocation(onComplete) {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
//Your logic...
//Invoke callback
onComplete();
}, function() {
handleLocationError(true, map.getCenter());
});
}
}

AJAX call in an Infowindow: Scope Issue

Or at least I believe it's a scope issue, correct me if I'm wrong.
I have a for loop that generates markers on my map. Each infowindow loads different content using callbacks to an ajax function.
I've simplified this sample to outline the problem.
var xhr = "";
var infowindow = new google.maps.InfoWindow();
var marker, i;
var polylineCoordinates = [new google.maps.LatLng(78.782762, 17.917843),
new google.maps.LatLng(-0.829439, -91.112473),
new google.maps.LatLng(15.066156, -23.621399),
]
function createHttpRequest() {
try {
xhr = new XMLHttpRequest();
return xhr;
}
catch (e)
{
//assume IE6
try {
xhr = new activeXBbject("microsoft.XMLHTTP");
return xhr;
}
catch (e) {
return alert("Unable to create an XMLHttpRequest object");
}
}
}
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(78.782762,17.917843),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"),
mapOptions);
}
//I recreated the polylineCoordinates array (see above)
//to try and replicate and real array in the script
for (i = 0; i < polylineCoordinates.length; i++) {
marker = new google.maps.Marker({
position: polylineCoordinates[i],
map: map
});
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent("<div id=\"infowindow\">" + getStationInfo(infoWindowDiv) + "</div>");
infowindow.open(map, marker);
}
})(marker, i));
} //End adding markers loop
function infoWindowDiv(stationInfo) {
var add = document.createTextNode(stationInfo);
document.getElementById("infowindow").appendChild(add);
}
function getStationInfo(callback) {
//createHttpRequest() exists globally
var xhr = createHttpRequest();
var url = "stations.php" //edited out the original URL
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
var stationInfo = "This is a Test";
return callback(stationInfo)
} //end readyState
} //end readystatechange
xhr.open("GET", url, true);
xhr.send(null);
} //end getStationInfo
Small Edit: Moved functions outside of the loop
Edit 2: There is nothing wrong with the ajax call, the url was edited for the sake of the sample code. Notice the final output shows "This is a test" in the infowindow which clearly states a successful callback was performed. Moreover, notice there is no responseText or responseXml. The variable being sent back has nothing to do with the url
The callback works fine but for some reason it's topped with the dreadful 'undefined' on top of it.
Console shows nothing.
Output:
undefined
This is a test
What am I doing wrong? How can it be undefined if it works?
What is happening:
you click on the infowindow
getStationInfo(infoWindowDiv) is called, fires off an AJAX request, but returns nothing useful ("undefined", there is no return statement)
The AJAX function will encounter an error (url "Unnecessary at this point" will not cause the onreadystatechange function to fire). But you tell us that isn't a problem.
The script encounters the javascript error Uncaught TypeError: Cannot call method 'appendChild' of null because the div with id infowindow hasn't been attached to the DOM.
Suggest adding an event listener on the infowindow to not attempt to access the div with id="infowindow" until it has been rendered (domready).
Working code:
var xhr = "";
var infowindow = new google.maps.InfoWindow();
var map = null;
var marker, i;
var polylineCoordinates = [new google.maps.LatLng(78.782762, 17.917843),
new google.maps.LatLng(-0.829439, -91.112473),
new google.maps.LatLng(15.066156, -23.621399)
]
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(78.782762,17.917843),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"),
mapOptions);
for (i = 0; i < polylineCoordinates.length; i++) {
marker = new google.maps.Marker({
position: polylineCoordinates[i],
map: map
});
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent("<div id=\"infowindow\" style=\"height:50px;width:200px;\"></div>");
infowindow.open(map, marker);
google.maps.event.addListenerOnce(infowindow,"domready", function(){
getStationInfo(infoWindowDiv);
});
})(marker, i));
} //End adding markers loop
}
function infoWindowDiv(stationInfo) {
var add = document.createTextNode(stationInfo);
document.getElementById("infowindow").appendChild(add);
}
function getStationInfo(callback) {
var stationInfo = "This is a Test";
callback(stationInfo)
} //end getStationInfo
google.maps.event.addDomListener(window, 'load', initialize);

Duplicate a google map to a separate <div> element on page

I have one istance of a google map on a page. I'm using the following line of code to get the map and assign it to a new variable.
newmap = map.getMap();
When I print newmap to console it shows that the map is being assigned to the variable. I now want to duplicate that map with the exact same options into the following div....
<div id="map-larger-canvas"></div>
Any idea's how I would do this?
Define option for every map and after init twice:
var map_options = {
center: new google.maps.LatLng(41.811729,12.738513),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
function initialize() {
var map1 = document.getElementById('map-1st');
var map_canvas = document.getElementById('map-larger-canvas');
var map1 = new google.maps.Map(map1, map_options)
var map2 = new google.maps.Map(map_canvas, map_options);
}
google.maps.event.addDomListener(window, 'load', initialize);
I use Json in this way, take a look:
$('#map_canvas_europe').gmap().bind('init', function() {
// This URL won't work on your localhost, so you need to change it
// see http://en.wikipedia.org/wiki/Same_origin_policy
$.getJSON( 'json/locations_europe.json', function(data) {
$.each( data.markers, function(i, marker) {
$('#map_canvas_europe').gmap('addMarker', {
'position': new google.maps.LatLng(marker.latitude, marker.longitude),
'bounds': true
}).click(function() {
$('#map_canvas_europe').gmap('openInfoWindow', { 'content': marker.content }, this);
});
});
});
});
$('#map_canvas_asia').gmap().bind('init', function() {
// This URL won't work on your localhost, so you need to change it
// see http://en.wikipedia.org/wiki/Same_origin_policy
$.getJSON( 'json/locations_asia.json', function(data) {
$.each( data.markers, function(i, marker) {
$('#map_canvas_asia').gmap('addMarker', {
'position': new google.maps.LatLng(marker.latitude, marker.longitude),
'bounds': true
}).click(function() {
$('#map_canvas_asia').gmap('openInfoWindow', { 'content': marker.content }, this);
});
});
});
});

Google Maps global object; js generated by coffeescript not working

What is the global object in a Google Maps app?
I rewrote the js at https://developers.google.com/maps/documentation/javascript/examples/map-geolocation
in coffeescript, which generated the following javascript:
// Generated by CoffeeScript 1.6.3
(function() {
var errorFlag, initialize;
google.maps.visualRefresh = true;
initialize = function() {
var map, mapOptions;
mapOptions = {
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
if (navigator.geolocation) {
return navigator.geolocation.getCurrentPosition(function(position) {
var infowindow, pos;
pos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
infowindow = new google.maps.InfoWindow({
map: map,
position: pos,
content: 'Location found'
});
return map.setCenter(pos);
}, function() {
return handleNoGeolocation(true);
});
} else {
return handleNoGeolocation(false);
}
};
handleNoGeolocation(errorFlag = function() {
var content, infowindow, options;
if (errorFlag) {
content = 'Geolocation failed';
} else {
content = 'Your browser does not support Geolocation';
}
options = {
map: map,
position: new google.maps.LatLng(60, 105),
content: content
};
infowindow = new google.maps.InfoWindow(options);
return map.setCenter(options.position);
});
google.maps.event.addDomListener(window, 'load', initialize);
}).call(this);
The app works when I use the js from their website, but not when I use the js generated by coffeescript. My guess is that since the map variable is a global variable in their code, I should bind it to the global object as well. I tried window.map, but that didn't work either. Any ideas?
The handleNoGeolocation function defination is wrongly compiled. It should have been
var errorFlag, initialize, handleNoGeolocation;
//..
//..
handleNoGeolocation = function (errorFlag) {
//..
//..
};
rather than
handleNoGeolocation(errorFlag = function() {
//..
//..
});
I guess something went wrong with indentation.
hope this helps.

Categories

Resources