Victordb
Victordb

Reputation: 549

Prevent form submit until recapcha v3 finished loading

I am using Recapcha V3 to insert a hidden input in the form with the token. When the form is submitted I check the token in the backend and act accordingly .

<script src='https://www.google.com/recaptcha/api.js?render={{config("recaptcha.key")}}'></script>
<script>
grecaptcha.ready(function () {
    grecaptcha.execute('{{config("recaptcha.key")}}', {action:  '{{$action}}'}).then(function (token) {
        $('<input />').attr('type', 'hidden')
                .attr('name', 'recaptcha')
                .attr('value', token)
                .appendTo('form');
    });
});
</script>

The problem is when a user submits the form too fast and the input isn't yet appendTo('form'), the backend receives no token and returns the user back to the form page with an validation error (I prevent data from being sent if the token is not present).

I can't figure out how to prevent the form from submitting in the first place, until the token has loaded.

So something like:

If the users clicks submit and the token is not yet loaded do some loading animation and wait for the token and then submit, if the token is present when the user clicks submit just allow the form to be submitted.

Upvotes: 0

Views: 1924

Answers (1)

Maxime Launois
Maxime Launois

Reputation: 958

You'll need to prevent form from being submitted as long as the reCAPTCHA token is not inserted into the form. You can achieve this by using a global variable, which is set after loading reCAPTCHA and checked before submitting the form:

<script src='https://www.google.com/recaptcha/api.js?render={{config("recaptcha.key")}}'></script>
<script>
// Whether the reCAPTCHA token is loaded into the form
var recaptchaLoaded = false;
// Whether the user already attempted submitting the form
var attemptedSubmit = false;

grecaptcha.ready(function () {
    grecaptcha.execute('{{config("recaptcha.key")}}', {action:  '{{$action}}'}).then(function (token) {
        $('<input />').attr('type', 'hidden')
                .attr('name', 'recaptcha')
                .attr('value', token)
                .appendTo('form');

        window.recaptchaLoaded = true;
        if(window.attemptedSubmit) {
            // As the user already attempted a submit,
            // trigger the "submit" mechanism

            // Note that this doesn't trigger the JS "submit" event
            $("#form").submit();
        }
    });
});

// Add an event listener for "submit"
$("#form").submit(function(event) {
    window.attemptedSubmit = true;
    if(!window.recaptchaLoaded) {
        // The reCAPTCHA token has not been inserted
        // Prevent submission of the form
        event.preventDefault();

        // Your button animation logic here...
    }
});
</script>

Upvotes: 2

Related Questions