I have so far a working covert script to get Longitude and Latitude from an Address.
Problem is that I can't submit, while the submit button is used to get the Longitude and Latitude.
So I would like the following:
Address will be placed in a hidden field. (populated by my CMS, ExpressionEngine)
Than on page load the Longitude and Latitude will be collected in two input fields
than press submit and done.
But how to do this, I use the following code so far.
Please help.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Longitude and Latitude from address</title>
<script src="http://maps.google.com/maps?file=api&v=2&key=YOUR KEY" type="text/javascript" charset="utf-8">
</script>
<script type="text/javascript">
//<![CDATA[
function load() {
if (GBrowserIsCompatible()) {
geocoder = new GClientGeocoder();
}
}
function showAddress(geolocation) {
if (geocoder) {
geocoder.getLatLng(
geolocation,
function(point) {
if (!point) {
alert(geolocation + " not found");
} else {
document.geoform.longitude.value = point.x;
document.geoform.latitude.value = point.y;
}
}
);
}
}
//]]>
</script>
</head>
<body onload="load()">
<form action="#" name="geoform" id="geoform" onsubmit="showAddress(this.geolocation.value); return false">
<input type="hidden" name="geolocation" value="Address goes here, populated by cms" size="50" />
Decimal Longitude:
<input name="longitude" type="text" id="longitude" value="" />
Decimal Latitude:
<input name="latitude" type="text" id="latitude" value="" />
<input type="submit" value="Longitude/latitude codes" />
</form>
</body>
</html>
By the time you're submitting the form, it's too late to make a request to geocode an address.
It's better to geocode the address on the page load, and then just submit the form.
function load() {
if (GBrowserIsCompatible()) {
geocoder = new GClientGeocoder();
geocoder.getLatLng(
document.geoform.geolocation.value,
function(point) {
if (!point) {
alert(geolocation + " not found");
} else {
document.geoform.longitude.value = point.x;
document.geoform.latitude.value = point.y;
}
}
);
}
}
By the way, three important points:
It's against Google's Terms of Service to geocode without displaying the results on a Google Map. See 10.1.1(g)
You shouldn't be developing with v2 anymore, it's deprecated and going away soon. Use v3 instead.
There is a web service geocoding API you can use to do this all in the server, and avoid this complexity altogether.
Related
I have a Google Form to collect information from my workers working in remote locations
Emp No *
Punch *
Customer details / mode or travel
The data goes into a Google spreadsheet with the below structure
Timestamp Emp No Punch Remark Name GeoCode GeoAddress Email
I am able to capture the GPS co-ordinates of the user by the below script. I made a web app (anyone even anonymous can run) and asked the user to click the link.
What I am not able to do :
I want to save the email ID (or emp no) of the user filling the form. But the email ID is not getting captured into the form. If I fill the form, the email ID is captured. For other users it is not captured. I don't want all the users to authenticate the script (to run the script as the logged in user). It must be captured by some other way. Is it possible?
If the GPS is not captured (it is empty), I want to display a different message in the HTML page. How to do it?
Code.gs
function doGet() {
return HtmlService.createHtmlOutputFromFile("Index");
}
//
function getLoc(value) {
var destId = FormApp.getActiveForm().getDestinationId() ;
var ss = SpreadsheetApp.openById(destId) ;
var respSheet = ss.getSheetByName("Location");
var numResponses = respSheet.getLastRow();
var currentemail = Session.getActiveUser().getEmail();
var c=value[0]; var d=value[1];
var e=c + "," + d ;
//respSheet.getRange(numResponses,6).setValue(e);
//respSheet.getRange(numResponses,8).setValue(currentemail);
var response = Maps.newGeocoder().reverseGeocode(value[0], value[1]);
var f= response.results[0].formatted_address;
//respSheet.getRange(numResponses,7).setValue(f);
respSheet.getRange(numResponses,6,1,3 ).setValues([[ e, f, currentemail ]]);
}
//
index.html
<!DOCTYPE html>
<html>
<script>
(function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
}
})()
function showPosition(position){
var a= position.coords.latitude;
var b= position.coords.longitude;
var c=[a,b]
getPos(c)
function getPos(value){
google.script.run.getLoc(value);
}
}
</script>
<body>
<p>Please ensure your GPS is on to record your location. You can generate the report from website to check. Pl. close this window (version 3)</p>
</body>
</html>
From the question
I want to save the email ID (or emp no) of the user filling the form. But the email ID is not getting captured into the form. If I fill the form, the email ID is captured. For other users it is not captured. I don't want all the users to authenticate the script (to run the script as the logged in user). It must be captured by some other way. Is it possible?
On a web application created using Google Apps Script to automatically get the user email ID you could set your web application to be executed as the user running the application instead being executed as you but if don't want to use this feature then you have to set your own authentication process.
From the question
If the GPS is not captured (it is empty), I want to display a different message in the HTML page. How to do it?
Use a JavaScript conditional expression
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
alert('Can\'t get the position');
}
})()
function showPosition(position){
var a= position.coords.latitude;
var b= position.coords.longitude;
var c=[a,b];
getPos(c);
function getPos(value){
google.script.run.getLoc(value);
}
}
The above code uses alert but you could use the DOM.
Resources
Web Apps | Google Apps Script
Document Object Model (DOM)
I was able to make a complete solution without any google form (just HTML) and managed to display an alert message also. The "Login" is still not possible.
Code.gs
It runs the form and saves the answers in the required columns into google sheet.
It runs faster than google form and "Submit" has to be clicked only once.
As the saving happens by "append row", the jumbling of data (between rows) which was happening in my earlier method is avoided.
/* #Include JavaScript and CSS Files */
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename)
.getContent();
}
/* #Process Form */
function processForm(formObject) {
var url = "https://docs.google.com/spreadsheets/d/...../edit#gid=52499297";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Location");
var response = Maps.newGeocoder().reverseGeocode(formObject.lat, formObject.long);
var address= response.results[0].formatted_address;
ws.appendRow(
[
new Date(),
formObject.empno,
formObject.punch,
formObject.rem,
"",
formObject.lat+","+formObject.long,
address
]
);
}
Index.html
This has the questions.
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<?!= include('JavaScript'); ?>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-6">
<form id="myForm" onsubmit="handleFormSubmit(this);">
<p class="h4 mb-4 text-left">Record Attendance and Location</p>
<div class="form-group">
<label for="empno">Emp No - Click to see list</label>
<input type="number" class="form-control" id="empno" name="empno" min="1" max="9999999" required>
</div>
<div class="form-group">
<label for="punch">Punch (Select one)</label>
<select class="form-control" id="punch" name="punch" required>
<option selected disabled hidden style='display: none' value=''></option>
<option value="In">In</option>
<option value="Out">Out</option>
<option value="Started">Started</option>
<option value="Reached">Reached</option>
</select>
</div>
<div class="form-group">
<label for="rem">Remark</label>
<input type="text" class="form-control" id="rem" name="rem">
</div>
<div class="form-group">
<input type="hidden" class="form-control" id="lat" name="lat">
<input type="hidden" class="form-control" id="long" name="long">
</div>
<button type="submit" class="btn btn-primary btn-block">Submit</button>
</form>
<div id="output"></div>
</div>
</div>
</div>
</body>
</html>
JavaScript.html
This processes the answers
<script>
function showPosition() {
navigator.geolocation.getCurrentPosition(showMap);
}
function showMap(position) {
// Get location data
var lat = position.coords.latitude;
var geo1 = document.getElementById("lat");
geo1.value = lat;
var long = position.coords.longitude;
var geo2 = document.getElementById("long");
geo2.value = long;
}
// Prevent forms from submitting.
function preventFormSubmit() {
var forms = document.querySelectorAll('form');
for (var i = 0; i < forms.length; i++) {
forms[i].addEventListener('submit', function(event) {
event.preventDefault();
});
}
}
window.addEventListener('load', preventFormSubmit);
window.addEventListener('load', showPosition);
function handleFormSubmit(formObject) {
google.script.run.processForm(formObject);
document.getElementById("myForm").reset();
alert('Data saved successfully');
}
</script>
I want to call a page to get geolocation, then auto submit form to my php page to $_REQUEST getlat and getlon without clicking a submit button. Here is what I have. In my browser inspector I see my geolocation values, but it will not auto submit. I tried using the onload function in my body tag, but then found you can only call one function at a time, also I read this is a bad practice anyway. I have view another similar questions but cant piece it together. Thanks for any help
<html>
<script>
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
showPosition,
positionError
);
}
}
function showPosition(position) {
document.getElementById('getlat').value = position.coords.latitude;
document.getElementById('getlon').value = position.coords.longitude;
lon = document.getElementById('getlon').value;
lat = document.getElementById('getlat').value;
}
function positionError(error) {
if (error.PERMISSION_DENIED) alert('Please accept geolocation');
hideLoadingDiv();
showError(
'Geolocation is not enabled. Please enable to use this feature'
);
}
</script>
<script>
function PageLoad() {
getLocation();
document.frm1.submit();
}
</script>
<body>
<script>
window.onload = PageLoad();
</script>
<form action="results.php" name="frm1">
<input type="hidden" name="longitude" id="getlon" />
<input type="hidden" name="latitude" id="getlat" />
</form>
</body>
</html>
You must be unaware of the asynchronous nature of javascript otherwise it's a very simple problem. Anyway here I explain
When page loads and it finds window.onload=PageLoad(); it calls the PageLoad() function and then
function PageLoad() {
getLocation(); // <-- gets called
document.frm1.submit(); // <-- doesn't wait for getLocation() to complete;
// rather runs right away
}
As you can guess, while getLocation() is doing it's job (in sorta "thread" A) document.frm1.submit(); gets run (in another sorta "thread" B) and submits the form which isn't what you expect.
So what you need to do instead is move the submit related code in the showPosition() so once browser gets the location and then form is submitted.
function showPosition(position) {
document.getElementById("getlat").value = position.coords.latitude;
document.getElementById("getlon").value = position.coords.longitude;
lon=document.getElementById("getlon").value;
lat=document.getElementById("getlat").value;
document.frm1.submit(); <-- submits when browser gets the users location
}
According mdn documentation
getCurrentPosition() method. This initiates an asynchronous request to
detect the user's position
You are sending the form before obtaining the coordinates. The solution is to send this form with the value of the updated hidden inputs just when the asynchronous request ends. Please try the following example
Having this html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<form action="results.php" name="frm1">
<input type="hidden" name="longitude" id="getlon" />
<input type="hidden" name="latitude" id="getlat" />
</form>
<script src="geo.js"></script>
</body>
</html>
JS
document.addEventListener('DOMContentLoaded', () => {
pageLoad();
});
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition, positionError);
}
}
function showPosition(position) {
console.log(position);
document.getElementById('getlat').value = position.coords.latitude;
document.getElementById('getlon').value = position.coords.longitude;
lon = document.getElementById('getlon').value;
lat = document.getElementById('getlat').value;
document.frm1.submit(); // here the form is submit
}
function positionError(error) {
if (error.PERMISSION_DENIED) alert('Please accept geolocation');
hideLoadingDiv();
showError('Geolocation is not enabled. Please enable to use this feature');
}
function pageLoad() {
getLocation();
}
Here I ma using when DOM is ready
I have a html file on my website domain (devodeliver.co.uk) which calls on my API Key with the code.
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=MY-KEY"></script>
In the Developers Console I have tried adding every combination of my domain URL as you can see below
But when I load my site it shows the map for a millisecond then returns with the error "Google Maps API error: InvalidKeyMapError https://developers.google.com/maps/documentation/javascript/error-messages#invalid-key-map-error_.bb # MY-KEY:32" - basically saying I haven't given my website permission to access that API Key. But even if I don't set any referrers, it come back with the same error message. I've also waited way over 5 minutes for the API to take affect. Please, what am I doing wrong?! I've spent almost 16 hours trying to figure this out & I can't seem to for the life of me. HELPPPP!
Full HTML code:
<html>
<head>
<style type="text/css">
#map
{
height:400px;
width:400px;
display:block;
}
</style>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB7-LTLEupUWBJBWl1GpOWPwkMvxzf8itQ"></script>
<script type="text/javascript">
function getPosition(callback) {
var geocoder = new google.maps.Geocoder();
var postcode = document.getElementById("postcode").value;
geocoder.geocode({'address': postcode}, function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
callback({
latt: results[0].geometry.location.lat(),
long: results[0].geometry.location.lng()
});
}
});
}
function setup_map(latitude, longitude) {
var _position = { lat: latitude, lng: longitude};
var mapOptions = {
zoom: 16,
center: _position
}
var map = new google.maps.Map(document.getElementById('map'), mapOptions);
var marker = new google.maps.Marker({
position: mapOptions.center,
map: map
});
}
window.onload = function() {
setup_map(51.5073509, -0.12775829999998223);
document.getElementById("form").onsubmit = function() {
getPosition(function(position){
var text = document.getElementById("text")
text.innerHTML = "Marker position: { Longitude: "+position.long+ ", Latitude:"+position.latt+" }";
setup_map(position.latt, position.long);
});
}
}
</script>
</head>
<body>
<form action="javascript:void(0)" id="form">
<input type="text" id="postcode" placeholder="Enter a postcode">
<input type="submit" value="Show me"/>
</form>
<div id="map"></div>
<div id="text"></div>
</body>
</html>
Here, when I tested it, it gives me the error "Google Maps API error: ApiNotActivatedMapError" on the JS console.
Take a look for this issue on: https://developers.google.com/maps/documentation/javascript/error-messages#deverrorcodes
When you use a library or service via the Maps-Javascript-API, and use a key, you need to activate the Google Maps JavaScript API .
Make sure to activate the Google Maps JavaScript API for your project.
Also,
take a look on this other topic about Enable the Google Maps Jvascript API: Google Map error: InvalidKeyOrUnauthorizedURLMapError
Preface: I have contacted google and read the documentation. When this is finished it will display the map on the next page and have autosuggest on the first - I will not be violating the terms and conditions this way, so please dont start a flame war
I have set about trying to create my own minimal geocoder which geocodes without showing a map on the current page. I have found that there is no example code online for doing this! I am new to jquery but this is the best I could come up with. However, low and behold it doesn't work.
I am sure I have done something stupid, so I would appreciate it if someone could let me know if they spot any obvious reasons why this wouldn't work. I have never made a javascript before.
JSFiddle Link: http://jsfiddle.net/njDvn/9/
<html>
<head>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script>
function getLatLng() {
var geocoder = new google.maps.Geocoder();
var address = document.getElementById('address').value;
geocoder.geocode({
'address': address
}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var latLng = results[0].geometry.location;
$('#lat').val(results[0].geometry.location.lat());
$('#lng').val(results[0].geometry.location.lng());
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
</script>
</head>
<body onload="initialize()">
<div>
<input id="address" type="textbox" value="Sydney, NSW">
<input type="button" value="Geocode" onclick="codeAddress()">
<input id="lat" type="textbox" value="lat">
<input id="lng" type="textbox" value="lng">
</div>
</body>
</html>
well first 2 things I can see are that the onclick of the button is calling codeAddress(), but you have not declared that function - you can change that to getLatLng() and it should work then. Plus the <body onload is calling initialize() which is also not declared. While that should not prevent the geocoder from firing you should probably fix it.
On one of my pages in Drupal, I have a panel that contains the following html code:
<head>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?libraries=geometry&sensor=false"></script>
<script type="text/javascript">
var dirService, initAddr, endLoc, doc;
function initialize() {
dirService = new google.maps.DirectionsService();
initAddr = "85 E San Fernando Street San Jose, CA 95113";
}
function showLocation() {
doc = document.getElementById("results_area");
endLoc = document.forms[0].address2.value;
findFromAddress();
}
function findFromAddress() {
dirService.route({'destination': initAddr, 'origin': endLoc, 'travelMode': google.maps.TravelMode.DRIVING}, function (result, status) {
if (status === google.maps.DirectionsStatus.OK) {
var distance = result.routes[0].legs[0].distance.value;
var miles = Math.round(distance * 0.000621371192 * 100) / 100;
alert("Distance from Loves Cupcakes is roughly" + miles
+ " miles" + "Estimated price is (price)" );
}
else {
alert("INVALID ZIP CODE");
}
});
}
</script>
</head>
<body onload="initialize()">
<p> Enter in zip code of desired delivery location</p>
<form action="#" onsubmit="showLocation(); return false;">
<p><input class="address_input" name="address2" size="20" type="text" /> <input name="find" type="submit" value="Search" /></p>
</form>
<p id="results_area"> </p>
Simply put, it takes a zipcode and calculates the distance from a specified location.
The HTML page works on its own, but when I enter it into a panel, some weird stuff happens that I don't understand. When I hit the "Submit" button, the page is reloaded, but with a slightly different URL and no alert box pops up. The URL changes from ../contact_us to ../Contact_Us?address2=&find=Search#. I understand the address2 and search are elements from my HTML code, but can anyone help me figure out why this is happening (I am assuming it has something to do with drupal, not the code itself, but not too sure)?
When the submit button is clicked, the browser sends a HTTP GET request to the address with the address2 and find values as parameters.
In your case, address2 has no value and find has a value of 'Search'
See here for a comprehensive explanation : https://www.rfc-editor.org/rfc/rfc3986#section-3