Know if reCaptcha v2 was checked or not

Hello,

I have a very simple static site, using Netlify form feature with reCaptcha v2 : Test - Contact

I am looking for a way to have a simple form validation, know if the captcha was checked and validated or not, simply to enable/disable submit button depending on this result.

Is it any possible ? Maybe there is an event in JS telling that the captcha was checked ?
Or should I go with my custom reCaptcha solution instead of using Netlify one ?

Thank you

Hi @SimonWMX

While I’ve not played with this myself, Verifying the user's response  |  reCAPTCHA  |  Google Developers might have some useful information for you.

Hi @coelmay ,
Thank you for your answer.

I need to check if the captcha was checked before the form is submitted, so according to this documentation the only option that seems suitable to me is what they call
" grecaptcha.getResponse(opt_widget_id) after the user completes the reCAPTCHA challenge "

Because the other option is using a callback, and I don’t think it’s possible to set this with built-in Netlify reCaptcha implementation.

Honestly, I don’t understand much about reCAPTCHA v2  |  Google Developers

I need to use

grecaptcha.getResponse(
opt_widget_id
)

But I have no idea, when and where and how, and if it is actually possible with Netlify captcha feature

Found this good example the example to use recaptcha in javascript · GitHub which fires on clicking the submit button though this probably wouldn’t work if you are wanting the button disabled by default until the user is verified.

An answer on javascript - ReCaptcha v2 client side events - Stack Overflow uses data-callback as mentioned on reCAPTCHA v2 Configuration to call a specific function. This function (in your case) could enable the submit button on your form.

I don’t have a working example for you at the moment though but if you are struggling, I’ll see what I can do.

Going back to your original post, there is no need to disable/enable the submit button when using reCaptcha. If the captcha is not solved, submitting the form won’t work (that’s how it’s meant to work.)

However, that said, if you really wish to do so, this is what I have managed to get working

function unHideButton() {
    const response = grecaptcha.getResponse()
    if (response.length !== 0) {
        // `submitBtn` is the id I gave the form submit button
        document.getElementById('submitBtn').disabled = false
    }
}
const addCallback = setTimeout(() => {
    // Need to check reCaptcha exists before adding callback
    // or reCaptcha will fail to load
    if (grecaptcha) {
        const rcv2 = document.querySelector('.g-recaptcha');
        rcv2.dataset.callback = "unHideButton";
        clearTimeout(addCallback);
    }
}, 100);
1 Like

Hi @coelmay ,

Thank you very much for such a fast and detailed answer.

I think there was a misunderstood : I am using reCaptcha v2 Netlify built-in feature, as described here : Spam filters | Netlify Docs

I am using the basic one, just by adding data-attribute to my form : data-netlify-recaptcha="true"
So, I do not have any reCaptcha lib JS code directly included into my project, and I do not have any API key. That makes the github example you provided not usable in my case.

Still tried the code from your second answer, and it doesn’t seem to be working ! The button remains disabled. I actually got this error :

site-3678d344c97845021729.js:517 Uncaught TypeError: grecaptcha.getResponse is not a function
    at unHideButton (site-3678d344c97845021729.js:517)
    at HTMLDocument.<anonymous> (site-3678d344c97845021729.js:195)

Also note that using reCaptcha feature from Netlify does not prevent the form to be sent when the captcha is not checked, the form is still being sent, and current page reloads, losing all the data typed in the form.

So if it is not possible to play with my submit button, I think another alternative would be to use a cookie to store the data typed into the form, in case of the user doesn’t check the captcha, I can redirect him to the same page, with the form pre-filled with previous data, and maybe a notice telling him to make sure he checks the box.

What do you think ?

Hi @SimonWMX,

If you’re submitting the form using AJAX, there might be a solution (there might be one without AJAX too, but I could think of this AJAX one first).

So, if someone clicks on the submit button, you can call the following:

if (grecaptcha.getResponse().length > 0) {
// submit the form
} else {
// reject the submission show an error, but don't call form.reset(), so the data stays as it is
}

The value of grecaptcha.getResponse() is '' when it’s not checked and a big string when it is checked. So, you can check for its length.

I used this method too in my example.

The reason for this, and the reason for the error, is the code is firing before grecaptcha is loaded (my example page contained little more than the form so loaded much quicker than your page.)

You have an action="/contact-succes" on your form which returns a 404 Not Found.

I don’t believe you need to “play” with your button. I advise you to remove the code I previously provided as it isn’t working in your situation. I suggest you remove reCaptcha and ensure your form works properly first (submitting, redirecting to success page, et.al.) ensuring there are no errors in the console. Then, add in reCaptcha and test again.

Thanks for your answers guys !

@hrishikesh unfortunately I am not using AJAX, I am oldschool and still allergic to JS :sweat_smile:

@coelmay oops, my bad. This is a test version of my custom CMS, and i reduced it to the minimum so I forgot the ‘contact success’ page. I just put it back. I am already using this kind of form for many projects and submissions work fine, with and without reCaptcha

Sorry about that, I am the one that didn’t understand correctly !

I use this :


document.addEventListener("DOMContentLoaded", function() {
  ...
  unHideButton();
});

Thought that’d wait until everything is loaded.

Updated my page with 2 buttons to test the feature (one disabled with the id submitBtn and another to test the submission, which works fine so far)
https://fervent-spence-9d6010.netlify.app/contact.html

What else would you suggest then ?

I just tested your form. Without the reCaptcha checked, the page reloaded (I navigated back to the page and the entered data was still there.) With it checked the form submitted and I was redirected to the success page.

There is still an error even with your event listener (grecaptcha.getResponse is not a function) as you are calling the function (twice even lines ~186 and ~195) i.e.

document.addEventListener("DOMContentLoaded", function () {
  // setAffixMinHeight();
  startFlexImages();
  initTobi();
  HideCookiesNotice();
  unHideButton();
});

This function is meant to get called once the reCaptcha is checked (hence why adding data-callback="unHideButton" through the rcv2.dataset.callback = "unHideButton"; line in the script I provided previously.)

I don’t know I can suggest anything more than I already have.

Hi @coelmay

I really appreciate your help and I want to tell you thank you very much once again.

Though, it is still not working.

Yes, that’s actually the behaviour I want to get rid off. Avoid getting the page reloaded and losing the data (ok we got it back when we do history back, but most of normal users don’t know that).

This is why I want to disable the button to prevent getting the form sent when captcha isn’t checked.
I plan to add a small notice “onClick” telling “please check the captcha”

Now calling it one time only, and still getting the error

Sorry I don’t understand much this point, I have difficulties to read JS code, specially new generation one.

This code is supposed to add data-callback attribute to my form ?
Or am I supposed to add this data attribute to my markup ?

Talking about data-callback confuses me, I don’t understand what it means exactly

I was suggesting you needed remove both calls to the function. You are trying to execute the unHideButton function prior to the availability of grecatpcha (i.e. it hasn’t loaded yet) so it throws an error. As mentioned previously this function is meant to get called after the captcha is checked as a callback function (by way of data-callback.)

The code I provided is adding the data-callback because adding it prior to the rendering of grecatpcha is not possible (as far as I can tell.) Currently the callback isn’t added because of the above (early firing of the function.)


Edit:
If you are still wanting to disable/enable the submit button, you can try this.

<script>
  function unHideButton() {
    if (grecaptcha.getResponse().length > 0) {
      document.getElementById('submitBtn').disabled = false
    }
  }
  document.addEventListener("DOMContentLoaded", () => {
    if (typeof grecaptcha === "object") {
      document.querySelector('.g-recaptcha').dataset.callback = "unHideButton"
    } else {
      console.log("Unable to add `data-callback` to grecaptcha as it doesn't exist.");
    }
  });
</script>
1 Like

In all this, I have overlooked one very simple thing, namely the required attribute.

Simply changing your email field (and any others that you require filled in by the user) to include required stops a form being submitted irregardless of reCaptcha.

Demonstration:

email-required

(Note: I modified your form for this demo.)

Your form email field is currently:

<input type="email" name="email"
  class="form-control rounded-0 mb-3 p-4"
  placeholder="Votre adresse e-mail">

Now just add required to it (and other fields) i.e.

<input type="email" name="email"
  class="form-control rounded-0 mb-3 p-4"
  placeholder="Votre adresse e-mail"
  required>

And you have no need to use disabled="true" and no need to use JavaScript to check if reCaptcha is checked or not.

Sometimes solutions are much simpler than they seem.

Hi @coelmay ,

Thank you !
Tried your suggestion to enable the submit, and this one works like a charm !
https://fervent-spence-9d6010.netlify.app/contact.html

Second suggestion is also interesting, indeed required attribute will prevent form to be submitted, but only if there is a missing field !
If for example I fill all the fields, and forgot the captcha, it won’t block the form submission. Also I prefer not having all fields required, it could discourage some users to send messages.

Thank you very much for your help, really appreciate !

This was a nice solution and was going to use it, but I came across a small nuisance.
I’ve got some required fields that have validation which could delay the time to submit after completing captcha. In some cases this would mean that the captcha is invalidated. I’ve wanted to have the submit button to stay enabled .

my solution was to use the form’s onsubmit handler

<script is:inline>
    document.getElementById('form').addEventListener('submit', function (event) {
      if (window.grecaptcha.getResponse().length > 0) { return; }
      event.preventDefault();
    });
</script>

Hi @cejka

thank you for sharing your solution! This is definitely helpful for other users

HI, thanks for your post.

I think is a simple idea!

But I don’t know how implemented… can you show me?

Thanks