I don't know why the r1 variable is undefined.
The 'latLng': mEvent.latLng thing is working OK on other functions...
<!-- API V3 --> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
....
.....
....
google.maps.event.addListener(map, 'click', function(mEvent) {
var geo1 = new google.maps.Geocoder();
geo1.geocode( { 'latLng': mEvent.latLng }, function(results, status) {
if ( status == google.maps.GeocoderStatus.OK )
{
var r1 = results[0].formatted_address;
}
else
{
var r1 = '?';
}
});
//do things with mEvent.latLng and r1...
Variable r1 is most probably undefined because it's out of scope. You need to move it's declaration up a bit. E.g.:
google.maps.event.addListener(map, 'click', function(mEvent) {
var geo1 = new google.maps.Geocoder();
var r1;
geo1.geocode( { 'latLng': mEvent.latLng }, function(results, status) {
if ( status == google.maps.GeocoderStatus.OK )
{
r1 = results[0].formatted_address;
}
else
{
r1 = '?';
}
});
//do things with mEvent.latLng and r1...
If you still find some problem use Firebug (in Firefox) or built in debuggers in other browsers. You can insert "debugger;" keyword to stop at some line when a debugger is active. You will then be able to check what variables are available.
Related
I work as an intern with Ruby on Rails and yesterday I had to do something with Javascript (my javascript skills ARE AWFUL, I DON'T EVEN HAVE SKILLS with IT).
I implemented current location feature in a project, but I'd like to do it another way... the thig is kinda done, take a look:
function geolocationSuccess(position) {
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
var geocoder = new google.maps.Geocoder();
var latlng = {lat: latitude, lng: longitude};
geocoder.geocode({'location': latlng}, function(results, status) {
if (status === google.maps.GeocoderStatus.OK) {
if (results[0]){
var user_address = results[0].formatted_address;
document.getElementById("current_location").innerHTML = user_address;
}else {
console.log('No results found for these coords.');
}
}else {
console.log('Geocoder failed due to: ' + status);
}
});
}
function geolocationError() {
console.log("please enable location for this feature to work!");
}
$(document).on("ready page:ready", function() {
$("#current-location").on("click", function(event) {
event.preventDefault();
if ("geolocation" in navigator) {
navigator.geolocation.getCurrentPosition(geolocationSuccess, geolocationError);
} else {
alert("Geolocation not supported!");
}
});
});
All right, I know it all happens when I click the button with Id="current-location", but I'd like it to happen automatically when the page loads, how can I do it?
Simply insert the code you want executed inside of a $(document).ready( block:
$(document).ready(function() {
if ("geolocation" in navigator) {
navigator.geolocation.getCurrentPosition(geolocationSuccess, geolocationError);
} else {
alert("Geolocation not supported!");
}
});
On a side note, I would recommend not naming a function variable event since event is a keyword. The standard convention for passing event to a function is to use e. For example:
$('#someId').on('click', function(e) {
e.preventDefault();
//do something
});
I am working on an application and need to convert an address supplied by user to lat lng and update a google map. I am using angular js version 1.0.0 Problem is in firefox i keep getting a too much recursion error.
app.controller("BasicMapController", function($scope, $timeout){
.......
angular.extend($scope, {
.......
checking_address: false// curently trying to get lat long from address
});
......
I had to create an ngBlur directive since 1.0.0 didn't have it and upgrading is not an option since too much other code breaks.
app.directive('ngBlur', function() {
return function( scope, elem, attrs ) {
elem.bind('blur', function() {
scope.$apply(attrs.ngBlur);
});
};
});
On my page i add ng-blur="onblur_()" to the relevant text area and then in my controller i define the relevant function:
$scope.onblur_ = function ($event) {
if ($scope.checking_address)
return;
var map_scope = angular.element($('.google-map')).scope();
var address = document.getElementById("id_address").value;
if ( !! !address)
return;
$scope.checking_address = true;
var geocoder = new google.maps.Geocoder();
geocoder.geocode({
'address': address
}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map_scope.map._instance.panTo(results[0].geometry.location);
if ($scope.markers[0] == undefined) {
$scope.markers[0] = new google.maps.Marker({
map: map_scope.map._instance,
position: results[0].geometry.location
});
} else
$scope.markers[0].setPosition(results[0].geometry.location);
}
$scope.checking_address = false;
});
}
The code works fine in Opera and Chromium. Any ideas on what could be wrong or how i could get around the problem?
This is my first post. I'm completely stuck and could use some help with adding infoWindows to Google Maps. The data I'm actually going to use (NOT the API I used here) doesn't have lat/lon and has multiple values.
Things are fine until infoWindow, but I can't pass any other arguments into the geocoder callback. Thanks in advance for the help!
Credit goes to Minghui Yu: http://goo.gl/zvAKZ8. Mine uses different data for the infowindow and will have probably about 30 markers.
Here's the relevant code JS FIDDLE:
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 3,
center: new google.maps.LatLng(0, 0),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var marker;
var i;
var mapData;
var locations = [];
$(document).ready(function () {
$.ajax({
url: 'http://api.openweathermap.org/data/2.5/weather?q=London,uk',
async: false,
success: function (mapData) {
locations.push(mapData.name);
}
});
initialize();
});
function initialize() {
setMarkers(map, locations);
}
function setMarkers(map, address) {
for (var i = 0; i < address.length; i++) {
setMarker(map, address[i])
}
}
function setMarker(map, address) {
geocoder = new google.maps.Geocoder();
geocoder.geocode({
'address': address
},
function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
position: results[0].geometry.location,
map: map
});
google.maps.event.addListener(marker,
"click", function () {
//HAVING THE PROBLEM HERE. Not sure how to separate this from the callback.
infowindow.setContent(mapData.main.temp);
// But this works if you run it:
//infowindow.setContent(address);
infowindow.open(map, marker);
});
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
You've declare myData as a global variable.
But here you have mapData as parameter of ajax success callback.
$(document).ready(function () {
$.ajax({
url: 'http://api.openweathermap.org/data/2.5/weather?q=London,uk',
async: false,
success: function (mapData) { //locally scoped which can't override
locations.push(mapData.name);
}
});
This will not override the global variable.
Instead do like this
var gmapData = {};
and use it like
$(document).ready(function () {
$.ajax({
url: 'http://api.openweathermap.org/data/2.5/weather?q=London,uk',
async: false,
success: function (mapData) {
locations.push(mapData.name);
gmapData = mapData; //assign mapData to global variable
}
});
Now use in infoWindow
google.maps.event.addListener(marker, "click", function () {
//infowindow.setContent() will accept only string
//whereas temp is numeric, so convert to string
infowindow.setContent(gmapData.main.temp.toString());
infowindow.open(map, marker);
});
JSFiddle
I'm using this code: http://gmaps-samples-v3.googlecode.com/svn/trunk/places/places-search.html
I'd like on the second click of the sidebar, to close the infowindow (var iw).
function isInfoWindowOpen(iw){
var map = iw.getMap();
return (map !== null && typeof map !== "undefined");
}
tr.onclick=function(){
google.maps.event.trigger(markers[i],'click');
console.log('markers[i]: '+i);
if (isInfoWindowOpen(iw)){
// do something if IW is open
iw.close(map,markers[i]);
}
}
Change the showInfoWindow function in the example to check to see if the infowindow is open and the same infowindow, then just close it, otherwise do the required processing to get the contents. Need to add a property to the marker so you can tell whether it is the same one or not.
function showInfoWindow(i) {
return function(place, status) {
if (!!iw && iw._iwId == i) {
iw.close();
iw = null;
} else {
if (iw) {
iw.close();
iw = null;
}
if (status == google.maps.places.PlacesServiceStatus.OK) {
iw = new google.maps.InfoWindow({
content: getIWContent(place),
_iwId:i
});
iw.open(map, markers[i]);
}
}
}
}
working example
Try setting the content to '' (standard way for closing the infowindow)
like this :
tr.onclick=function(){
google.maps.event.trigger(markers[i],'click');
console.log('markers[i]: '+i);
if (isInfoWindowOpen(iw)){
// do something if IW is open
iw.close(map,markers[i]);
// Set the content to ''
iw.setContent('');
}
}
The goal
Reuse already loaded JavaScript correctly.
The problem
I'm generating a map dynamically using Google Maps API V3 and I need to reuse it. How?
The scenario
On Index.html, there's the following script:
var gMapsLoaded = false;
window.gMapsCallback = function () {
gMapsLoaded = true;
$(window).trigger('gMapsLoaded');
}
window.loadGoogleMaps = function () {
if (gMapsLoaded) return window.gMapsCallback();
var script_tag = document.createElement('script');
script_tag.setAttribute("type", "text/javascript");
script_tag.setAttribute("src",
"http://maps.google.com/maps/api/js?sensor=false&callback=gMapsCallback");
(document.getElementsByTagName("head")[0]
|| document.documentElement).appendChild(script_tag);
}
When I click on some button to show the map, my app invokes this script:
[...]
var geocoder;
var map;
var address = context.address();
function initialize() {
var mapDiv = document.getElementById("map_canvas");
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(-34.397, 150.644);
var myOptions = {
zoom: 15,
center: latlng,
mapTypeControl: true,
mapTypeControlOptions:
{ style: google.maps.MapTypeControlStyle.DROPDOWN_MENU },
navigationControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(mapDiv, myOptions);
if (geocoder) {
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
map.setCenter(results[0].geometry.location);
var infowindow = new google.maps.InfoWindow(
{
content: '<b>' + address + '</b>',
size: new google.maps.Size(150, 50)
});
var marker = new google.maps.Marker({
position: results[0].geometry.location,
map: map,
title: address
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
} else {
alert("No results found");
}
} else {
alert
("Geocode was not successful
for the following reason: " + status);
}
});
}
gMapsLoaded = false;
}
$(window).on('gMapsLoaded', initialize);
window.loadGoogleMaps();
As you can see, the application is always calling the loadGoogleMaps(); function that calls the external .js file. If I click in the 5 different maps, I get 5 scripts with the same proposal.
Someone have any idea to solve this?
Duplicated question?
Yes, I think that the essence of the question is duplicated, but the nucleus isn't.
As you can see, the application is always calling the
loadGoogleMaps(); function that calls the external .js file. If I
click in the 5 different maps, I get 5 scripts with the same proposal.
That is incorrect. After the first time it completely loads, the if statement on the first line will return early, preventing you from including it multiple times.
There's nothing wrong with the way that's written.
jsFiddle
var gMapsLoaded = false;
window.gMapsCallback = function () {
gMapsLoaded = true;
$(window).trigger('gMapsLoaded');
}
window.loadGoogleMaps = function () {
if (gMapsLoaded) return window.gMapsCallback();
console.log('Generating new script tag');
var script_tag = document.createElement('script');
script_tag.setAttribute("type", "text/javascript");
script_tag.setAttribute("src",
"http://maps.google.com/maps/api/js?sensor=false&callback=gMapsCallback");
(document.getElementsByTagName("head")[0]
|| document.documentElement).appendChild(script_tag);
}
$(window).on("gMapsLoaded",function(){
console.log("gMapsLoaded");
});
$(function(){
$("button").on("click",window.loadGoogleMaps);
});
Now, if you were to click it 5 times really fast when it isn't already loaded, it could potentially load it multiple times. You should call that function on it's own before a click event would normally happen to prevent that.
Update:
At the end of your initialize() method, you're using gMapsLoaded = false; which causes the above code to once again request a new script tag. Simply remove/comment out that line.