Changing visibility of HTML elements based on geolocation permission [duplicate] - javascript

This question already has answers here:
check if location setting has been turned off in users browser
(2 answers)
Closed 3 years ago.
I'm trying to make an HTML element visible if the end user hasn't agreed to let the browser know their location. However, my current code isn't working (nor is the console log) when declining the browser's request. But when allowing the browser to access my location, the API call to Google Places works.
To summarise: If a user declines the browser's request, I want the visibility of geolocationunavail to be visible, rather than hidden.
HTML
<div id="geolocationunavail">
<p>Don't want to share your location?</p>
<p><span>That's cool.</span> Type a location below.</p>
</div>
CSS
#geolocationunavail {
visibility: hidden;
}
JS
function getUserLocation() {
if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(function(position) {
document.querySelector("#longitude").value = position.coords.longitude;
document.querySelector("#latitude").value = position.coords.latitude;
var lng = position.coords.longitude;
var lat = position.coords.latitude;
var latlng = new google.maps.LatLng(lat, lng);
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'latLng': latlng }, function (results, status) {
if (status !== google.maps.GeocoderStatus.OK) {
alert(status);
}
if (status == google.maps.GeocoderStatus.OK) {
console.log(results);
var address = (results[0].formatted_address);
document.querySelector("#citysearch").value = address;
}
});
});
} else {
console.log("Geolocation is not supported by this browser.");
document.getElementById("geolocationunavail").style.display = "visible";
}
}

It looks like you have 2 different problems, so I will address them both:
First, your geolocation function is not working as expected. This is happening because you are not using the function correctly. You would not want to use an else statement to say that geolocation is not working, because geolocation will always "work" since it is called successfully regardless of the user input. Even if the user selects "block" the function technically "worked" and therefore will not run the else statement.
Second, your visibility is not toggling correctly. There are 2 ways you can fix this. You can either make it a class and use classList.toggle("myClass"), or you can do document.getElementById('geolocationunavil').style.visibility = 'visible';
Both of these put together will result in:
function getUserLocation() {
navigator.geolocation.getCurrentPosition(
position => {
document.querySelector("#longitude").value = position.coords.longitude;
document.querySelector("#latitude").value = position.coords.latitude;
var lng = position.coords.longitude;
var lat = position.coords.latitude;
var latlng = new google.maps.LatLng(lat, lng);
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'latLng': latlng }, function (results, status) {
if (status !== google.maps.GeocoderStatus.OK) {
alert(status);
}
if (status == google.maps.GeocoderStatus.OK) {
console.log(results);
var address = (results[0].formatted_address);
document.querySelector("#citysearch").value = address;
}
});
},
err => {
console.log("Geolocation is not supported by this browser.");
document.getElementById("geolocationunavail").style.visibility = "visible";
})
}

Related

How can I keep showing a Js var in HTML after route changes?

I'm bad with Javascript and would like your help!
Hi, I'm building a Rails application and would like to add some features related to geoloction. For that I get the current location of the user with JS and then print it with HTML.
As you guys will see, my code runs every time the page loads, but when my routes change, for example: /about, /settings, /events, it simply disappear and I have to load the page again to print the HTML element.
/* CURRENT LOCATION */
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).ready(function() {
if ("geolocation" in navigator) {
navigator.geolocation.getCurrentPosition(geolocationSuccess, geolocationError);
} else {
alert("Geolocation not supported!");
}
});
How can I have the current location printed on this element in all my application routes?
I wouldn't like to request this information every time.
Maybe a cookie? I don't know...
or request just once every some time
What do you guys recommend? Please help me :)
You can use localStorage for this purpose: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
localStorage allows you to save data between browser sessions and windows.
An example usage might be:
...
// Somewhere in geocode request callback
localStorage.setItem('user_address', results[0].formatted_address)
...
// Somewhere in your render code
document.getElementById("current_location").innerHTML =
localStorage.getItem('user_address')
...

Google Map geolocation getcurrentposition()

I am using the google geolocation's getCurrentPosition() function for get the current position of the user.
It works fine for me in firefox but not working on chrome.
My code is as below ::
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<p id="demo">Click the button to get your position.</p>
<button onclick="getLocation()">Try It</button>
<div id="mapholder"></div>
<script>
var x = document.getElementById("demo");
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition, showtemp);
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
function showPosition(position) {
var latlon = position.coords.latitude + "," + position.coords.longitude;
var img_url = "http://maps.googleapis.com/maps/api/staticmap?center="
+latlon+"&key=AIzaSyDOgvRydLLNrztjgagobYS_sROK1u3r4M4&zoom=14&size=400x300&sensor=false";
document.getElementById("mapholder").innerHTML = "<img src='"+img_url+"'>";
}
function showtemp(temp) {
alert("test");
}
function showError(error) {
$.get("http://ipinfo.io", function (response) {
var array = (response.loc).split(',');
console.log(array[0]);
var latlon = array[0] + "," + array[1];
var img_url = "http://maps.googleapis.com/maps/api/staticmap?center="
+latlon+"&zoom=14&size=400x300&sensor=false";
document.getElementById("mapholder").innerHTML = "<img src='"+img_url+"'>";
}, "jsonp");
}
</script>
</body>
</html>
Please help me solve this.
It Gives me error :: " getCurrentPosition() and watchPosition() are deprecated on insecure origins, and support will be removed in the future. You should consider switching your application to a secure origin, such as HTTPS."
Thanks in advance
getcurrentposition() is deprected and there is no replacement of it. read this answer :- getcurrentposition-and-watchposition-are-deprecated-on-insec‌​ure-origins
Click on this google updated api's example link it's working example. : https://developers.google.com/maps/documentation/javascript/examples/map-geolocation.
Hover at top right of the code block to copy the code or open it in JSFiddle.
Use this functions :
// Note: This example requires that you consent to location sharing when
// prompted by your browser. If you see the error "The Geolocation service
// failed.", it means you probably did not give permission for the browser to
// locate you.
<script>
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 6
});
var infoWindow = new google.maps.InfoWindow({map: map});
// Try HTML5 geolocation.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
infoWindow.setPosition(pos);
infoWindow.setContent('Location found.');
map.setCenter(pos);
}, function() {
handleLocationError(true, infoWindow, map.getCenter());
});
} else {
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter());
}
}
function handleLocationError(browserHasGeolocation, infoWindow, pos) {
infoWindow.setPosition(pos);
infoWindow.setContent(browserHasGeolocation ?
'Error: The Geolocation service failed.' :
'Error: Your browser doesn\'t support geolocation.');
}
</script>
Geolocation is not deprecated per se, but limited to sites served via HTTPS.
The warning itself reads "getCurrentPosition() and watchPosition() are deprecated on insecure origins", which boilds down to pages served via HTTP and not HTTPS.
See, your code works fine here in the latest Chrome.
The easiest way to get SSL is probably to use Github pages for hosting your content or using something surge.
You could use the https://ipinfo.io API (it's my service) as an alternative to getCurrentLocation(). It's free for up to 1,000 req/day (with or without SSL support). It gives you coordinates, name and more, works on non-SSL sites, and doesn't prompt the user for permission. Here's an example:
curl ipinfo.io
{
"ip": "172.56.39.47",
"hostname": "No Hostname",
"city": "Oakland",
"region": "California",
"country": "US",
"loc": "37.7350,-122.2088",
"org": "AS21928 T-Mobile USA, Inc.",
"postal": "94621"
}
Here's an example which constructs a coords object with the API response that matches what you get from getCurrentPosition():
$.getJSON('https://ipinfo.io/geo', function(response) {
var loc = response.loc.split(',');
var coords = {
latitude: loc[0],
longitude: loc[1]
};
});
And here's a detailed example that shows how you can use it as a fallback for getCurrentPosition():
function do_something(coords) {
// Do something with the coords here
}
navigator.geolocation.getCurrentPosition(function(position) {
do_something(position.coords);
},
function(failure) {
$.getJSON('https://ipinfo.io/geo', function(response) {
var loc = response.loc.split(',');
var coords = {
latitude: loc[0],
longitude: loc[1]
};
do_something(coords);
});
};
});
See http://ipinfo.io/developers/replacing-navigator-geolocation-getcurrentposition for more details.

Trigger JavaScript error when geo location services disabled

In my AngularJS project I am using the following code to get a device's GPS co-ordinates:
// when user clicks on geo button
$scope.getGeoLocation = function() {
var geocoder = new google.maps.Geocoder();
window.navigator.geolocation.getCurrentPosition(function(position) {
$scope.$apply(function() {
$scope.position = position;
var latlng = new google.maps.LatLng($scope.position.coords.latitude, $scope.position.coords.longitude);
geocoder.geocode({'latLng': latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
$scope.searchstring = results[2].formatted_address;
$location.search('s', $scope.searchstring);
$location.search('p', 1);
$location.search('geo', true);
$route.reload();
}
});
});
}, function(error) {
$scope.error = error;;
});
};
The problem is when location services is turned off on an iPhone 6, there is a no error created to inform the user that they need to turn on location services.
Does any one know how I can amend the code above to trigger an error in this scenario? Any help would be much appreciated.
As pointed out in this post Is there a way to check if geolocation has been DECLINED with Javascript?, you can pass a second callback to getCurrentPosition which will get called if the permission is declined.
Thanks for pointing me in the right direction unobf. Please find attached the code (with updated error handling) in case any one stumbles across this.
// when user clicks on geo button
$scope.getGeoLocation = function() {
var geocoder = new google.maps.Geocoder();
window.navigator.geolocation.getCurrentPosition(function(position) {
$scope.$apply(function() {
$scope.position = position;
var latlng = new google.maps.LatLng($scope.position.coords.latitude, $scope.position.coords.longitude);
geocoder.geocode({'latLng': latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
$scope.searchstring = results[2].formatted_address;
$location.search('s', $scope.searchstring);
$location.search('p', 1);
$location.search('geo', true);
$route.reload();
}
});
});
}, function(error) {
$scope.error = "";
// Check for known errors
switch (error.code) {
case error.PERMISSION_DENIED:
$scope.error = "This website does not have permission to use " +
"the Geolocation API.";
alert("Geo location services appears to be disabled on your device.");
break;
case error.POSITION_UNAVAILABLE:
$scope.error = "The current position could not be determined.";
break;
case error.PERMISSION_DENIED_TIMEOUT:
$scope.error = "The current position could not be determined " +
"within the specified timeout period.";
break;
}
// If it's an unknown error, build a $scope.error that includes
// information that helps identify the situation, so that
// the error handler can be updated.
if ($scope.error == "")
{
var strErrorCode = error.code.toString();
$scope.error = "The position could not be determined due to " +
"an unknown error (Code: " + strErrorCode + ").";
}
});
};

Google Maps reverse geocoding address appears after second click?

Currently if I click on a marker, error in console shows "address undefined" but if i click it again the address shows up, why is this happening?
What my listener looks like:
map.data.addListener('click', function(event) {
var lat = event.latLng.lat();
var lng = event.latLng.lng();
function getReverseGeocodingData() {
var latlng = new google.maps.LatLng(lat, lng);
// This is making the Geocode request
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'latLng': latlng }, function (results, status) {
if (status !== google.maps.GeocoderStatus.OK) {
alert(status);
}
// This is checking to see if the Geoeode Status is OK before proceeding
if (status == google.maps.GeocoderStatus.OK) {
console.log(results[0].formatted_address);
address = (results[0].formatted_address);
}
});
}
getReverseGeocodingData(lat, lng);
infoWindow.setContent("Address: " + address + "<br>Vehicle: " + event.feature.getProperty('deviceID')+"<br> Speed: "+event.feature.getProperty('speedKPH'));
infoWindow.setPosition(event.latLng);
infoWindow.setOptions({pixelOffset: new google.maps.Size(0,-34)});
infoWindow.open(map);
});
thank you for your time and help in advance.
geocoder.geocode works asynchronously, which means the callback will be invoked later™. You are calling this method from the synchronous method getReverseGeocodingData, and then proceed to use the address data immediately afterwards.
This can't work.
Asynchronous communication can be visualized with traditional paper mail. Imagine you send a letter to Google to get the address at x,y. After you put the letter in the postbox, you don't have the result just yet, so you can't print that sign with the address on it yet. But you can do other stuff, like repainting your house (yeah, the metaphor is stretched). You will have to be patient to wait for the answer via mail.
A few days later the mailman rings, and delivers you the answer from Mountain View. It says: "x,y is at Hauptstraße 22". Now you can start printing that sign (and this is where the metaphor ends) to the status bar of your browser.
On the other hand, you can visualize synchronous communication with phone calls. You get the answer immediately, and you can't do anything else during the call. After you hung up, you got the answer.
In JavaScript, we are pretty much stuck with the asynchronous model. If this is good or bad is not for today to decide ;-)
So thanks thriqon i understood the problem,
and have come up with this solution which i'm not sure how correct it is, but it does what i need it to do. It calls for the address once they hover over the point in the background without popping up the infowindow and when they click, tada, the address is shown in the infowindow! hope this helps some people! messsssy code
map.data.addListener('mouseover', function(event) {
var lat = event.latLng.lat();
var lng = event.latLng.lng();
function getReverseGeocodingData(lat, lng) {
var latlng = new google.maps.LatLng(lat, lng);
// This is making the Geocode request
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'latLng': latlng }, function (results, status) {
if (status !== google.maps.GeocoderStatus.OK) {
alert(status);
}
// This is checking to see if the Geoeode Status is OK before proceeding
if (status == google.maps.GeocoderStatus.OK) {
console.log(results[0].formatted_address);
address = (results[0].formatted_address);
return address;
}
});
}
getReverseGeocodingData(lat, lng);
map.data.addListener('click', function(event) {
infoWindow.setContent("Address: " + address + "<br>Vehicle: " + event.feature.getProperty('deviceID') +"<br> Speed: "+event.feature.getProperty('speedKPH')+"<br> Heading:"+event.feature.getProperty('heading'));
infoWindow.setPosition(event.latLng);
infoWindow.setOptions({pixelOffset: new google.maps.Size(0,-34)});
infoWindow.open(map);
});
});

Finish function executing before proceeding

I have a form that is validated upon submission, inside the form submit a function is called, the submit continues and doesn't wait for the function to finish. How do I fix this?
var clientaddress=false;
function checkaddress(callback){
var geocoder = new google.maps.Geocoder();
geocoder.geocode({'address': address}, function(results, status) {
if (status != google.maps.GeocoderStatus.OK) {
clientaddress=false;
callback(false);
}
else if (status == google.maps.GeocoderStatus.OK) {
clientaddress=true;
callback(false);
}
}
jQuery(document).ready(function(){
jQuery("#submitOrder").submit(function(){
checkaddress(function(result) {
if (!result) {
jAlert("Please enter a valid address!");
jQuery("#address").focus();
isValidation = 0;
}
});
//other validation code that gets executed without waiting for checkaddress()
//submit page
})
I tried to make one function that calls both the address checker and a validation function, but still they do not wait for each other.
How can I solve this problem?
Because the geocode function is async! Use a callback:
function checkaddress(callback){
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status != google.maps.GeocoderStatus.OK) {
callback(false)
} else if (status == google.maps.GeocoderStatus.OK) {
callback(true)
}
});
}
Then use this like:
checkaddress(function(result) {
if (result) {
//result true!
} else {
//result false!
}
//REST OF YOUR CODE GOES HERE, IF PUT OUTSIDE IT WILL EXECUTE WHILE CHECKADDRESS IS IN PROGRESS
});
Your submit function is also most likely running the default behavior, use preventDefault
jQuery("#submitOrder").submit(function(e){
e.preventDefault();
//code
});

Categories