How to prevent form submission until onsubmit function completes? - javascript

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);
}

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>

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.

Change from using an onSubmit to onComplete

Related

GPS location is fetched after second click not on first click

I want to fetch live gps location using javscript to store it in database. I already have implemented it. when user clicks on button. But it fetches location on second click.
Html code
<form action="user_location" method="post" id="form-{{$user->id}}">
#csrf
<input type="hidden" name="id" value="{{$user->id}}">
<input type="hidden" name="location" id="location-{{$user->id}}">
</form>
<a onclick="getLocation({{$user->id}})" class="btn">{{__('Get Location')}}</a>
Javscript code
function getLocation(user_id) {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
geolocation = "Geolocation is not supported by this browser.";
}
if(setlocation){
form = document.getElementById("form-"+user_id);
var b = document.getElementById("location-"+user_id)
b.value = x.textContent;
form.submit();
}
}
function showPosition(position) {
x.innerText = position.coords.latitude + "-" + position.coords.longitude;
setlocation = true;
}
The getCurrentPosition function is asynchronous. That means that when it is called, it will allow the code after it to run before finishing. So that means that setLocation will not be true whenever your code reaches the following if statement:
if(setlocation){ // setlocation is still false
Handle your results of getting the position inside the success callback of getCurrentPosition.
function getLocation(user_id) {
if (!navigator.geolocation) {
return;
}
const form = document.getElementById("form-" + user_id);
const location = document.getElementById("location-" + user_id);
navigator.geolocation.getCurrentPosition(function(position) {
const { coords } = position;
location.value = coords.latitude + "-" + coords.longitude;
form.submit();
});
}

Integrating Google's reCaptcha v3 with Recurly's JavaSript API

I am using Recurly's JavaScript API to process subscriptions payments.
I want to implement Google's reCaptcha V3 API to the Recurly's self-hosted page.
<script src="https://js.recurly.com/v4/recurly.js"></script>
recurly.configure({
publicKey : 'xxx-xxx',
required : ['cvv', 'address1', 'city', 'state', 'country', 'postal_code'],
});
// When a customer hits their 'enter' key while in a field
recurly.on('field:submit', function (event) {
$('form').submit();
});
// On form submit, we stop submission to go get the token
$('form').on('submit', function (event) {
// Prevent the form from submitting while we retrieve the token from Recurly
event.preventDefault();
// Reset the errors display
$('#errors').text('');
$('input').removeClass('error');
// Disable the submit button
$('button').prop('disabled', true);
var form = this;
// Now we call recurly.token with the form. It goes to Recurly servers
// to tokenize the credit card information, then injects the token into the
// data-recurly="token" field above
recurly.token(form, function (err, token) {
// send any errors to the error function below
if (err) error(err);
// Otherwise we continue with the form submission
else form.submit();
});
});
Things is, Google's API implementation is something like this :
<input type="hidden" name="recaptcha_response" id="recaptchaResponse">
<button type="submit" id="btn-submit" class="g-recaptcha" data-sitekey="xxxxxxxxx" data-callback='onSubmit' data-action='submit'>Submit</button>
<script>
function onSubmit(token)
{
document.getElementById("recaptchaResponse").value = token;
document.getElementById("frm-subscribe").submit();
}
</script>
Both have their own version of onSubmit. How do I include Google's one into Recurly's ?
<input type="hidden" name="recaptcha_response" id="recaptchaResponse">
<button type="submit" id="btn-submit">Submit</button>
recurly.token(form, function (err, token) {
// send any errors to the error function below
if (err) error(err);
// Otherwise we continue with the form submission
else
{
grecaptcha.ready(function()
{
grecaptcha.execute('xxx-xxx-site-key', {action: 'submit'}).then(function(token)
{
document.getElementById("recaptchaResponse").value = token;
form.submit();
});
});
}
});

$.getJSON request does not work on button click

I have tried to find a solution to this problem, I'm currently at a loss. I'm trying to gather info on streams using the twitch API.
I am able to get a .getJSON request to work when I pass in an array of usernames, null is returned if the user is offline or invalid.
$(document).ready(function() {
var streamers = ["ESL_SC2","OgamingSC2","cretetion","freecodecamp","storbeck","habathcx","RobotCaleb","noobs2ninjas","meteos","c9sneaky","JoshOG"];
var url = "https://api.twitch.tv/kraken/streams/";
var cb = "?client_id=5j0r5b7qb7kro03fvka3o8kbq262wwm&callback=?";
getInitialStreams(streamers, url, cb); //load hard-coded streams
});
function getInitialStreams(streamers, url, cb) {
//loop through the streamers array to add the initial streams
for (var i = 0; i < streamers.length; i++) {
(function(i) {
$.getJSON(url + streamers[i] + cb, function(data) {
//If data is returned, the streamer is online
if (data.stream != null) {
console.log("online");
} else {
console.log("offline");
}
});
})(i);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form class="form-inline">
<input id="addStreamerForm" class="form-control" type="text" placeholder="Add a Streamer">
<button id="addStreamerBtn" class="btn" type="submit">Add</button>
</form>
However, when I try to call the API through a click function (eventually pulling any input through the form) .getJSON fails. As seen below.
$(document).ready(function() {
var url = "https://api.twitch.tv/kraken/streams/";
var cb = "?client_id=5j0r5b7qb7kro03fvka3o8kbq262wwm&callback=?";
$("#addStreamerBtn").click(function(e) {
addStreamer("Ben", url, cb);
});
});
function addStreamer(streamer, url, cb) {
console.log("I'm inside the function");
$.getJSON(url + streamer + cb, function(data) {
console.log("WE DID IT");
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form class="form-inline">
<input id="addStreamerForm" class="form-control" type="text" placeholder="Add a Streamer">
<button id="addStreamerBtn" class="btn" type="submit">Add</button>
</form>
I don't understand why the code won't work for the 2nd snippet. Any guidance would be greatly appreciated.
The issue is because you've hooked to the click event of the submit button. This means that the form is being submit as your AJAX request happens, so the page is immediately unloaded and the AJAX cancelled.
To fix this, hook to the submit event of the form, and call preventDefault() on the event. Try this:
$(document).ready(function() {
var url = "https://api.twitch.tv/kraken/streams/";
var cb = "?client_id=5j0r5b7qb7kro03fvka3o8kbq262wwm&callback=?";
$(".form-inline").submit(function(e) {
e.preventDefault();
addStreamer("Ben", url, cb);
});
});
function addStreamer(streamer, url, cb) {
console.log("I'm inside the function");
$.getJSON(url + streamer + cb, function(data) {
console.log("WE DID IT");
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form class="form-inline">
<input id="addStreamerForm" class="form-control" type="text" placeholder="Add a Streamer">
<button id="addStreamerBtn" class="btn" type="submit">Add</button>
</form>

Javascript form validation doesn't execute

I have an input box. Upon submit, I have a PHP script which checks to see if the input box is empty. If it is, it displays an error message and runs a Javascript function.
My problem is that the error message appears, but the Javascript function doesn't execute.
Here's my script:
<?php
if(isset($_POST['submit'])) {
$username = $_POST['username'];
if(empty($username)) {
echo 'Please enter a username';
echo"
<script>
window.onload = function () {
function validate(e) {
var username = document.getElementById('username');
if (username.value.trim() == '') {
username.classList.add('error');
setTimeout(function() {
username.classList.remove('error');
}, 300);
e.preventDefault();
}
}
}
</script>
";
}else{
// something here
}
}
?>
<form method="post" id="login">
<input type="text" id="username" name="username">
<input type="submit" name="submit">
</form>
Where does your JavaScript function actually get executed? Removing the logic, the structure of what you have is:
window.onload = function () {
function validate(e) {
//...
}
}
So when the window loads, you execute a function. That function does nothing more than define another function. Nothing ever executes that other function.
If you want to execute that code when the window loads, don't wrap it in a function. Just execute it:
window.onload = function () {
// validation logic here
}

Form submits correctly in Chrome/FF, but fails altogether in IE/Safari

I have a form with a css submit button. When a the submit button is clicked, i call a function that executes:
document.forms["request"].onsubmit();
What should happen, then, is that the onsubmit method ought to be triggered. This works properly in Chrome/FF, but for some reason IE/Safari will bypass the onsubmit function and simply add the parameter "address=" onto the url as if it were submitting the form and ignoring the onsubmit function. Heres the code for the form:
<form id="request" method="get" onsubmit="addLocation(this.address.value); return false;">
<br>
<label style="position:relative;left:5px;" for="address">Enter an intersection or address:
</label>
<br>
<br>
<input style="height:35px; width:300px;position:relative;bottom:1px;left:10px;" id="address" name="address" class="required address"/>
<a style="float:right;right:120px;position:relative;" class="button" onclick="submit();">
<span>Submit Request
</span>
</a>
</form>
and what follows are some relevant js functions:
function addLocation(address) {
if (geocoder) {
geocoder.getLocations(address, function (point) {
if (!point) {
alert(address + " not found");
} else {
if (point.Placemark[0].address != submittedString) {
submittedString = point.Placemark[0].address;
addRow(point.Placemark[0].address);
req = "addrequest?truck=" + "coolhaus&address=" + point.Placemark[0].address;
alert(req);
addRequest(req);
request.onreadystatechange = function () {}
}
}
});
}
}
function addRequest(req) {
try {
request = new XMLHttpRequest();
} catch (e) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
alert("XMLHttpRequest error: " + e);
}
}
request.open("GET", req, true);
request.send(null);
return request;
}
You can test the form here:
http://la.truxmap.com/request?id=grillmastersla
Thanks so much!
Don't name your function "submit", there is already a method in the form with that name, so it can conflict with that.
It's the submit method that you can call to submit the form, not the onsubmit event. So, your code to post the form should be:
document.forms["request"].submit();

Categories

Resources