5

I've integrated reCAPTCHA and it is working fine, except for when the users are too quick to click the Submit button right after checking the "I'm not a robot" checkbox. It takes quite some time for reCAPTCHA to register the user action via Ajax, and if they click on Submit too quickly, the g-recaptcha-response is missing, and the validation fails.

Hence my question: how to I grey out the Submit button until g-recaptcha-response value is available?

    <form id="capform" action="/captchaverify" method="POST">
        <div class="g-recaptcha" data-sitekey="..."></div>
        <p>
        <input id="capsubmit" type="submit" value="Submit">
    </form>
rustyx
  • 80,671
  • 25
  • 200
  • 267
  • Possible duplicate of [ReCaptcha 2.0: enable Submit button on callback if recaptcha successful](http://stackoverflow.com/questions/30018213/recaptcha-2-0-enable-submit-button-on-callback-if-recaptcha-successful) – manniL Oct 16 '16 at 17:20

2 Answers2

5

I ended up using the data-callback attribute as described in the documentation:

<form action="/captchaverify" method="POST">
    <div class="g-recaptcha" data-sitekey="..." data-callback="capenable" data-expired-callback="capdisable"></div>
    <p>
    <input id="capsubmit" type="submit" value="Submit">
</form>

JavaScript (mootools-based, but the general idea should be clear):

function capenable() {
    $('capsubmit').set('disabled', false);
}
function capdisable() {
    $('capsubmit').set('disabled', true);
}
window.addEvent('domready', function(){
    capdisable();
});
rustyx
  • 80,671
  • 25
  • 200
  • 267
0

Here's an example that begins with the submit button disabled, and enables it once the callback is received from reCaptcha. It also uses jquery validate to ensure the form is valid before submitting.

var UserSubmitted = {
    $form: null,
    recaptcha: null,
    init: function () {   
        this.$form = $("#form").submit(this.onSubmit);
    },
    onSubmit: function (e) {
        if ($(this).valid()) {
            var response = grecaptcha.getResponse();
            if (!response) {
                e.preventDefault();
                alert("Please verify that you're a human!");
            }
        }
    },
    setupRecaptcha: function (key) {
        UserSubmitted.recaptcha = grecaptcha.render('recaptcha', {
            'sitekey': key,
            'callback': UserSubmitted.verifyCallback
            //'theme': 'light'//,
            //'type': 'image'
        });
    },
    verifyCallback: function (response) {
        if (response) {
            $(".visible-unverified").addClass("hidden");
            $(".hidden-unverified").removeClass("hidden");
        }
    }
};

I call setupRecaptcha from the page with a named function that's part of the js include.

<script>
    var recaptchaLoader = function () {
        UserSubmitted.setupRecaptcha("yourkey");
    };
</script>

<script src="https://www.google.com/recaptcha/api.js?onload=recaptchaLoader&render=explicit" async defer></script>

You could simplify this. I use it in a multi-tenant application with different keys, and UserSubmitted is actually part of a larger library. You can't usenamespaces (UserSubmitted.somefunction) as the onload param either (to my knowledge).

ScottE
  • 21,530
  • 18
  • 94
  • 131