How do I show multiple recaptchas on a single page?
Solution 1
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
Solution 2
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()
Solution 3
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>
Solution 4
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.
Solution 5
This is easily accomplished with jQuery's clone()
function.
So you must create two wrapper divs for the recaptcha. My first form's recaptcha div:
<div id="myrecap">
<?php
require_once('recaptchalib.php');
$publickey = "XXXXXXXXXXX-XXXXXXXXXXX";
echo recaptcha_get_html($publickey);
?>
</div>
The second form's div is empty (different ID). So mine is just:
<div id="myraterecap"></div>
Then the javascript is quite simple:
$(document).ready(function() {
// Duplicate our reCapcha
$('#myraterecap').html($('#myrecap').clone(true,true));
});
Probably don't need the second parameter with a true
value in clone()
, but doesn't hurt to have it... The only issue with this method is if you are submitting your form via ajax, the problem is that you have two elements that have the same name and you must me a bit more clever with the way you capture that correct element's values (the two ids for reCaptcha elements are #recaptcha_response_field
and #recaptcha_challenge_field just in case someone needs them)
Related videos on Youtube
oym
Updated on July 08, 2022Comments
-
oym almost 2 years
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?
-
oym almost 15 yearsI tried that..when I try to duplicate the captcha code it will just display the captcha that comes first
-
El Yobo about 9 yearsAnyone coming across this for the new recaptcha API, this is possible by using the explicit loading described with examples in the docs at developers.google.com/recaptcha/docs/display#recaptcha_methods
-
Edward about 8 yearsAn iframe should be possible but is a bad way of solving the problem, compared to using JavaScript like in
Hüseyin Yağlı
's answer. Most browsers should support JavaScript and the default reCAPTCHA uses JavaScript anyway. I don't know though what would need to be done to solve the problem without JavaScript support though.
-
-
Ogugua Belonwu almost 12 yearsYou will encounter issues when you request for a new challenge as it will be updating only one recaptcha instance
-
Oxi over 11 yearsthis does not work ... means only the original captcha( the first one called <div id="myrecap"> here )only will be refreshed , and other not refreshed
-
Serj Sagan over 11 yearsActually Oxi, your concern was addressed by my previous comment
-
Serj Sagan over 8 yearsYou're probably doing it wrong... how about a link to your code in jsfiddle.net Anyways, there is no longer a need to do any of this... you should be using Hüseyin Yağlı answer.
-
Ivan Juarez over 8 yearsCoincidentally, do you know how to add hidden recaptcha field for jquery validation for each field?, currently I have it working only with 1 recaptchafield but can it work with two recaptchas? <input type="hidden" class="hiddenRecaptcha required" name="hiddenRecaptcha" id="hiddenRecaptcha">
-
Hüseyin Yağlı over 8 years@IvanJuarez This is a good question to ask as a new question.
-
Gene Kelly over 8 yearsFor those of you wanting to use grecaptcha.getResponse() with multiple instances you can simply reference each render as 0,1,2,etc. For example the first instance would be referenced as grecaptcha.getResponse(0).
-
Edward about 8 yearsIt is possible with reCAPTCHA actually, just not possible to do without JavaScript. Most browsers should support JavaScript and the default ReCaptcha uses JavaScript anyway so this solution is good.
Hüseyin Yağlı
's answer explains the solution. reCAPTCHA documentation for this solution is at developers.google.com/recaptcha/docs/display#explicit_render. I don't know though what would need to be done to solve the problem without JavaScript support though. -
ryanpcmcquen almost 8 yearsExcellent answer, but your script has to use
https
, not a protocol relative link: developers.google.com/recaptcha/docs/display#auto_render -
Greg Alexander over 7 yearsThis is the right way IMO, this makes it dynamic in that I can have unlimited instances without defining static ids
-
Mirza Obaid over 7 yearsSave my time its perfect solution
-
VanDir over 7 yearsIf you need to extract manually the captcha code (like in ajax requests) look my answer.
-
Marcio Mazzucato about 7 yearsCould you please take a look in my question? The POST parameter is going empty.
-
Ray S. almost 7 yearshave a javascript only version?
-
JxAxMxIxN almost 7 yearsI used this almost exactly and in addition to 'sitekey' I also added a 'callback' like so: grecaptcha.render(el, {'sitekey' : $(this).attr('data-sitekey'), 'callback':CaptchaSubmit});
-
the_nuts almost 7 years
data-sitekey="YOUR_KEY_HERE"
is useless and can be removed from the div (if you need to change the key, less places to edit) -
Gkiokan almost 7 yearsActually you have a typo there. The Attribute data-sitekey is needen and makes this even more dynamic in case you would have multiple sitekeys, why ever. The correct line would be
grecaptcha.render(el, {'sitekey' : $(el).attr('data-sitekey') });
-
codacopia over 6 yearsWow! This took some working on, but to add to @GeneKelly's note regarding
grecaptcha.getResponse(0)
andgrecaptcha.getResponse(1)
to validate multiple instances I would add that the indexing does have to correspond with thegrecaptcha.render
ordering. For this example,grecaptcha.render('RecaptchaField1'...
would be verified withgrecaptcha.getResponse(0)
andgrecaptcha.render('RecaptchaField2'...
would be verified withgrecaptcha.getResponse(1)
, etc... -
Black over 5 yearsWow, I was searching for hours for this. Thanks!!
-
Black over 5 yearsI edited your post and implemented it fully like described in the API, I also replaced
$
withjQuery
to make it compatible with the prototype framework. -
Eugen Konkov over 5 yearsThe problem with this that when you executing
grecaptcha.execute()
the callback will be called only for firstdiv
with recaptcha despite on where you click -
masud_moni over 5 yearsworking like a charm in the frontend. but what about the server side validation?
(new GoogleRecaptchaApi)->reCaptchaValidate(request('captcha')
It is showing false -
Carlos Espinoza almost 5 yearsIt's absolutely possible with reCAPTCHA actually
-
good_afternoon over 4 yearsThis works until I make the
"size": "invisible"
. Anyone know why? -
Lucas Bustamante over 4 yearsHey, thanks for that. What is the
#your_recaptcha_box_id
? -
MeSo2 about 4 yearswhere is the 2 forms part?
-
surinder singh about 4 yearssorry not getting you
-
surinder singh about 4 yearsjust put
<div class="g-recaptcha" data-sitekey="your_site_key"></div>
where u needed , in forms/divs -
00-BBB over 3 years@masud_moni mine is added to $post as 'g-recaptcha-response'
-
kneidels over 3 yearsThis is working great for me in ajax, BUT- in a case where there is an error on the form (eg, user not found) - and a relevant error is returned from the ajax method, i ould usually resat the captcha by calling
grecaptcha.reset();
which worked great in a single-form-per-page setup. But in a multiple form per page, thisreset
command does not effect/reset the captcha. I tried calling theCaptchaCallback
function as well, but it did not solve the issue. -
kneidels over 3 yearsAnswering my comment above. See: stackoverflow.com/questions/31344626/…
-
Svetoslav Stefanov over 2 yearsWoah, thank you! Couldn't find such a thing in the official documentation. This way you could have multiple captchas, without having explicit rendering. I have a case where I have normal rendering everywhere around the site and I need explicit rendering only in one place - this solved my issue.
-
Bloggrammer over 2 yearsCan the site_key ''6Lc_your_site_key" be the same for the multiple Recaptcha?