Multiple ReCaptcha on the same page
Been trying to use multiple Google reCAPTCHAs on the same page with mixed success. Reason for doing this is for example a login page with a reCAPTHCA for the login form and a modal opening with a reset password form. I prefer to use the “invisible” reCAPTCHA since it gives a cleaner look. To be able to use the native validation of forms in HTML5 i need to manually execute the reCAPTCHA when the form is submitted which gave me issues with multiple reCAPTCHAs.
Problem
I have the form in need of HTML5 validation before submit, with tags like “required” and type=”email” etc. To be able to do this I can’t put the reCAPTCHA data triggers on the button because it overrides the validation. Instead i use a hidden reCAPTCHA like this one:
[html]
<div id="capt_login" class="g-recaptcha" data-sitekey="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" data-size="invisible" data-callback="Login"></div>;
[/html]
Then with jQuery i override the submit event of the form and executes the reCAPTCHA like this:
[js]
$("#frm_login").submit(function(event) {
event.preventDefault();
grecaptcha.reset();
grecaptcha.execute();
});
[/js]
That will work just fine for one reCAPTCHA or the first one on the page but not for a second or third one. The reason for this is the reset and execute functions provided by reCAPTCHA. If you don’t give it the ID of the reCAPTCHA widget it presumes first. You can, as I did, wish that reCAPTCHA was implemented in a “provide the div id” fashion but NO!
Solution
The reCAPTCHA widget id is actually just the index of the widget for the order they appear in the DOM. So I put together this simple snippet:
[js]
function GetReCaptchaID(containerID) {
var retval = -1;
$(".g-recaptcha").each(function(index) {
if(this.id == containerID)
{
retval = index;
return;
}
});
return retval;
}
[/js]
I then changed my submit event override to this:
[js]
$("#frm_login").submit(function(event) {
event.preventDefault();
var reCaptchaID = GetReCaptchaID("capt_login");
grecaptcha.reset(reCaptchaID);
grecaptcha.execute(reCaptchaID);
});
[/js]
This makes every reCAPTCHA on the page work an call their correct callbacks once completed.