Reputation: 103
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
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
Reputation: 55002
Is the question how to have 2 callbacks? How about: "...onload=twoCallbacks"
function twoCallbacks(...args){
callback1(...args)
callback2(...args)
}
Upvotes: 0
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