The Invisible reCAPTCHA lets you easily set a callback upon successful verification:
<button class="g-recaptcha" data-sitekey="your_site_key" data-callback='successfulVerification()'>Submit</button>
But it doesn't appear to have any option to trigger a callback if the modal for further verification is closed (or the reCAPTCHA is unable to verify that you're a human - actually not sure if this ever happens, maybe it just keeps showing you new challanges forever?)
The reason why this is important is say we have a loading spinner or some kind of visual cue to show the user that we're working on the submission. If the reCAPTCHA is unable to automatically determine that the user is indeed human, the modal will be shown - now if the user completes it successfully then that's fine - but if he/she exits it, the loading spinner will still be visible as it doesn't know that the reCAPTCHA failed/user exited it.
One workaround is to only show the loading spinner after the reCAPTCHA succeeds and the request begins - however this would be a poor experience for the user as there would be a delay between clicking the button and the form "appearing" to be submitted - leaving the user to possibly wonder if the form actually submitted or not.
Any ideas on how to remedy this? Thanks!
I haven't found a solution to this but a hack workaround would be to reenable the submission button after a timeout so at least the user isn't locked out indefinitely if they cancel the recaptcha attempt.
var timeout = setTimeout(function () { enableSubmit(); }, 3000);
grecaptcha.render(elem, {
...
callback: function (token) {
clearTimeout(timeout);
continueWithSubmission();
}
});
grecaptcha.execute();
Related
I have a page that presents a test, where javascript sets a timeOut to abandon the page if the user waits too much (180") before giving an answer and pressing submit.
It has to be done for various reasons, and I cannot modify the committment.
After 180" on the page, so, currently the code goes back to a beginningpage.php where the user will have to re-enter its unique ID to continue the test.
This is the simple javascript code:
setTimeout(function () {
window.location.href= "beginningpage.php";
}, 180000);
Everything runs smooth. Now I need to modify the code to better manage the case. We assume that if the user has gone away, it will not be able to answer to an alert box. So let's say we push a confirm() after those 180".
How to write code so that - when the confirm() windows is displayed - if nobody clicks a confirm button (for let's say 30") the code automatically close the confirm window and leaves the page going back to beginningpage.php?
Otherwise, if the user is still at his desk and is simply wondering about the answer to give, he must be given the possibility to click "ok, I hurry up" to remain on the page for say another 60". That means that after the first displaying of the confirm window, the timeout must be set to a different deadline, not 180000 as before but 60000.
Maybe the idea of using different window.locations.href is not the right one.
How could be the code to accomplish everything I need as above explained?
Just don't use a confirm box... Show a div with two buttons after 180 seconds and then start counting your 30 seconds.
So let's say we push a confirm() after those 180".
How to write code so that - when the confirm() windows is displayed - if nobody clicks a confirm button (for let's say 30") the code automatically close the confirm window and leaves the page going back to beginningpage.php?
You can't. confirm, alert, and promopt are 1990s holdovers with stop-the-world behavior. (Mostly. Browsers are eroding that slowly over time.) That means none of your JavaScript code can run while the archaic window is showing.
Instead, switch to using modern alerting techniques (showing a "modal" div, etc.) so that your JavaScript code can use setTimeout to give up after the relevant amount of time.
You can never achieve this with alert or confirm because they block further js execution till the popup is active.
You need a custom modal with html element and a js function
All you have to do is call clearTimer for auto-page reload based on the response from custom confirm modal.
var x = document.getElementById("stopReloadBtn")
var reloadTimer
setTimeout(function() {
x.style.display = "block"
reloadTimer = setTimeout(function() {
window.location.href = "beginningpage.php"
}, 5000)
}, 5000);
function stopReload(){
clearTimeout(reloadTimer)
x.style.display = "none"
}
<button id="stopReloadBtn" style="display: none" onclick="stopReload()">Still Here?</button>
I have reduced the timers to 5 sec in this code. A button will appear after 5 sec. After which you will have 5 sec to click this button else the page will reload.
I've added ajax calls that fire when a user leaves a text box to automatically save their text. There is also a save button at the bottom of the page (the save button is still necessary because it permanently archives the document state at that point in time).
The problem is when a user edits a text box and then directly clicks the submit button. The ajax request is made but then the submit request kills it and I get an error. If I don't get a successful response back from the server then I display a message letting the user know there is a problem (long story short, we've had issues with users spending a long time entering data and then for whatever reason it doesn't get submitted and they lose it all).
In the case that they hit the Save button, I don't care that the request is cancelled because the hitting Save is, obviously, going to Save the data anyway. How can I differentiate between an ajax error where connectivity was lost versus one where it was cancelled because the form was submitted?
I tried this:
var formIsSubmitting = false;
$(document).ready(function () {
$('form').on('submit', function (e) {
debugger;
formIsSubmitting = true;
});
});
function handleError(xmlRequest) {
debugger;
if (!formIsSubmitting)
alert(xmlRequest.status + ' \n\r ' + xmlRequest.statusText + '\n\r' + xmlRequest.responseText);
}
This didn't work though. Also it doesn't break on either of the debugger lines so not sure what's up with that either.
EDIT:
Here's what the button looks like:
<asp:LinkButton ID="lbnSaveP1" runat="server" OnCommand="GoToPage"
OnClientClick="return validateP1();" CommandName="1" CommandArgument="1" />
validateP1 doesn't do anything fancy... just what you'd expect.
I am trying to implement some code to prevent the back button from doing anything on a page in my site. Page posts a form to process a payment, so don't want the user to press back otherwise it ends up in a weird user experience. There is serverside code to handle it, but would like to prevent it clientside as much as possible.
My issue is that even if I use methods like the ones mentioned here: how to stop browser back button using javascript
The problem is that although the page never goes back now, as soon as the back button is pushed the form POST gets canceled.(Using Chrome browser.)
Code I have currently is:
function() {
if(window.history && window.history.pushState) {
window.history.pushState({ page: 1 }, $(document).find("title").text(), null);
window.addEventListener('popstate', function (e) {
e.preventDefault();
e.stopPropagation();
window.history.pushState({ page: 1 }, $(document).find("title").text(), null);
});
}
else {
window.location.hash = "pp";
window.onhashchange = function (e) {
e.preventDefault();
e.stopPropagation();
window.location.hash = "pp";
};
}
}
Is there actually anything I can do here?
Unfortunately there's not a lot you can do. You can stop the end result of pressing the back button (changing the page), but you can't stop the side effects of clicking it (causing currently pending requests to halt).
The best you can do is capture when the back button is pressed, determine if the form was sent but no response was received, and then alert the user that the form was likely sent. Then you could attempt to direct the user to next page, which you could design to kick back to the payment page if none was received.
It's problems like this that are hard to analyze for edge cases. :)
There are some very interesting questions here for stopping execution and most of these relate to pausing for a certain time before something else is allowed to occur.
I have a slightly different scenario in my jquery mobile 1.3.2 with the following function which adds an event to user's calendar.
function addToMyCal(typ,id)
{
loginReq();
addToUsrCal(window.wh2usr,"spscId",id);
}
// login required
function loginReq()
{
// check cookie
if (! loginCheck())
$('#popupLogin').popup('open')
}
I observe that, if a user is not logged in, then the login popup is shown but it does not pause to get user credentials. Instead the login popup is displayed, addToUsrCal() is called right away, which fails because there is no user information.
So how do I 1) either wait till user provides credentials without a timeout or 2) allow user to cancel the login and return back to where they were on the site?
Thanks
Your call to $('#popupLogin').popup doesn't wait for any user interaction - it just displays the popup and immediately returns. Then the loginReq function is finished and returns to the caller, addToMyCal. From there, the next line in addToMyCal is executed - the call to addToUsrCal.
If you want to call addToUsrCal only after some user input, then you'll need to move that function call to a callback function - probably tied to the submit action on a form or the click action of a submit button (these presumably already exist in your popup's content).
Similarly, you can add a callback to a cancel button in the popup that will close the popup (using a call to $('#popupLogin').popup("close").
I'm trying to achive the following:
On page A we have an access restricted Link to page B. The access restriction is handled on the server side in PHP.
When a user clicks on this link to page B we display a modal dialogue on page A (via javascript) with a form, having the link's href (B) as the action. (To give the user an immediate feedback. The fallback is to redirect him to a login form that redirects him to the site he wants to access.)
This system works quite well.
But now comes my question:
We have access restricted links that should be opened in a new window.
Now if I use target="_blank" on the form the user stays logged out on the page he came from (A), that is still open in the background.
Is there a way to reload the page (A, in the background) right after the form has been submitted to the new window (B)?
My first idea was to use window.location.reload(); in the submit handler on page A.
This didn't work in chrome and from what I understand could create a race condition.
Another idea would be to log the user in via an ajax call and open a new window through javascript. Is there a way to do this without having to deal with pop-up blockers?
I implemented the idea of lostsource (see below) with one slight addition.
As I need to reload only once, the timer of setInterval can be stopped if the cookie changed.
var ri=setInterval(function() {
if(oldCookie != document.cookie) {
// assuming a login happened, reload page
clearInterval(ri);
window.location.reload();
}
},1000); // check every second
I still love the idea. stackoverflow is awsome!
Assuming you're storing PHP session information inside a cookie, you might be able to monitor your document.cookie for changes.
Before submitting the form store the value of the current cookie and monitor it for changes with a timer:
form.onsubmit = function() {
var oldCookie = document.cookie;
var cookiePoll = setInterval(function() {
if(oldCookie != document.cookie) {
// stop polling
clearInterval(cookiePoll);
// assuming a login happened, reload page
window.location.reload();
}
},1000); // check every second
}
On the parent page, do you have any visual/functional changes because of the login? As in any new actions possible?
If not, then you dont have to do anything as you would be checking for login on every action from the parent page, you can check for permissions along with that.
If there are changes or additional functionalities, you can call a javascript function in the parent, say reloadMe, using window.opener.reloadMe()
Why not just a simple setTimeout
setTimeout(function(){ location.reload(); }, 1000);
It is a bit hacky, but seems appropriate for your situation.