using foundation 5 joyride with tabs - zurb-joyride

Is there a way to switch tabs with foundation 5 Joyride?
I have foundation tabs on the page and want Joyride to point elements on different tabs.

Like mentioned in the comment from Steven, you could use the callback either in the pre or post step callback function you activate the tab you need.
post_step_callback : function (){}, // A method to call after each step
pre_step_callback : function (){} // A method to call before each step
Hope this helps...

Here's what worked for me. I looked around and couldn't find anything useful, so wrote this. The hardest part was figuring out how to get the id of the target anchor. This was found buried in the 'this' object available to the callback.
$(this.$target)[0].id;
The 'content' class is used by foundation to identify the content to display when a tab is clicked. So traversing up the .parents tree finding the enclosing elements gives you the content tab(s) holding your link. And then of course you have to add an id to the <a> element of the tab you want to click. If you name it the same as your content div, with '-a' appended, you should be good to go.
html:
<dl class="tabs radius" data-tab id="my_tabs">
<dd class="active">Tab 1</dd>
<dd class="active">Tab 2</dd>
</dl>
<div class="tabs-content">
<div class="content" id="tab1">
<article id="joyride_stop1">...</article>
</div>
<div class="content" id="tab2">
<article id="joyride_stop2">...</article>
</div>
</div>
js:
$(document).ready(function() {
$(document).foundation('joyride', 'start', {
pre_step_callback: function(i, tip) {
var target = $(this.$target)[0].id;
if($('#' + target).parents('.content').length > 0) {
$('#' + target).parents('.content').each(function() {
var id = $(this).attr('id');
if($('#' + id).is(':visible') == false) {
$('#' + id + '-a').click();
}
});
}
}
});
});
This will work on any page, whether it contains tabs or not, so it can be universally included across a site.

Related

Prototype.js: Showing the next hidden div

How do I show a hidden adjacent div on Prototype.js? Here is my current code:
<button id="checkAnswer" onclick="checkAnswer2()">Check Answer</button>
<p class="feedback">Feedback:</p>
Script:
function checkAnswer2 () {
$('checkAnswer').next().show();
}
If you put the ID in the function, you’re going to have to make a new function for each question/answer pair. How about this:
<button class=“checkAnswer”>Check Answer</button>
<p class=“feedback”>Feedback:</p>
script
$$('.feedback').invoke('hide');
$(document).on('click', '.checkAnswer', function(evt, elm){
elm.next('p').show();
});
Now you can repeat as many of these as you want on the page, and each button will always manage whatever p follows it.

Infinite Scroll on ajax loaded content

I'm doing a WP_Query on let's say page-a.php, that page has a div called target where page-b.php is being loaded into. Page-a is a custom template and page-b is an archive page.
The structure on page A as example:
<body>
<div id="wrap">
<div class="target">
while
<div class="post">
<h1>Title</h1>
<p>Description</p>
</div>
endwhile
<div class="pagination"></div>
</div>
</div>
</body>
On page-b I only include the < post > and < pagination > divs within a regular wp loop.
Now the jQuery:
$(window).load(function() {
$('.target').infinitescroll({
navSelector : ".navigation",
// selector for the paged navigation (it will be hidden)
nextSelector : ".navigation a.next",
// selector for the NEXT link (to page 2)
itemSelector : ".post",
// selector for all items you'll retrieve
debug : true,
loading: {
finishedMsg: '<div class="alert alert-info" style="margin-top:50px"><p class="center">All posts were loaded</p></div>',
img: '',
msg: null,
msgText: "<p style='text-align:center; margin-top:50px;'><i style='font-size:60px; color:#babfc8'class='fa fa-cog fa-spin'></i></p>"
}
}, function(arrayOfNewElems){
$('.post').animate({"opacity":"1","max-height":"150px","padding":"15px 8px"},800, "jswing");
}
);
});
-If I call that script on page-a.php will only work on it, once page-b content is placed on
-If I call on page-a.php and page-b.php it works on first, then when first ajax content is loaded and then (if I apply a new filter) it won't work.
-If I call the script on my ajax response function it will work once, then if I apply another filter and target div refreshes content, I get the
Uncaught TypeError: Cannot call method 'appendTo' of null
div classes called (.target and .post) are present on the page.
What the hell am I doing wrong here. Thanks.
PS: If you need to take a look at the real scripts let me know and I will provide.
I think you need this : http://www.247techblog.com/implement-infinite-scroll-functionality-wordpress-wp-ajax-function/
Just need to call a wp ajax function

CodeIgniter & script.aculo.us InPlaceEdit produces duplicates on update

I'm working on a CI project and implemented scriptaculous InPlaceEdit. It works, but behaves strangly when and after updating a value.
1) When I click to edit, even though the field is just one word and should be 1 line, it produces a text area with 3 cols and 50 rows. It seems the script added empty space before the original value.
2) I save the new value and want to re-edit it, it gives me twice the form. after that 4x and so on...
HTML
So when the site is rendered, the line looks like this:
<h2 id="case_title-editme-27" class="editable savetitle" onclick="EditInput('case_title','27', 'cases');"> One line </h2>
Clicking to edit in place procudes:
<form id="case_title-editme-27-inplaceeditor" class="input-edit">
<textarea class="editor_field" rows="3" cols="40" name="value"></textarea>
<br>
<input class="editor_ok_button" type="submit" value="Save">
<a class="editor_cancel_link editor_cancel" href="#">cancel</a>
</form>
<h2 id="case_title-editme-27" class="editable savetitle" onclick="EditInput('case_title','27', 'cases');" title="Click to edit" style="display: none;"> One line </h2>
Here's my JS:
function EditInput(field, id, table) {
var id = id;
var table = table;
var field = field;
new Ajax.InPlaceEditor(
field+'-editme-'+id,
'<?PHP echo base_url();?>saveajax/'+id, {
okText: 'Save',
formClassName: 'input-edit',
callback: function(form, value) { return 'table=' + table + '&field=' + field + '&value=' + escape(value) },
}
);
}
And the PHP view
<?php foreach($caseheadlines as $headline):?>
<h2 class="editable savetitle" id="case_title-editme-<?php echo $headline['case_id']; ?>" onclick="EditInput('case_title','<?PHP echo $headline['case_id']; ?>', 'cases');">
<?php echo $headline['case_title']; ?>
</h2>
<?php endforeach;?>
So when clicking on the div, the js function get's fired and everything works expect the problems above. controller and models are fine, data get's saved to the DB.
Anyone has any idea?
The javascript you have provided is creating multiple inplace editors. I would change it like this.
for all the fields that you want to have editable add a specific class to those fields. I see you already have the editable class on the <h2> above - lets use that.
When the DOM is loaded trigger all those elements with that class to be inplace editors like this
document.observe("dom:loaded",function(){
$$('.editable').each(function(element){
new Ajax.InPlaceEditor(element,
'<?PHP echo base_url();?>saveajax/'+id, {
rows : 1,
cols : 15,
okText: 'Save',
formClassName: 'input-edit',
callback: function(form, value) { return 'table=' + table + '&field=' + field + '&value=' + escape(value) },
}
);
});
});
Now there will only be 1 instance of the inplace editor for each field. The inplace editor handles the on click turn into an editable field part.
as far as the row and cols problem if you set the rows and cols options in the instance for exactly what you want that should help - I've added them to my example

Why does my cycle slideshow hide all the slides?

The jQuery plugin cycle looks for elements of class slideshow. I want to add this class to a <ul> element to make a slideshow out of its <li>s. But when I add the slideshow class to the <ul> element, all <li> disappear and I get no slideshow whatsoever.
The HTML looks like this:
<ul>
<li>
<h3 class="expander">...</h3>
<div class="content">
<p>...</p>
<h4>...</h4>
<ul class="slideshow">
<li>...</li>
<li>...</li>
</ul>
</div>
</li>
...
</ul>
As you see, the slideshow <ul> is included in another list. This parent list consists of headers which reveal the content of each list item on click. I am hiding all the .contents programmatically when the DOM is ready. Then, I add a click listener to the .expanders so they can show the hidden .contents.
It is inside these .contentss that I have .slideshows which use the cycle plugin to cycle through their list items.
The other weird thing about all this is that the slideshow's worked perfectly before I transformed my headers into toggles for their associated content. Indeed, when I added the toggle functionality to the headers, the slides are no longer visible. But then if I take away the slideshow class, they are visible again. Of course, they no longer have slideshow functionnality...
Here is the javascript for all this:
$(document).ready(function()
{
var expanders = $('.expander');
expanders.each(function()
{
$('.content', $(this).parent()).toggle();
$(this).click(function()
{
$('.content', $(this).parent()).toggle("blind", {"easing":"easeInOutCirc"}, "normal");
});
});
$('.slideshow').each(function() {
var parent = $(this).parent();
$(this).cycle(
{
fx: 'scrollHorz',
easing: 'easeInOutCirc',
timeout: 0,
nowrap: 1
});
});
});
Any idea what could be causing this problem?
Apparently, I needed to move the cycle code above the toggle code, like this:
$(document).ready(function()
{
$('.slideshow').each(function() {
var parent = $(this).parent();
$(this).cycle(
{
fx: 'scrollHorz',
easing: 'easeInOutCirc',
timeout: 0,
nowrap: 1
});
});
var expanders = $('.expander');
expanders.each(function()
{
$('.content', $(this).parent()).toggle();
$(this).click(function()
{
$('.content', $(this).parent()).toggle("blind", {"easing":"easeInOutCirc"}, "normal");
});
});
});
I don't know why this works though, so better answers would be appreciated.

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 I 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. 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:
Create your Recaptcha fields normally with this:
<div class="g-recaptcha" data-sitekey="YOUR_KEY_HERE"></div>
Load the script with this:
<script src="https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&render=explicit" async defer></script>
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>
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.
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 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)
I know this question is old but in case if anyone will look for it in the future. It is possible to have two captcha's on one page. Pink to documentation is here: https://developers.google.com/recaptcha/docs/display
Example below is just a copy form doc and you dont have to specify different layouts.
<script type="text/javascript">
var verifyCallback = function(response) {
alert(response);
};
var widgetId1;
var widgetId2;
var onloadCallback = function() {
// Renders the HTML element with id 'example1' as a reCAPTCHA widget.
// The id of the reCAPTCHA widget is assigned to 'widgetId1'.
widgetId1 = grecaptcha.render('example1', {
'sitekey' : 'your_site_key',
'theme' : 'light'
});
widgetId2 = grecaptcha.render(document.getElementById('example2'), {
'sitekey' : 'your_site_key'
});
grecaptcha.render('example3', {
'sitekey' : 'your_site_key',
'callback' : verifyCallback,
'theme' : 'dark'
});
};
</script>
The grecaptcha.getResponse() method accepts an optional "widget_id" parameter, and defaults to the first widget created if unspecified. A widget_id is returned from the grecaptcha.render() method for each widget created, it is not related to the attribute id of the reCAPTCHA container!!
Each reCAPTCHA has its own response data.
You have to give the reCAPTCHA div an ID and pass it to the getResponse method:
e.g.
<div id="reCaptchaLogin"
class="g-recaptcha required-entry"
data-sitekey="<?php echo $this->helper('recaptcha')->getKey(); ?>"
data-theme="<?php echo($this->helper('recaptcha')->getTheme()); ?>"
style="transform:scale(0.82);-webkit-transform:scale(0.82);transform-origin:0 0;-webkit-transform-origin:0 0;">
</div>
<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>
<script src="https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&render=explicit" async defer></script>
Access response:
var reCaptchaResponse = grecaptcha.getResponse(0);
or
var reCaptchaResponse = grecaptcha.getResponse(1);
I have contact form in footer that always displays and also some pages, like Create Account, can have captcha too, so it's dynamically and I'm using next way with jQuery:
html:
<div class="g-recaptcha" id="g-recaptcha"></div>
<div class="g-recaptcha" id="g-recaptcha-footer"></div>
javascript
<script src="https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&render=explicit&hl=en"></script>
<script type="text/javascript">
var CaptchaCallback = function(){
$('.g-recaptcha').each(function(){
grecaptcha.render(this,{'sitekey' : 'your_site_key'});
})
};
</script>
This is a JQuery-free version of the answer provided by raphadko and noun.
1) Create your recaptcha fields normally with this:
<div class="g-recaptcha"></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:
var CaptchaCallback = function() {
var captchas = document.getElementsByClassName("g-recaptcha");
for(var i = 0; i < captchas.length; i++) {
grecaptcha.render(captchas[i], {'sitekey' : 'YOUR_KEY_HERE'});
}
};
Looking at the source code of the page I took the reCaptcha part and changed the code a bit. Here's the code:
HTML:
<div class="tabs">
<ul class="product-tabs">
<li id="product_tabs_new" class="active">Detailed Description</li>
<li id="product_tabs_what">Request Information</li>
<li id="product_tabs_wha">Make Offer</li>
</ul>
</div>
<div class="tab_content">
<li class="wide">
<div id="product_tabs_new_contents">
<?php $_description = $this->getProduct()->getDescription(); ?>
<?php if ($_description): ?>
<div class="std">
<h2><?php echo $this->__('Details') ?></h2>
<?php echo $this->helper('catalog/output')->productAttribute($this->getProduct(), $_description, 'description') ?>
</div>
<?php endif; ?>
</div>
</li>
<li class="wide">
<label for="recaptcha">Captcha</label>
<div id="more_info_recaptcha_box" class="input-box more_info_recaptcha_box"></div>
</li>
<li class="wide">
<label for="recaptcha">Captcha</label>
<div id="make_offer_recaptcha_box" class="input-box make_offer_recaptcha_box"></div>
</li>
</div>
jQuery:
<script type="text/javascript" src="http://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>
<script type="text/javascript">
jQuery(document).ready(function() {
var recapExist = false;
// Create our reCaptcha as needed
jQuery('#product_tabs_what').click(function() {
if(recapExist == false) {
Recaptcha.create("<?php echo $publickey; ?>", "more_info_recaptcha_box");
recapExist = "make_offer_recaptcha_box";
} else if(recapExist == 'more_info_recaptcha_box') {
Recaptcha.destroy(); // Don't really need this, but it's the proper way
Recaptcha.create("<?php echo $publickey; ?>", "more_info_recaptcha_box");
recapExist = "make_offer_recaptcha_box";
}
});
jQuery('#product_tabs_wha').click(function() {
if(recapExist == false) {
Recaptcha.create("<?php echo $publickey; ?>", "make_offer_recaptcha_box");
recapExist = "more_info_recaptcha_box";
} else if(recapExist == 'make_offer_recaptcha_box') {
Recaptcha.destroy(); // Don't really need this, but it's the proper way (I think :)
Recaptcha.create("<?php echo $publickey; ?>", "make_offer_recaptcha_box");
recapExist = "more_info_recaptcha_box";
}
});
});
</script>
I am using here simple javascript tab functionality. So, didn't included that code.
When user would click on "Request Information" (#product_tabs_what) then JS will check if recapExist is false or has some value. If it has a value then this will call Recaptcha.destroy(); to destroy the old loaded reCaptcha and will recreate it for this tab. Otherwise this will just create a reCaptcha and will place into the #more_info_recaptcha_box div. Same as for "Make Offer" #product_tabs_wha tab.
var ReCaptchaCallback = function() {
$('.g-recaptcha').each(function(){
var el = $(this);
grecaptcha.render(el.get(0), {'sitekey' : el.data("sitekey")});
});
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.google.com/recaptcha/api.js?onload=ReCaptchaCallback&render=explicit" async defer></script>
ReCaptcha 1
<div class="g-recaptcha" data-sitekey="6Lc8WQcUAAAAABQKSITdXbc6p9HISCQhZIJwm2Zw"></div>
ReCaptcha 2
<div class="g-recaptcha" data-sitekey="6Lc8WQcUAAAAABQKSITdXbc6p9HISCQhZIJwm2Zw"></div>
ReCaptcha 3
<div class="g-recaptcha" data-sitekey="6Lc8WQcUAAAAABQKSITdXbc6p9HISCQhZIJwm2Zw"></div>
To add a bit to raphadko's answer: since you have multiple captchas (on one page), you can't use the (universal) g-recaptcha-response POST parameter (because it holds only one captcha's response). Instead, you should use grecaptcha.getResponse(opt_widget_id) call for each captcha. Here's my code (provided each captcha is inside its form):
HTML:
<form ... />
<div id="RecaptchaField1"></div>
<div class="field">
<input type="hidden" name="grecaptcha" id="grecaptcha" />
</div>
</form>
and
<script src="https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&render=explicit" async defer></script>
JavaScript:
var CaptchaCallback = function(){
var widgetId;
$('[id^=RecaptchaField]').each(function(index, el) {
widgetId = grecaptcha.render(el.id, {'sitekey' : 'your_site_key'});
$(el).closest("form").submit(function( event ) {
this.grecaptcha.value = "{\"" + index + "\" => \"" + grecaptcha.getResponse(widgetId) + "\"}"
});
});
};
Notice that I apply the event delegation (see refresh DOM after append element ) to all the dynamically modified elements. This binds every individual captha's response to its form submit event.
A good option is to generate a recaptcha input for each form on the fly (I've done it with two but you could probably do three or more forms). I'm using jQuery, jQuery validation, and jQuery form plugin to post the form via AJAX, along with the Recaptcha AJAX API -
https://developers.google.com/recaptcha/docs/display#recaptcha_methods
When the user submits one of the forms:
intercept the submission - I used jQuery Form Plugin's beforeSubmit property
destroy any existing recaptcha inputs on the page - I used jQuery's $.empty() method and Recaptcha.destroy()
call Recaptcha.create() to create a recaptcha field for the specific form
return false.
Then, they can fill out the recaptcha and re-submit the form. If they decide to submit a different form instead, well, your code checks for existing recaptchas so you'll only have one recaptcha on the page at a time.
Here's a solution that builds off many of the excellent answers. This option is jQuery free, and dynamic, not requiring you to specifically target elements by id.
1) Add your reCAPTCHA markup as you normally would:
<div class="g-recaptcha" data-sitekey="YOUR_KEY_HERE"></div>
2) Add the following into the document. It will work in any browser that supports the querySelectorAll API
<script src="https://www.google.com/recaptcha/api.js?onload=renderRecaptchas&render=explicit" async defer></script>
<script>
window.renderRecaptchas = function() {
var recaptchas = document.querySelectorAll('.g-recaptcha');
for (var i = 0; i < recaptchas.length; i++) {
grecaptcha.render(recaptchas[i], {
sitekey: recaptchas[i].getAttribute('data-sitekey')
});
}
}
</script>
It is possible, just overwrite the Recaptcha Ajax callbacks. Working jsfiddle: http://jsfiddle.net/Vanit/Qu6kn/
You don't even need a proxy div because with the overwrites the DOM code won't execute. Call Recaptcha.reload() whenever you want to trigger the callbacks again.
function doSomething(challenge){
$(':input[name=recaptcha_challenge_field]').val(challenge);
$('img.recaptcha').attr('src', '//www.google.com/recaptcha/api/image?c='+challenge);
}
//Called on Recaptcha.reload()
Recaptcha.finish_reload = function(challenge,b,c){
doSomething(challenge);
}
//Called on page load
Recaptcha.challenge_callback = function(){
doSomething(RecaptchaState.challenge)
}
Recaptcha.create("YOUR_PUBLIC_KEY");
Here is a nice guide for doing exactly that:
http://mycodde.blogspot.com.ar/2014/12/multiple-recaptcha-demo-same-page.html
Basically you add some parameters to the api call and manually render each recaptcha:
<script src="https://www.google.com/recaptcha/api.js?onload=myCallBack&render=explicit" async defer></script>
<script>
var recaptcha1;
var recaptcha2;
var myCallBack = function() {
//Render the recaptcha1 on the element with ID "recaptcha1"
recaptcha1 = grecaptcha.render('recaptcha1', {
'sitekey' : '6Lc_0f4SAAAAAF9ZA', //Replace this with your Site key
'theme' : 'light'
});
//Render the recaptcha2 on the element with ID "recaptcha2"
recaptcha2 = grecaptcha.render('recaptcha2', {
'sitekey' : '6Lc_0f4SAAAAAF9ZA', //Replace this with your Site key
'theme' : 'dark'
});
};
</script>
PS: The "grecaptcha.render" method receives an ID
I would use invisible recaptcha. Then on your button use a tag like " formname='yourformname' " to specify which form is to be submitted and hide a submit form input.
The advantage of this is it allows for you to keep the html5 form validation intact, one recaptcha, but multiple button interfaces. Just capture the "captcha" input value for the token key generated by recaptcha.
<script src="https://www.google.com/recaptcha/api.js" async defer ></script>
<div class="g-recaptcha" data-sitekey="yours" data-callback="onSubmit" data-size="invisible"></div>
<script>
var formanme = ''
$('button').on('click', function () { formname = '#'+$(this).attr('formname');
if ( $(formname)[0].checkValidity() == true) { grecaptcha.execute(); }
else { $(formname).find('input[type="submit"]').click() }
});
var onSubmit = function(token) {
$(formname).append("<input type='hidden' name='captcha' value='"+token+"' />");
$(formname).find('input[type="submit"]').click()
};
</script>
I find this FAR simpler and easier to manage.

Resources