idecchi
idecchi

Reputation: 103

Getting widgetId from reCAPTCHA v2 from g-recaptcha tag?

Hi this is my first attempt posting question here.

I want to know if I can ever get widgetId from the g-recaptcha tag and not from the returning value of grecaptcha.render() of reCAPTCHA v2.

The reason behind this is that I have 2 different scripts that handles each 2 forms on a same page. I want to be able to reset the reCAPTCHA individually.

Each scripts have thier own onload callback that supposed to get their own widgetId. But this does not work because it seems there is only 1 onload callback functions can be called by the url parameter of the google reCAPTCHA code.

I couldn't have multiple onload callback functions set to the recaptcha source url like below.

"https://www.google.com/recaptcha/api.js?onload=onloadCallback1,onloadCallback2&render=onload"

"https://www.google.com/recaptcha/api.js?onload[]=onloadCallback1&onload[]=onloadCallback2&render=onload"

So I thought maybe I can get the widget Id from the g-recaptcha tag after loaded...

Any idea or solution???

Upvotes: 3

Views: 3964

Answers (3)

Phil
Phil

Reputation: 1061

Another approach to this is to use explicit rendering and add the widget Id to the container as a data attribute which can then be retrieved elsewhere, such as if you need to reset the captcha widget manually

<script src="https://www.google.com/recaptcha/api.js?onload=recaptchaLoaded&render=explicit"></script>

<script>
    function recaptchaLoaded() {
    
        document.querySelectorAll('.g-recaptcha').forEach((el, i) => {
            var widgetId = grecaptcha.render(el);
            el.setAttribute('data-grecaptcha-id', widgetId);
        });
    
    }

    document.getElementById("mybutton").addEventListener("click", (event) => {
        var widgetId = document.getElementById("mycaptcha").getAttribute('data-grecaptcha-id');
        grecaptcha.reset(widgetId);
    });

</script>

Note that the script URL must include render=explicit and the name of your onload callback method

Upvotes: 0

pguardiario
pguardiario

Reputation: 55002

Is the question how to have 2 callbacks? How about: "...onload=twoCallbacks"

function twoCallbacks(...args){
  callback1(...args)
  callback2(...args)
}

Upvotes: 0

idecchi
idecchi

Reputation: 103

Hmmm,,, it's not sophisticated but I came up with an idea of getting the widget id based on the order of g-recapctha class. The function accpets an id of the target recaptcha box as an argument and returns the index of the g-recaptcha class that is associated with.

// recaptha box 1
<div id="recaptchaBox-1" class="g-recaptcha" data-sitekey="xxx"></div>
<input id="resetBtn1" type="button" value="Reset1">

// recaptha box 2    
<div id="recaptchaBox-2" class="g-recaptcha" data-sitekey="xxx"></div>
<input id="resetBtn2" type="button" value="Reset2">

/**
 * Returns widgetId from a given element id
 * @param {string} elementId 
 * @return {number} i
 */
function getWidgetId(elementId) {
  const recaptchaBoxes = document.querySelectorAll('.g-recaptcha');
  const targetBox = document.querySelector(`#${elementId}`);
  for (let i = 0; i < recaptchaBoxes.length; i++) {
    if (recaptchaBoxes[i].id === targetBox.id) {
      return i;
    }
  }
}

// Get the widgetId for each boxes.
const widgetId1 = getWidgetId('recaptchaBox-1');
const widgetId2 = getWidgetId('recaptchaBox-2');

// Assign grecaptcha.reset() for each buttons on click event.
document.getElementById('resetBtn-1').addEventListener('click', () => grecaptcha.reset(widgetId1));
document.getElementById('resetBtn-2').addEventListener('click', () => grecaptcha.reset(widgetId2));

Upvotes: 7

Related Questions