Skip to content

Instantly share code, notes, and snippets.

@tvaliasek
Last active October 24, 2022 12:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tvaliasek/83a166e5c773cece3b5c7d49a964e030 to your computer and use it in GitHub Desktop.
Save tvaliasek/83a166e5c773cece3b5c7d49a964e030 to your computer and use it in GitHub Desktop.
AJAX invisible recaptcha for uestla/recaptchacontrol
/**
* This file is part of the ReCaptchaControl package
*
* !!! needs polyfill for FormData in IE11 and Edge !!!
* https://github.com/jimmywarting/FormData
*
* @license MIT
* @author Petr Kessler (https://kesspess.cz)
* @link https://github.com/uestla/ReCaptchaControl
*/
;
(function (window, $) {
if (!$ || typeof $.nette === 'undefined') {
console.error('nette.ajax.js library is required, please load it.');
}
var clientIDs = {};
// renders all recaptcha elements on page
var renderAll = function () {
$('.g-recaptcha').each(function () {
var el = $(this);
if (el.children().length) { // already rendered -> skip
return;
}
clientIDs[this.id] = grecaptcha.render(this, {
size: 'invisible',
badge: 'inline',
callback: function (token) {
el.closest('form').off('submit.recaptcha').trigger('submit');
}
}, true);
});
$(function () {
$('form').on('submit.recaptcha', function (event) {
event.preventDefault();
var form = $(this);
if (Nette.validateForm(this, true)) {
// execute only reCAPTCHAs in submitted form
$('.g-recaptcha', form).each(function () {
grecaptcha.execute(clientIDs[this.id]);
});
}
});
});
};
// set global onload callback (used in library loading below)
var callbackName = 'g_onRecaptchaLoad';
window[callbackName] = function () {
renderAll();
$.nette.ext('recaptcha', {
load: function () {
renderAll();
},
before: function (jqXHR, settings) {
if ((settings.hasOwnProperty('data')) && (settings.data instanceof FormData)) {
var formData = settings.data;
var formDataKeys = formData.keys();
var iterationDone = false;
var formDataKeysArray = [];
while (!iterationDone) {
try {
var keyItem = formDataKeys.next();
iterationDone = keyItem.done;
if (!iterationDone) {
formDataKeysArray.push(keyItem.value);
}
} catch (error) {
iterationDone = true
}
}
for (var index in formDataKeysArray) {
if (formDataKeysArray[index] === 'g-recaptcha-response') {
var formDataValue = formData.get(formDataKeysArray[index]);
if (formDataValue === '' || formDataValue === undefined) {
var formEl = settings.nette.form;
formEl.trigger('submit.recaptcha')
return false;
}
}
}
}
},
complete: function () {
renderAll();
}
});
};
// load official library with explicit rendering
$('<script />', {
src: 'https://www.google.com/recaptcha/api.js'
+ '?onload=' + callbackName
+ '&render=explicit'
+ '&hl=' + ($('html').attr('lang') || 'en'),
async: true,
defer: true
}).insertAfter('script:last');
})(window, window.jQuery || false);
@stolfam
Copy link

stolfam commented Oct 1, 2018

nevim zda-li jde o bug, ale při kombinaci s webpackem v4 mi to hází error:
Module build failed: Error: Unknown substitution "BODY" given
kdyby někdo věděl jak se toho zbavit, budu vděčný :) díky

@tvaliasek
Copy link
Author

Mohlo by se teď vyřešit. Fixnulo to zároveň IE 11 bug pro let a for ... of.

@tvaliasek
Copy link
Author

Další fix!! FormData nemá podporu v IE 11 a Edge. Musí se polyfillovat: https://github.com/jimmywarting/FormData

@martinjinda
Copy link

@martinknor
Copy link

Diky, kdyby nekdo chtel aby fungovalo i pro nove nactene formy napr. po nacteni snippetu, tak do $.nette.ext('recaptcha')... pridejte

init: function () {
  this.ext('snippets', true).after($.proxy(function ($el) {
	  renderAll();
  }, this));
},

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment