New reCaptcha with jQuery Validation Plugin

bluantinoo picture bluantinoo · Apr 10, 2015 · Viewed 62.3k times · Source

I searched and can't figure out how to validate the new reCaptcha, before form submit, along with the validate function of jQuery validation Plugin.

My intent:

    $.validator.addMethod('reCaptchaMethod', function (value, element, param) {
            if (grecaptcha.getResponse() == ''){
                return false;
            } else {
                // I would like also to check server side if the recaptcha response is good
                return true
            }
        }, 'You must complete the antispam verification');


    $("#form").validate({
            rules: {
                name: {
                    required: true,
                    minlength: 2
                },
                email: {
                    required: true,
                    email: true
                },
                reCaptcha: {
                    reCaptchaMethod: true   
                }
            },
            messages: {
                name: "Please fill your name",
                email: "Please use a valid email address"
            },
            submitHandler : function () {
                        $.ajax({
                            type : "POST",
                            url : "sendmail.php",
                            data : $('#form').serialize(),
                            success : function (data) {
                                $('#message').html(data);
                            }
                        });
                    }


        });

In a few words: I would like to check server-side, with the remote method, if the user has passed the recaptcha validation BEFORE submitting the form, along with other rules of validation.

I'm able to check the recaptcha AFTER submission (on sendmail.php), but it would be nicer to have the recaptcha validation response along with other fields validation.

The main reason is for a better user experience, having all fields checked at once.

I've managed to achieve this, moving the check inside the submitHandler:

            submitHandler : function () {
                  if (grecaptcha.getResponse() == ''){
                      // if error I post a message in a div
                      $( '#reCaptchaError' ).html( '<p>Please verify youare human</p>' );

                  } else {

                        $.ajax({
                            type : "POST",
                            url : "sendmail.php",
                            data : $('#form').serialize(),
                            success : function (data) {
                                $('#message').html(data);
                            }
                        });
                    }

             }

But I don't like this approach, for 2 reasons:

  1. It is just checking if the recaptcha has been filled, not if it's valid, and
  2. User feels like it is a 2 step verification.

In this answer they say it can be done rendering the Recaptcha on a callback, to specify a function call on a successful CAPTCHA response.

I tried to implement that, but I've not been able to use this solution within a rule of the validate() function.

Answer

FabioG picture FabioG · Jan 12, 2016

I know this question is a bit dated but I was having the same problem and just found the solution. You can do this by adding a hidden field next to the reCaptcha div, like:

<div class="g-recaptcha" data-sitekey="{YOUR-SITE-KEY-HERE}"></div>
<input type="hidden" class="hiddenRecaptcha required" name="hiddenRecaptcha" id="hiddenRecaptcha">

then in your javascript:

$("#form").validate({
        ignore: ".ignore",
        rules: {
            name: {
                required: true,
                minlength: 2
            },
            email: {
                required: true,
                email: true
            },
            hiddenRecaptcha: {
                required: function () {
                    if (grecaptcha.getResponse() == '') {
                        return true;
                    } else {
                        return false;
                    }
                }
            }
        },(...rest of your code)

NOTICE THAT YOU MUST HAVE the ignore: ".ignore" in your code because jquery.validate ignores hidden fields by default, not validating them.

If you want to remove the error message on reCapcha validate add a data-callback to the reCapcha element

<div class="g-recaptcha" data-sitekey="{YOUR-SITE-KEY-HERE}" data-callback="recaptchaCallback"></div>

And then in your js file add

function recaptchaCallback() {
  $('#hiddenRecaptcha').valid();
};