Implementing the Invisible reCAPTCHA on our dynamically generated forms. Our from engine gets a field list from the database, and dynamically fills the DOM with the form fields, displays it, and handles the post. To use the Invisible reCAPTCHA:
I'm loading the google api code when my page is finished loading:
<script src="https://www.google.com/recaptcha/api.js?render=explicit" async defer></script>
Once my form is loaded from the DB, I inject the recaptcha div into my field list:
form.fields.push( { html: '<div id="g-recaptcha-div" class="g-recaptcha" data-sitekey="<my site key>" data-badge="inline" data-size="invisible"></div>',
type: 'html'
} );
Later on, I append the form to the DOM (jQuery 'appendTo'), and immediately after that, I render the reCAPTCHA:
recaptcha_id = grecaptcha.render("g-recaptcha-div",
{
'data-callback': _settings.form.submit,
'sitekey' : <my site key>
}, true
);
and the form appears, with the reCAPTCHA badge/protected by icon showing. Looking at the DOM inspector, I can the recaptcha DIV, with the 'g-recaptcha-response' textarea there, but it's invisible. As I would expect.
Then, in my submit function, after I do some form validation, I execute the recaptcha:
grecaptcha.execute(recaptcha_id);
At which point I would expect the challenge to pop up. But it doesn't. Well, it did once. And my form submits to my PHP backend, where there is a parameter for g-recaptcha-response, but it is empty. The one time that the challenge appeared, there was a value in g-recaptcha-response.
Is the challenge always supposed to appear when the execute function is called? If not, then how should we handle the empty response value?
thanks, andy
Ok, for those following along at home:
1) yes, you can specify the name of the callback function in the call to grecaptcha.render. Looking deeper, I noticed on this page (https://developers.google.com/recaptcha/docs/invisible#js_api) that I needed to specify the name of the function like so:
recaptcha_id = grecaptcha.render("g-recaptcha-div",
{
'sitekey' : <my site key>,
'callback' : <callback>
}, true
);
I was trying to use "data-callback", which is how to specify it in the HTML. Doh! And to answer my other question, once you do this correctly, the callback gets called with a token whether or not the challenge is rendered.