pass variables to php with ajax load() - ajax

I found some close answers for this, but none of them worked in my case. I have:
Input tag:
<input name="title" id="title">
Ajax:
<script language="javascript">
function example_ajax_request() {
$('#example-placeholder').html('<p><img src="/img/ajax-loader.gif" /></p>');
setTimeout('example_ajax_request_go()', 0);
}
function example_ajax_request_go() {
$j(document).ready(function () {
var inputField = $j('#inputText').val();
$j(".button").click(function () {
$('#example-placeholder').load('preview.php?title=' + title + ' .aClass');
}
</script>
Button to call the function:
<input type="button" onclick="example_ajax_request()" value="Preview" />
I'm trying to pass 'title' var from the input tag via ajax to 'preview.php'. This code above has errors and is not running, can you suggest correct one? Thanks!

You have not put in exact error messages (from your browser's console, please put them in and update your question). I am just putting across some suggestions/improvements:
Whenever you are passing GET parameters, always URIEncode the value(the xyz and value in url?abc=xyz&blah=value). In javascript there is a function call EncodeURIComponent(..). You would use it like:
'preview.php?title=' + EncodeURIComponent(title +' .aClass')
A possible typo, you have have a space in the URL, before the + ' .aClass'. If you need one, explicitly replace it with a + or %20.

Found a way. Here it is:
<script type="text/javascript">
function example_ajax_request() {
$('#example-placeholder').html('<p><img src="img/ajax-loader.gif" /></p>');
$('#example-placeholder').load("preview.php?title="+$('#title').val());
}
</script>
Thanks!

Related

Ajax html response to div

Hi I am printing the ajax html response to div element and giving radio input option to select the file. after selecting the specific file the another div should show the message. but the ajax html response is not working
Jquery script:
$(document).ready(function()
{
$('#upload').ajaxForm({
beforeSubmit: function() {
$('#Analysis').show();
$('#Content_column').hide();
$('#file_list').show();
$('#trait').show();
$('#trait').html('Submitting...');
},
success: function(data) {
var $out = $('#file_list');
$out.html('&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbspFile list:');
$out.append('<div id="list">');
$('#list').html(data);
$out.append('</div>');
}
});
});
The output of this script is
<ul class="php-file-tree"><li class="pft-directory">Genotypic<ul><input id="Penotypic" type="radio" name="uploads/Genotypic/" value="uploads/Genotypic/jquery.txt" />jquery.txt<br><input id="Penotypic" type="radio" name="uploads/Genotypic/" value="uploads/Genotypic/marker.csv" />marker.csv<br></ul></li><li class="pft-directory">Other</li><li class="pft-directory">Penotypic<ul><input id="Penotypic" type="radio" name="uploads/Penotypic/" value="uploads/Penotypic/namPheno.csv" />namPheno.csv<br><input id="Penotypic" type="radio" name="uploads/Penotypic/" value="uploads/Penotypic/perl.pl" />perl.pl<br></ul></li></ul>
Jquery script:
$('#Penotypic').click(function() {
var $out1 = $('#trait');
$('#trait').show();
$out1.append('Submitted...');
});
this is not showing anything in the div trait. may be the html response is loading as a tesxt so the #Penotypic is not recognised. please help me to fix this.
Thanku
You have many inputs of id="Penotypic". Make every id unique or use classes as function trigger.
I wouldn't use "/" in the name attribute. See: http://www.w3.org/TR/html401/types.html#type-name
Then try if your ajax script does work. If it doesn't work, try if it works from static page (don't use your first jQuery script, but it's output as a static form). You probably need to bind your event trigger. Use jQuery's on().

Strange issue with ajax POST

I have this html page with the form
<form method="post" id="form1" name="form1" action="/status_comment/save">
//Some text inputs
<input type="text" name="new_comment" id="new_comment" onkeydown="post_comment(event,'13')" >
</form>
And this is my javascript function to do the POST call
function post_comment(event,item_id)
{
var keyCode = ('which' in event) ? event.which : event.keyCode;
if(parseInt(keyCode)==13 && event.shiftKey!=1)
{
var str = $('#form1').serialize(); // Gets all the filled details
$.post('/status_comment/save',
str,
function(data){
alert(data);
});
}}
Backend is done using Django and this is the return statement
data=simplejson.dumps(data)
return HttpResponse(data, mimetype='application/json')
The referral url is say "/xyz".
The thing is, after the form gets submitted, it is being automatically redirect to the "/status_comment/save" page instead of remaining on the same page.
I tried the get method and it works fine but not the POST method.
I tried debugging it, so changed the url in post call to the referral url, then it refreshs the page instead of doing nothing.
Also the alert() command inside the function above doesnt work, so its probably not being entered into.
Interesting thing I have noticed, when looking at the web developer console, the Initiator for the POST call in this page is being displayed as "Other" while the initiator for GET call and POST call (in other pages, where its working) is "jquery-1.8.0.min.js:2"
Any thoughts? Thanks...
First you really shouldn't try to capture the enter if you can avoid it. Use the submit binding. It makes everything more obvious and easier for your fellow developers (I bet I am not the only one who thought "What the heck is KeyCode 13?").
I'm wondering if perhaps being more explicit might help. Have you tried calling preventDefault and stopImmediatePropagation?
$('#form1').submit(function(evt) {
evt.preventDefault();
evt.stopImmediatePropagation();
// serialize and be AJAXy yada yada yada
If that doesn't work, or for some reason you prefer to handle capturing enter on your own, then you might want to have the above code in addition to your keydown handler. So it would be:
<input type="text" name="new_comment" id="new_comment" onkeydown="post_comment(event,'13')" >
...
$('#form1').submit(function(event) {
event.preventDefault();
event.stopImmediatePropagation();
}
function post_comment(event,item_id)
{
event.preventDefault();
event.stopImmediatePropagation();
var keyCode = ('which' in event) ? event.which : event.keyCode;
if(parseInt(keyCode)==13 && event.shiftKey!=1)
{
var str = $('#form1').serialize(); // Gets all the filled details
$.post('/status_comment/save',
str,
function(data){
alert(data);
});
}
}
Start by getting rid of the onkeydown attribute from the input:
<form method="post" id="form1" name="form1" action="/status_comment/save">
//Some text inputs
<input type="text" name="new_comment" id="new_comment" />
</form>
And then simply subscribe to the .submit() event of this form using jquery and perform the AJAX request in there. Don't forget to return false from it to ensure that the default action is canceled and the browser stays on the same page:
$('#form1').submit(function() {
var str = $(this).serialize(); // Gets all the filled details
$.post(this.action, str, function(data) {
alert(data);
});
return false; // <!-- that's the important part
});

Google ReCaptcha without PHP plugin

I understand the cross-domain error when using ajax to try to obtain information from another website but according to jQuery you should be able to use a jsonp request instead. I am stumped on how to achieve this when trying to display recaptcha. The issue is I am unable to use the plugin to achieve this, which would make it so much easier.
<script type="text/javascript" src="http://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>
<script type="text/javascript">
function showRecaptcha() {
Recaptcha.create("// removed for example", 'captchadiv', {
tabindex: 1,
theme: "red",
callback: Recaptcha.focus_response_field
});
}
jQuery(document).ready(function(){
showRecaptcha('recaptcha_div');
jQuery('#contact-form').submit(function(){
var challenge = Recaptcha.get_challenge();
var response = Recaptcha.get_response();
var ip = "<?php print $_SERVER['REMOTE_ADDR'] ?>";
var private = "// removed for example";
var requestUrl = "http://www.google.com/recaptcha/api/verify?privatekey=" + private + "&remoteip=" + ip + "&challenge=" + challenge + "&response=" + response;
jQuery.getJSON(requestUrl, function(json) {
alert("what");
});
})
});
</script>
<form id="">
// Form stuff
</form>
<div id="captchadiv"></div>
<input type="submit" name="submit" id="form-submit">
How should I call this to googles server and obtain the correct callback. It's basically going to return a true or false. I either get the infamous Access-Control-Allow-Login or or an error regarding plain/text. Anyone with suggestions?
1) Google does not support JSONP output. Why? Go to 2).
2) reCAPTCHA is meant to be validated on server side code. Why? Go to 3).
3) Spammers can easily bypass your client side validation code, thus rendering any CAPTCHA solution pointless.
You can try this way, Invisible reCAPTCHA
https://developers.google.com/recaptcha/docs/invisible

Jquery and scope issues with $.post

I am having one small problem with my code. I am sending a POST request to my page, after I am done it should return "OK" meaning it worked. From inside my handler function I call set_var(data) to set my global variables text, but the problem is my print_info() returns undefined.
I've spent a lot of time on this and realize my problem has to do with scoping somehow but I am not sure how to go about fixing it. If anyone can provide any pointers, that would be great.
<?
if($_REQUEST['action'] == 'test')
{
echo "OK";
die;
}
?>
<script type="text/javascript" src="jquery-1.6.1.js" ></script>
<script type="text/javascript">
var ajax_post_result;
function set_var(data)
{
//PRINTS MY TEXT OK
alert("SET:: " + data);
//SET TO MY GLOBAL VARIABLE
ajax_post_result = data;
//ALSO PRINTS OK
alert("SET2:: " + ajax_post_result);
}
function return_handler(data, textStatus)
{
//THESE BOTH WORK ... BUT ONLY HERE AND WITHIN set_var()
//alert("1: " + data); //PRINTS WHAT I NEED
//CALL FUNCTION TO SET GLOBAL VARIABLE
set_var(data);
}
function print_info()
{
return ajax_post_result;
}
function ajax_post(file, data )
{
$.post( file, data, return_handler);
//PRINTS UNDEFINED
alert("RETURN:: " + print_info() );
}
</script>
<form id=newform name='testform'>
<input type="hidden" name="newexample" value="1">
Enter Something: <input name="something" id='something1' value="" type="text">
<input type="button" value="Submit" name="Submit" onclick="ajax_post('index.php?action=test', $('#newform').serialize() ); return false;">
</form>
AJAX requests are, as evidenced by the first A in the acronym, asynchronous. So, when you call $.post(), execution of the ajax_post function continues on its merry way more or less immediately, without waiting for the request to finish. You get to your "RETURN" alert before your return_handler has run to set the global variable.
You can use jQuery.ajax and set the async option to false, which will get you a synchronous request.
Or, and I recommend this strategy, move all the things that need to happen only after the request is done to the success handler.
Your problem is due to the asynchronous nature of AJAX.
You should do all your post AJAX processing in the callback function. Something like this (using your current functions)
$.post(file, data, function(data, textstatus) {
return_handler(data, textstatus);
alert("RETURN:: " + print_info());
});
Though you could easily combine your functions into the one closure (minus the alerts), eg
$.post(file, data, function(data, textstatus) {
ajax_post_result = data;
});

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