Несколько форм с reCAPTCHA на одной странице
Установить несколько форм с reCAPTCHA на одной странице, при условии, что данные с форм отправляются обычным сабмитом, не составляет труда. Ведь при обычной отправке страница перезагружается и все reCaptcha обновляются вместе со страницей. Но как быть, если отправка данных осуществляется с помощью ajax? Решение есть и оно довольно простое.
Если вы уже установили reCaptcha на свой сайт, по инструкции изложенной в этой статье и внесли правки в сниппет, о которых написано здесь, то вам осталось сделать совсем немного.
Как отправлять и обрабатывать ajax данные с форм решать вам. Самый популярный способ описан здесь и мы его тоже используем.
Теперь начнем:
Во первых, нужно закрыть комментарием вызов javascript reCAPTCHA в нашем сниппете и вызывать его в шаблоне страницы, потому, что если форм несколько, то каждая из них будет добавлять этот вызов в HEAD страницы.
Во вторых, если форм больше одной, то потребуется обработать каждую reCAPTCHA по отдельности, для чего нам понадобятся две небольших JavaScript функции. Подробнее об этом читайте у разработчиков Google reCAPTCHA.
Итак, закрываем в сниппете комментарием эту строку:
//$script = '<script src="https://www.google.com/recaptcha/api.js?hl='.$lang.'"></script>';
В HEAD страницы сайта ставим вызов javascript reCAPTCHA:
<script src="https://www.google.com/recaptcha/api.js?onload=onReCaptchaLoad&render=explicit" async defer></script>
Как вы заметили, после загрузки он обращается к функции onReCaptchaLoad, которую мы пропишем в самом низу страницы (можно вынести в отдельный файл со скриптами). Функция нужна для первоначального рендеринга виджетов reCAPTCHA.
Вот эта функция:
var onReCaptchaLoad = function() {
var reCaptcha;
var recaptchas = document.querySelectorAll('div[data-sitekey]');
for (i = 0; i < recaptchas.length; i++) {
reCaptcha = grecaptcha.render(recaptchas[i].id, {
'sitekey' : recaptchas[i].dataset.sitekey,
});
}
};
Еще нам понадобится функция для сброса reCAPTCHA:
function recaptchaReload(id){
var _recaptcha = document.getElementById(id).getElementsByTagName('form')[0].getElementsByClassName('g-recaptcha')[0];
var _recaptcha_id = _recaptcha.getAttribute('id');
var _sitekey = _recaptcha.getAttribute('data-sitekey');
grecaptcha.render( _recaptcha, { sitekey : _sitekey } );
}
И, наконец, в функцию получения ajax ответа из упомянутой статьи нужно добавить вызов функции recaptchaReload с ID блока содержащего форму:
success: function(data)
{
...some code...
recaptchaReload('ajaxForm-1');
}
Не так уж и сложно.
Вы могли заметить, что в функции recaptchaReload используется не grecaptcha.reset, а grecaptcha.render.
Это вызвано тем, что у виджета reCAPTCHA в нашей форме, ID устанавливается динамически скриптом и меняется при получении ajax ответа.