10
votes

I am creating a form for a website in our CMS application that uses the new invisible reCaptcha of Google.

However, I am stuck on how to use the callback of the reCaptcha?

Before the use of the captcha, the code was very simple:

HTML

<form>
    Form input fields here...
    <button id="a23k4l234lj2l-submit-button"></button>
</form>

jQuery

$('#a23k4l234lj2l-submit-button').click(function (e) {
    e.preventDefault();
    var that = $(this);
    if(Abayo.validate(that)) {
        Abayo.submit(that);
    }
})

The Abayo library has functions to validate specific forms and send the data to a script that handles the form data.

Now, I want to add the reCaptcha to the form. The documentation says the following:

1 Create a div with data-size='invisible'.

<div class="g-recaptcha"
      data-sitekey="your_site_key"
      data-callback="onSubmit"
      data-size="invisible">
</div>

2 Call grecaptcha.execute from a javascript method.

grecaptcha.execute();

This works, but the callback function of the captcha ONLY gives me a response code to check the verify the user response:

The user's response, g-recaptcha-response, will be the input for your callback function.

The response only tells me if I can send my request to the server.

What I need is the location of the submit-button, DOM element or ANY kind of identification of the button to retrieve the data from the form that MATCHES the button?

With the following code I cannot retrieve the data from the form and send it to the server?

$('#a23k4l234lj2l-submit-button').click(function (e) {
    e.preventDefault();
    grecaptcha.execute();
})

var onSubmit = function(response) {
    // var that cannot be defined, I don't have a DOM element anywhere?
    var that = ????
    if(Abayo.validate(that)) {
        Abayo.submit(that);
    }
}

Question

Is there a way to get the DOM element in the reCaptcha callback?

2
Can’t you store the element reference somewhere in your submit button click handler? So that you can read it back later in the callback function? - CBroe
Well, I could, but I don't really want to. Any stored reference, if not needed, is one too many .It is a last resort IMO. - PIDZB
Fair enough; that was rather thinking in the workaround direction anyway, if there is no possibility to handle this inside callback. - CBroe
After searching for hours for answer to this I had to give up and stored the form's ID in a global variable so I could use it in the callback. - SigmaSteve

2 Answers

10
votes

You can programmatically create your recaptcha.

First create your captcha div.

<div id="myCaptcha" />

Then render the captcha and pass in your data with token.

var that = $(this);
grecaptcha.render('myCaptcha', { 
  sitekey: 'xxx', 
  callback: function(token) {
    Abayo.submit(token, that) 
  }
});

More info here https://developers.google.com/recaptcha/docs/invisible#js_api

1
votes

Have you tried setting onSubmit function dynamically like this (keeping your div tag as is with data-callback="onSubmit"):

$('#a23k4l234lj2l-submit-button').click(function (e) {
    e.preventDefault();
    var that = $(this);
    if(Abayo.validate(that)) {
      window.onSubmit = function(){ // defining onSubmit function dynamically here
        Abayo.submit(that); // you can access `that` here
      };
      grecaptcha.execute();
    }
})

Note: I don't have a sitekey handy to verify this code. So consider this as an approach rather than working code sample.