I have implemented new Google's INVISIBLE reCaptcha on several sites successfully, however, it conflicts with jQuery validate(), in such a way that the js validation is no longer executed on button/form submit, and reCaptcha instantly kicks-in. If user forgets to fill-in a requried form field, it will have to wait for server response, and get back to it next time.
jQuery .validate() supports callback, but because of the fact that it is hard-coded inside an internal class of a CMS, is there a way I can modify it somehow outside (e.g. from front-end theme, on document load, when validation code is already rendered)?
Or, another idea would be to postpone captcha's callback somehow, so that validation step can get a chance to run.
Thanks!
jQuery Validate form: (hard-coded in the core, can't be modified, unless I edit core file or extend class/clone function - not optimal)
<script type="text/javascript">
$(document).ready(function(){
$("form[name=comment_form]").validate({
rules: {
body: {
required: true,
minlength: 1
},
authorEmail: {
required: true,
email: true
}
},
wrapper: "li",
errorLabelContainer: "#comment_error_list",
invalidHandler: function(form, validator) {
$('html,body').animate({ scrollTop: $('#comment_error_list').offset().top }, { duration: 250, easing: 'swing'});
},
submitHandler: function(form){
$('button[type=submit], input[type=submit]').attr('disabled', 'disabled');
form.submit();
}
});
});
</script>
reCaptcha explicit render:
<script type='text/javascript'>
var renderInvisibleReCaptcha = function() {
for (var i = 0; i < document.forms.length; ++i) {
var form = document.forms[i];
var holder = form.querySelector('.invisible-recaptcha');
if (null === holder) continue;
(function(frm){
var holderId = grecaptcha.render(holder, {
'sitekey': 'my-key-here',
'badge': 'inline',
'size': 'invisible',
'callback': function (recaptchaToken) {HTMLFormElement.prototype.submit.call(frm);},
'expired-callback': function(){grecaptcha.reset(holderId);}
});
frm.onsubmit = function (evt){evt.preventDefault();grecaptcha.execute(holderId);};
})(form);
}
};
</script>
I had the same problem, I finally found the right way to integrate jquery validate with invisible reCaptcha. It's a mix of some of the proposed solutions here.
First of all, the the HTML part:
<div class="g-recaptcha" data-sitekey="<your key here>"
data-size="invisible"
data-callback="formSubmit">
</div>
Then, you must implement the reCaptcha callback in that way:
function formSubmit(response) {
// submit the form which now includes a g-recaptcha-response input
$("#orderform").submit();
return true;
}
And finally, the tricky part is in the jquery validate's submitHandler:
submitHandler: function (form) {
if (grecaptcha.getResponse()) {
// 2) finally sending form data
form.submit();
}else{
// 1) Before sending we must validate captcha
grecaptcha.reset();
grecaptcha.execute();
}
}
The sequence is as follows:
Hope this helps.