How do I show multiple recaptchas on a single page?
I have 2 forms on a single page. One of the forms has a recaptcha displaying all the time. The other should display a recaptcha only after a certain event such as maxing out login attempts. So there are times when I would need 2 recaptchas to appear on the same page. Is this possible? I know I could probably use a single one for both, but the way I have the layout, I would much prefer to have 2. Thanks.
Update: well I guess it may not be possible. Can anybody recommend another capture library to use side by side with reCaptcha? I really want to be able to have 2 captchas on the same page.
Update 2: What if put each form in an iframe? Would this be an acceptable solution?
With the current version of Recaptcha (reCAPTCHA API version 2.0), you can have multiple recaptchas on one page.
There is no need to clone the recaptcha nor try to workaround the problem. You just have to put multiple div elements for the recaptchas and render the recaptchas inside them explicitly.
This is easy with the google recaptcha api:
https://developers.google.com/recaptcha/docs/display#explicit_render
Here is the example html code:
<form>
<h1>Form 1</h1>
<div><input type="text" name="field1" placeholder="field1"></div>
<div><input type="text" name="field2" placeholder="field2"></div>
<div id="RecaptchaField1"></div>
<div><input type="submit"></div>
</form>
<form>
<h1>Form 2</h1>
<div><input type="text" name="field3" placeholder="field3"></div>
<div><input type="text" name="field4" placeholder="field4"></div>
<div id="RecaptchaField2"></div>
<div><input type="submit"></div>
</form>
In your javascript code, you have to define a callback function for recaptcha:
<script type="text/javascript">
var CaptchaCallback = function() {
grecaptcha.render('RecaptchaField1', {'sitekey' : '6Lc_your_site_key'});
grecaptcha.render('RecaptchaField2', {'sitekey' : '6Lc_your_site_key'});
};
</script>
After this, your recaptcha script url should look like this:
<script src="https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&render=explicit" async defer></script>
Or instead of giving IDs to your recaptcha fields, you can give a class name and loop these elements with your class selector and call .render()
Simple and straightforward:
1) Create your recaptcha fields normally with this:
<div class="g-recaptcha" data-sitekey="YOUR_KEY_HERE"></div>
2) Load the script with this:
<script src="https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&render=explicit" async defer></script>
3) Now call this to iterate over the fields and create the recaptchas:
<script type="text/javascript">
var CaptchaCallback = function() {
jQuery('.g-recaptcha').each(function(index, el) {
grecaptcha.render(el, {
'sitekey' : jQuery(el).attr('data-sitekey')
,'theme' : jQuery(el).attr('data-theme')
,'size' : jQuery(el).attr('data-size')
,'tabindex' : jQuery(el).attr('data-tabindex')
,'callback' : jQuery(el).attr('data-callback')
,'expired-callback' : jQuery(el).attr('data-expired-callback')
,'error-callback' : jQuery(el).attr('data-error-callback')
});
});
};
</script>
A similar question was asked about doing this on an ASP page (link) and the consensus over there was that it was not possible to do with recaptcha. It seems that multiple forms on a single page must share the captcha, unless you're willing to use a different captcha. If you are not locked into recaptcha a good library to take a look at is the Zend Frameworks Zend_Captcha component (link). It contains a few
This answer is an extension to @raphadko's answer.
If you need to extract manually the captcha code (like in ajax requests) you have to call:
grecaptcha.getResponse(widget_id)
But how can you retrieve the widget id parameter?
I use this definition of CaptchaCallback to store the widget id of each g-recaptcha box (as an HTML data attribute):
var CaptchaCallback = function() {
jQuery('.g-recaptcha').each(function(index, el) {
var widgetId = grecaptcha.render(el, {'sitekey' : 'your code'});
jQuery(this).attr('data-widget-id', widgetId);
});
};
Then I can call:
grecaptcha.getResponse(jQuery('#your_recaptcha_box_id').attr('data-widget-id'));
to extract the code.