I trying to implement Recaptcha V2 on an angular site.
I'm using angular translate and I don't know how to regenerate the reCaptcha object with the correct language provided from the $scope
There is any method ? or process to reload the object with the correct lang ?
Thanks
Based on the limitation of the API you can load the script dynamically:
Function to load script
(source)
function loadScript(url, callback)
{
// Adding the script tag to the head as suggested before
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
// Then bind the event to the callback function.
// There are several events for cross browser compatibility.
script.onreadystatechange = callback;
script.onload = callback;
// Fire the loading
head.appendChild(script);
//modification so we can remove this after
return script;
}
Note: this is a regular JS function
Load script dynamically
in your Angular controller
$scope.loadGoogleRecaptcha = function (id, lang) {
/// using timeout not to use $apply
$timeout(function () {
//set default value
var elemntID = id || false;
var language = lang || 'en';
if (!elemntID) {
console.warn('NO Id selected for re-captcha loading!')
return false;
}
var element = document.getElementById(elemntID)
if (angular.element(element).length == 0) {
console.warn('provided id doesn\'t exist ', elemntID);
return false;
}
//Delete oldscript
if ($rootScope.addedScript)
angular.element($rootScope.addedScript).remove();
//clear current recaptcha container
angular.element(element).empty();
var url = "https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit&hl=" + lang;
return $window.loadScript(url, function () {
console.log('Scipt loaded:', url);
})
});
}
init captcha with current language using angular-translate-localStorage
$rootScope.addedScript = $scope.loadGoogleRecaptcha('g-recaptcha-register' ,$window.localStorage.getItem( 'NG_TRANSLATE_LANG_KEY'));
sample of function to switch language
$rootScope.changeLanguage = function (langKey) {
$translate.use(langKey);
$rootScope.selectedLanguage = langKey;
$scope.loadGoogleRecaptcha('g-recaptcha-register' , langKey);
};
Or you could use a watcher
$scope.$watch(
'selectedLanguage', function (n, o) {
//putting if to prevent double fetch the first time
if (!!n && n != o){
$rootScope.addedScript = $scope.loadGoogleRecaptcha('g-recaptcha-register', n);
}
}
);
Changing the recapacha src with the right hl attribute worked for me
Heres my solution using JQuery
// reload capcha on translation
$rootScope.$on('$translateChangeSuccess', (event, data) => {
// reload captcha
let language;
if (data.language === 'en_CA') {
language = 'en';
} else {
language = 'fr';
}
const captchaElm = angular.element(document).find('.vc-recaptcha').find('iframe');
if (captchaElm.length) {
let src = captchaElm.attr('src');
src = src.replace(/(hl=)[^\&]+/, `$1${language}`);
captchaElm.attr('src', src);
}
});