How to run reCaptcha ONLY if HTML5 validation has passed?

Viewed 14253

Usually, HTML5 form validation runs before the submit event.

With this

<form id="myForm">
    <input  type="text" name="foo" required />

    <button type="submit"> Submit </button>

</form>

<script>
    $("#myForm").on('submit',function(){
        console.log("I'm entering the submit event handler");
    });
</script>

if the input field is empty, the submit event handler doesn't run. It will be triggered only if the HTML5 validation (the required attribute, in this case) has passed.

I'd expect a captcha to run after the HTML5 validation too; why do I have to annoy the user compiling a captcha if later on I'd warn him there are missing fields ? First I should force the user to do everything in the right way, then ensure it's a human and not a bot, IMHO.

Appearently, reCaptcha does something on the form it attaches on, removing the HTML5 validation feature.

For example, using the latest Invisible reCaptcha:

<form id="myForm">
    <input  type="text" name="foo" required />

    <button type="submit"
           class="g-recaptcha" 
    data-sitekey="your_site_key" 
   data-callback='myCallback'> Submit </button>

</form>

<script>
    function myCallback(token){
        $("#myForm").submit();
    }

    $("#myForm").on('submit',function(){
        console.log("I'm entering the submit event handler");
    });
</script>

The form will be submitted with the empty field, without notifying the user about its obligatoriness.

Any clue on why it acts like this ? Is there a way I can instruct reCaptcha to let HTML5 form validation run before taking control ?

2 Answers

maechler's answer is excellent, however, if one does not want to use jQuery, you can add the event listener with an iife

(function() {
    document.getElementById("my-form").addEventListener("submit", function(event) {
        console.log('form submitted.');
        if (!grecaptcha.getResponse()) {
            console.log('captcha not yet completed.');

            event.preventDefault(); //prevent form submit
            grecaptcha.execute();
        } else {
            console.log('form really submitted.');
        }
      });
  })();

I hope that helps.

Related