Множетственная ReCaptcha2 на 1 стр + Ajaxform


Добрый день! Вдохновленный заметкой и комментарием Андрея в ней, я решил немного по подробнее расписать про особенности подключения Google ReCaptcha 2 для использования в MODX Revolution c дополнением AjaxForm и FormIt.


Под катом пример с картинками.

Итак, стояла задача установить Google ReCaptcha2 в трех формах на одной странице (Лэндинг). Две из которых запрос прайса на почту и одна с просьбой перезвонить.

Работает все изначально через AjaxForm в связке с FormIt. Для этого ставим компонент recaptchav2, в настройках через системные параметры MODX задаем sitekey и secretkey, предварительно получив их тут.

Первый шаг: тут логинимся в google и задаем имя набора параметров и домен сайта где будет каптча:
Второй шаг: тут получаем заветные ключи и копируем себе, их мы и будем указывать в параметрах MODX:
Третий шаг: полученные ключи мы прописываем в соответствующих настройках MODX как показано на скриншоте.
Четвертый шаг: Необходимо поработать с кодом шаблона ресурса, на котором предполагается использовать несколько вызовов ReCaptcha2. Следующим образом. В подвал добавляем вызов апи Google и небольшой javascript который будет отвечать за рендер каптчи, т.к. штатные вызовы компонента recaptchav2 в данной ситуации не подходят, ниже код:
<script src="https://www.google.com/recaptcha/api.js?onload=MyCallBack&render=explicit" async defer></script>
        <script>
          var recaptcha1;
          var recaptcha2;
          var recaptcha3;
          var MyCallBack = function() {
            //Render the recaptcha1 on the element with ID "recaptcha1"
            recaptcha1 = grecaptcha.render('recaptcha1', {
              'sitekey' : '[[++recaptchav2.site_key]]', //Replace this with your Site key
              'theme' : 'light'
            });
            
            //Render the recaptcha2 on the element with ID "recaptcha2"
            recaptcha2 = grecaptcha.render('recaptcha2', {
              'sitekey' : '[[++recaptchav2.site_key]]', //Replace this with your Site key
              'theme' : 'dark'
            });
            //Render the recaptcha3 on the element with ID "recaptcha3"
            recaptcha3 = grecaptcha.render('recaptcha3', {
              'sitekey' : '[[++recaptchav2.site_key]]', //Replace this with your Site key
              'theme' : 'light'
            });
          };
        </script>
Небольшое пояснение:
1) к апи идет обращение с параметром MyCallBack он может быть абсолютно любым, далее по коду есть одноименная переменная которой присваивается функция.
2) в функции задаем переменную recaptcha1 и в ней одноименный параметр, это будет id div а в который будет выводится каптча, как называть — ваше дело. Делаем по аналогии для всех трех каптч.
3) далее в sitekey не забываем поставить плейсхолдер системного параметра компонента recaptchav2 и можно пожеланию выбрать тему в параметре theme светлую или темную.

Пятый шаг: Нужно привести вызов сниппета AjaxForm к следующему примерно виду:
[[!AjaxForm?
    &snippet=`FormIt`
    &form=`form.request`
    &hooks=`recaptchav2,email`
    &emailFrom=`[[++mail_smtp_user]]`
    &emailFromName=`Админ сайта`
  	&emailSubject=`Запрос прайса с сайта [[++site_url:replace=`http://== `:replace=`/== `]]`
  	&emailTo=`yourmail@domain.tld`
  	&emailTpl=`tpl.mail.price`
  	&frontend_js=`[[+assetsUrl]]js/custom.js`
    &validate=`name:required,emailclient:email:required,g-recaptcha-response:required`
    &validationErrorMessage=`В форме содержатся ошибки!`
    &successMessage=`Заявка успешно отправлена`
    &name.vTextRequired=`Пожалуйста, укажите, как к вам обращаться`
    &email.vTextRequired=`Пожалуйста, укажите свою электронную почту`
]]
В хуке обязательно указать recaptchav2
а в чанке form.request, в конце формы, перед кнопкой отправки формы добавить див для рендера каптчи:
<div class="form-item">
              <div id="recaptcha1"></div>
              <span class="error_g-recaptcha-response error"></span>
            </div>
И по аналогии в чанках других форм сделать с разницей только лишь в id diva которые мы указали в javascript коде под вызовом api google.
Ниже дива идет span для отработки ошибок ввода каптчи.

Как результат получаем вот что:

При такой конфигурации все должно работать.
17 мая 2017, 14:11    Сергей Лелеко   G+  
31    981 +13

Комментарии (14)

  1. Scorp Satex 17 мая 2017, 19:39 # +1
    Спасибо, буквально недавно столкнулся с этой задачей. Буду пробовать.
    1. Павел 23 мая 2017, 13:43 # +3
      Небольшая пометка. Чтобы высвечивалось необходимость заполнения рекапчи (проверку на галку), т.е. «Это поле обязательно для заполнения.» Нужно в вызов Ajaxform добавить:
      &validate=`g-recaptcha-response:required`
      
      1. Сергей Лелеко 24 мая 2017, 06:34 # +1
        Абсолютно верное замечание, спасибо! Я внес правку в код вызова
      2. Alex Lenk 25 мая 2017, 23:10 # 0
        Подскажите пожалуйста, от чего данная ошибка происходит? это в консоле браузера на сайте
        Uncaught Error: ReCAPTCHA placeholder element must be an element or id
            at Object.Yp [as render] (recaptcha__ru.js:470)
            at MyCallBack (common.js:25)
            at c (recaptcha__ru.js:465)
        Yp @ recaptcha__ru.js:470
        MyCallBack @ common.js:25
        c @ recaptcha__ru.js:465
        
        1. Сергей Лелеко 26 мая 2017, 07:05 # 0
          Добрый день!
          А делали точно все по этой статье? используется точно компонент recaptchav2 и хук указан от него?
          просто первую версию рекаптчи гугл вроде как вообще более не поддерживает…
          1. Alex Lenk 26 мая 2017, 07:39 # 0
            да, а можете показать чанк form.request возможно я там ошибку допустил:
            [[!AjaxForm?
                &snippet=`FormIt`
                &form=`form.callWizard`
                &hooks=`recaptchav2,email`
                &emailFrom=`[[++mail_smtp_user]]`
                &emailFromName=`Админ сайта [[++site_url:replace=`http://== `:replace=`/== `]]`
              	&emailSubject=`Вызов замерщика с сайта [[++site_url:replace=`http://== `:replace=`/== `]]`
              	&emailTo=`artlenk.ru@gmail.com`
              	&emailTpl=`tpl.callWizard`
                &validate=`name:required,phone:required,g-recaptcha-response:required`
                &validationErrorMessage=`В форме содержатся ошибки!`
                &successMessage=`Заявка успешно отправлена`
                &successMessage=`<h3>Ваше заявка отправлена</h3><p style="width: 319px;">Наши специалисты свяжутся с вами в ближайшее время.</p>
            
            `
                &name.vTextRequired=`Пожалуйста, укажите, как к вам обращаться`
                &phone.vTextRequired=`Пожалуйста, укажите свой номер телефона`
            ]]
            
            1. Сергей Лелеко 26 мая 2017, 07:44 # 0
              да, у меня он такой:
              <form action="" method="post" class="ajax_form form text-top">
               <div class="fields incon">
                  <div class="incon" style="width: auto;">
                     <div class="field" data-type="name">
                        <div class="name">
                           <div class="">Имя</div>
                        </div>
                        <div class="input"> <input type="text" name="name" class="form-control" style="border-radius: 4px;"> <span class="error_name"></span>  </div>
                     </div>
                  </div>
                  <div class="incon" style="width: auto;">
                     <div class="field" data-type="phone">
                        <div class="name">
                           <div class=""> E-mail<span class="required">*</span> </div>
                        </div>
                        <div class="input"> <input type="text" name="emailclient" class="form-control" style="border-radius: 4px;"> <span class="error_email"></span> </div>
                     </div>
                  </div>
                  <div class="incon">
                          <div class="form-item">
                            <div id="recaptcha1"></div>
                            <span class="error_g-recaptcha-response error"></span>
                          </div>
                  </div>
               </div>
               <div class="macros-button">
                  <div class="btnwrap">
                     <div class="incon"> <input data-action="" type="submit" class="btn"> </div>
                  </div>
               </div>
              </form>
              1. Сергей Лелеко 26 мая 2017, 07:45 # 0
                smtp у вас точно настроен в системных параметрах?
                1. Alex Lenk 26 мая 2017, 14:12 # 0
                  нет, у меня там ничего не прописано было. Я убрать пару строк и все заработало
                  	&emailFrom=`[[++mail_smtp_user]]`
                  	&emailFromName=`Админ сайта`
                  	&frontend_js=`[[+assetsUrl]]js/custom.js`
                  
                  1. Сергей Лелеко 26 мая 2017, 19:39 # 0
                    &frontend_js=`[[+assetsUrl]]js/custom.js`
                    еще этого файла у вас конечно же нету, прописывая этот параметр подразумевал модифицированный стандартный js Ajaxform а
          2. Константин Ильин 08 июня 2017, 17:33 # +3
            Немного проще делается с капчей, ведь реально неудобно когда много форм и каждую надо в переменную забивать — это неудобно. Лучше использовать each для прохода.

            Скрипты
            <script src="https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&render=explicit" async defer></script>
            <script>
            var CaptchaCallback = function() {
                $('.g-recaptcha').each(function(index, el) {
                    grecaptcha.render(el, {'sitekey' : '[[++recaptchav2.site_key]]'});
                });
            };
            </script>
            
            Разметка в любой форме одинаковая
            <form>
            .....
             <div class="g-recaptcha" data-sitekey="[[++recaptchav2.site_key]]"></div>
            .....
            </form>
            
            1. Сергей Лелеко 08 июня 2017, 21:07 # 0
              Хорошее решение. Не против если его в текст статьи добавлю?

              PS видимо недостаточны мои знания JS)
              1. Константин Ильин 08 июня 2017, 22:54 # 0
                Не против конечно, все для блага разработчиков)
            2. Александр Мельник 08 июня 2017, 22:53 # 0
              Использовал такой же подход, он не единажды описан на просторах интернета.
              А вот кто-то пробовал работать с новой невидимой каптчей гугла?
              Есть опыт относительно MODX, AjaxForm и FormIt?

              Вы должны авторизоваться, чтобы оставлять комментарии.