Reputation: 31
For my onsubmit
function, I have a function that requests for user's location and adds their location to the input values of my form.
However, when the user clicks on the submit button and a pop-up appears and asks the user to allow the browser to know their location, my form always submits before the user could answer the pop-up. This leaves the function incompleted and the input values become undefined.
I have tried adding a "return true;" statement until my onsubmit
function ends, but the form still gets submitted prior. I have also tried adding "e.preventDefault();" before my function completes. None of the methods worked so far...
My form:
<form action="/login" onsubmit="getLocation()" method="POST">
<button type="submit" class="btn btn-dark">Login</button>
<input id="currentUserLattitude" type=hidden name="currentLocation" value="placeholder">
<input id="currentUserLongitude" type=hidden name="currentLocation" value="placeholder">
</form>
The onsubmit function:
function getLocation(e) {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(onGeoSuccess, onGeoError);
return true;
} else {
alert("Geolocation is not supported by this browser.");
}
}
function onGeoSuccess(position) {
document.getElementById("currentUserLattitude").value = position.coords.latitude;
document.getElementById("currentUserLongitude").value = position.coords.longitude;
}
function onGeoError(err) {
alert("Error code " + err.code + ". " + err.message);
}
Upvotes: 1
Views: 1578
Reputation: 6457
Use an id and event listener, prevent default on submit, wrap your function in a promise, and only submit if the result is true:
function getLocation(e) {
// Create new promise
return new Promise(resolve => {
if (navigator.geolocation) {
// Since getCurrentPosition is asynchronous, resolve in the onsuccess callback.
navigator.geolocation.getCurrentPosition(
position => {
onGeoSuccess(position);
// Resolving here will return back to the .then()
resolve();
},
error => {
onGeoError(error);
resolve();
}
);
} else {
alert("Geolocation is not supported by this browser.");
// Return to the .then()
resolve();
}
});
}
function onGeoSuccess(position) {
document.getElementById("currentUserLattitude").value =
position.coords.latitude;
document.getElementById("currentUserLongitude").value =
position.coords.longitude;
}
function onGeoError(err) {
alert("Error code " + err.code + ". " + err.message);
}
document.getElementById("form").addEventListener("submit", e => {
// Prevent submission
e.preventDefault();
// Call your function and wait for a response
getLocation().then(() => {
// Submit the form
return e.target.submit();
});
});
<form id="form" action="/login" onsubmit="getLocation()" method="POST">
<button type="submit" class="btn btn-dark">Login</button>
<input id="currentUserLattitude" type=hidden name="currentLocation" value="placeholder">
<input id="currentUserLongitude" type=hidden name="currentLocation" value="placeholder">
</form>
Upvotes: 4
Reputation: 71
First, you should ask permission on page load:
<body onload="getLocation()">
Second, you should use a flag (variable) to track the status of the Geo location success. And finally if there was no error the form is ready for submit.
var anErrorOccured = true;
function getLocation ()
{
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition (onGeoSuccess);
}
}
function onGeoSuccess(position)
{
document.getElementById("currentUserLattitude").value = position.coords.latitude;
document.getElementById("currentUserLongitude").value = position.coords.longitude;
anErrorOccured = false;
}
function submitData ()
{
if (anErrorOccured)
{
return false;
}
else
{
return true;
}
}
Basically the anErrorOccured variable is set to true and only if the position is set successfully you will mark it as false. And don't forgot to use 'return' when attaching some function to onsubmit event:
<form action="/login" onsubmit="return submitData()" method="POST">
You can also disable your submit button based on this flag, to be more user friendly.
Upvotes: 0