recaptcha - Установка

Статья, в которой рассмотрим, как подключить recaptcha к форме обратной связи, работающей по технологии ajax.


reCAPTCHA - это бесплатная служба google, которая позволяет защитить ваш сайт от спама.

Сайт Google reCAPTCHA
Сайт Google reCAPTCHA

Процесс установки google recaptcha v2 состоит из 3 шагов:

  1. Получить API-ключи (site key и secret) для Вашего сайта;
  2. Подключить виджет гугл капчи к HTML странице, и обеспечить посредством технологии AJAX передачу его ответа сервер;
  3. Добавить в серверный сценарий php проверку ответа google recaptcha.

reCAPTCHA - Регистрация и получение ключей

Работа с google recaptcha 2 начинается с регистрации сайта на https://www.google.com/recaptcha и получения пары ключей.

Более детально данный процесс можно представить с помощью следующих этапов:

  1. Открытия страницы https://www.google.com/recaptcha.
  2. Нажатия на кнопку "Get reCAPTCHA" (получить рекапчу). Если Вы не имеете учётную запись Google, то дополнительно необходимо будет ещё пройти процедуру регистрации на этом сайте чтобы получить её.
  3. Ввода название сайта (например, Мой сайт) и домена (например, mysite.ru) в соответствующие поля формы "Регистрация сайта".
  4. Нажатия на кнопку "Регистрация" и получения 2 ключей. Один из ключей является публичным. Данный ключ указывается в HTML-коде сайта и предназначен для отображения виджета recaptcha. Второй ключ является секретным. Он предназначен для установления связи северного скрипта сайта с сервисом reCAPTCHA для проверки ответа пользователя.
Публичный и секретный ключи reCaptcha для сайта
Публичный и секретный ключи reCaptcha

Установка recaptcha на сайт

Подключение reCAPTCHA к сайту (странице) осуществляется как на стороне клиента (в HTML), так на стороне сервера (в PHP).

Разберём, как это осуществляется более подробно. В качестве примере выберем ajax форму обратной связи.

Подключение recaptcha к HTML-документу

Подключение виджета reCAPTCHA к странице осуществляется посредством выполнения 2 действий:

  1. Включения в страницу JavaScript скрипта recaptcha.
  2. Добавление элемента div с классом "g-recaptcha" и атрибутом data-sitekey, имеющий в качестве значения ваш публичный ключ (public key) капчи.

Кроме этого, добавим на страницу ещё элемент div с идентификатором id="recaptchaError". Данный элемент будем использовать для отображения ошибки, связанной с google racaptcha.

<!-- добавление элемента div -->
<div class="g-recaptcha" data-sitekey="6KepjAsTFFFFFFMqccY0ZiGqc3TEd3YVxo8cHsGX"></div>

<!-- элемент для вывода ошибок -->
<div class="text-danger" id="recaptchaError"></div>

<!-- js-скрипт гугл капчи -->
<script src='https://www.google.com/recaptcha/api.js'></script>

Кроме этого необходимо будет внести ещё изменения в файл script.js, т.к. форма обратной связи отправляется на сервер через AJAX.

// Работа с виджетом recaptcha
// 1. Получить ответ гугл капчи
var captcha = grecaptcha.getResponse();

// 2. Если ответ пустой, то выводим сообщение о том, что пользователь не прошёл тест.
// Такую форму не будем отправлять на сервер.
if (!captcha.length) {
  // Выводим сообщение об ошибке
  $('#recaptchaError').text('* Вы не прошли проверку "Я не робот"');
} else {
  // получаем элемент, содержащий капчу
  $('#recaptchaError').text('');
}

// 3. Если форма валидна и длина капчи не равно пустой строке, то отправляем форму на сервер (AJAX)
if ((formValid) && (captcha.length)) {
  ...
  // добавить в formData значение 'g-recaptcha-response'=значение_recaptcha
  formData.append('g-recaptcha-response', captcha);
  ...
}  
  
// 4. Если сервер вернул ответ error, то делаем следующее...
// Сбрасываем виджет reCaptcha
grecaptcha.reset();
// Если существует свойство msg у объекта $data, то...
if ($data.msg) {
  // вывести её в элемент у которого id=recaptchaError
  $('#recaptchaError').text($data.msg);
}

Интегрирование recaptcha в php скрипт

Установка recaptcha в скрипт php осуществляется посредством внесения в файл process.php следующих изменений:

  • создание переменной $secret, содержащей секретный ключ вашего сайта;
  • подключения клиентской библиотеки reCAPTCHA PHP посредством включения в скрипт файла autoload.php;
  • проверка наличия ключа g-recaptcha-response в суперглобальном массиве POST;
  • если данное имя (g-recaptcha-response) есть, то создать экземпляр службы recaptcha, используя ваш секретный ключ;
  • получить результат проверки кода: если результат положительный, то выполнить необходимые действия (например, отправить информацию на почту).
  • если возникла ошибка, то отправить клиенту отрицательный результат.
// ваш секретный ключ
$secret = '6NepjAsGBBABBN7_Qy9yfzShcKmc70X2kXQyX1WO';
// однократное включение файла autoload.php (клиентская библиотека reCAPTCHA PHP)
require_once (dirname(__FILE__).'/recaptcha/autoload.php');
// если в массиве $_POST существует ключ g-recaptcha-response, то...
if (isset($_POST['g-recaptcha-response'])) {
  // создать экземпляр службы recaptcha, используя секретный ключ
  $recaptcha = new \ReCaptcha\ReCaptcha($secret);
  // получить результат проверки кода recaptcha
  $resp = $recaptcha->verify($_POST['g-recaptcha-response'], $_SERVER['REMOTE_ADDR']);
  // если результат положительный, то...
  if ($resp->isSuccess()){
    // действия, если код captcha прошёл проверку
    //...
  } else {
    // иначе передать ошибку
    $errors = $resp->getErrorCodes();
    $data['error-captcha']=$errors;
    $data['msg']='Код капчи не прошёл проверку на сервере';
    $data['result']='error';
  }

} else {
  //ошибка, не существует ассоциативный массив $_POST["send-message"]
  $data['result']='error';
}

Готовая форма обратной связи с recaptcha

Бесплатно загрузить форму обратной связи с recaptcha можно по следующей ссылке:

Форма обратной связи с recaptcha

Изображения готовой формы, в которую интегрирована recaptcha.

Форма обратной связи с recaptcha
Форма обратной связи с recaptcha
Заполненная форма обратной связи с recaptcha
Заполненная форма обратной связи с recaptcha
Результат, который будет отображён при удачной обработке формы на сервере
Результат, который будет отображён при удачной обработке формы на сервере

Статьи, связанные с этой темой:



   PHP 0    3411 0

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

  1. Александр # 0
    Отлично, все прекрасно работает.
    Александр, подскажите, где что нужно поправить в коде js и php если нам не надо отправлять файлы, но есть еще два поля, например с телефоном и адресом сайта пользователя. Если содержимое формы выглядит так.
    HTML:
    <form id="messageForm" enctype="multipart/form-data">
      <div class="row">
        <div id="error" class="col-sm-12" style="color: #ff0000; margin-top: 5px; margin-bottom: 5px;"></div>
        <!-- Имя и email пользователя -->
        <div class="col-sm-6">
          <!-- Имя пользователя -->
          <div class="form-group has-feedback">
            <label for="name" class="control-label">Введите ваше имя:</label>
            <input type="text" id="name" name="name" class="form-control" required="required" value="" placeholder="Например, Иван Иванович"
              minlength="2" maxlength="30">
            <span class="glyphicon form-control-feedback"></span>
          </div>
        </div>
        <div class="col-sm-6">
          <!-- Email пользователя -->
          <div class="form-group has-feedback">
            <label for="email" class="control-label">Введите адрес email:</label>
            <input type="email" id="email" name="email" class="form-control" required="required" value="" placeholder="Например, ivan@mail.ru"
              maxlength="30">
            <span class="glyphicon form-control-feedback"></span>
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-sm-6">
          <!-- Телефон -->
          <div class="form-group has-feedback">
            <label for="name" class="control-label">Введите ваш телефон:</label>
            <input type="phone" id="phone" name="phone" class="form-control" required="required" value="" placeholder="+7 (901) 123-45-67"
              pattern="^\+\d{1,3}(|\s)\(\d{1,5}\)(|\s)\d{1,3}[\- ]\d{2}[\- ]\d{2}$">
            <span class="glyphicon form-control-feedback"></span>
          </div>
        </div>
        <div class="col-sm-6">
          <!-- Адрес сайта -->
          <div class="form-group has-feedback">
            <label for="email" class="control-label">Введите адрес вашего сайта:</label>
            <input type="url" id="siteurl" name="siteurl" class="form-control" required="required" value="" placeholder="Например, www.google.ru"
              maxlength="30">
            <span class="glyphicon form-control-feedback"></span>
          </div>
        </div>
      </div>
      <!-- Сообщение пользователя -->
      <div class="form-group has-feedback">
        <label for="message" class="control-label">Введите сообщение:</label>
        <textarea id="message" class="form-control" rows="3" placeholder="Введите сообщение, состоящее не менее чем из 20 символов и не более чем из 500"
          minlength="20" maxlength="500" required="required"></textarea>
      </div>
      <hr style="margin-top: 3px; margin-bottom: 3px;">
      <center>
        <div class="g-recaptcha" data-sitekey="6LepjAsTAAAAAFZqccY0ZiGqc3XEd3YNxo8cHsHX"></div>
      </center>
      <p class="text-danger" id="msg"></p>
      <!-- Кнопка, отправляющая форму по технологии AJAX -->
      <button name="send-message" type="submit" class="btn btn-primary pull-right">Отправить сообщение</button>
    </form>
    <!-- Конец формы -->
    
    1. Александр Мальцев # 0
      Изменил форму. Убрал возможность прикрепления файлов к ней, а также добавил новые поля (телефон и адрес сайта из Вашего шаблона).
      Скачать по ссылке: форму обратной связи с телефоном для сайта.

      Кстати в Вас в HTML шаблоне 2 опечатки в атрибуте for.
      1. Александр # 0
        Про опечатки — согласен, не уследил за ctrl+c + ctrl+v
    2. Александр # 0
      Александр. Благодарю.
      Наверное навязчив и назойлив, но хочется больше «красоты», можно-ли как-то сделать так, чтобы див с рекапчей появлялся только тогда, когда все поля формы заполнены.
      1. Александр Мальцев # 0
        В этом случае придётся немного изменить html-документ и js-скрипт.
        1. Добавить класс hidden к капчи и сообщению:
        <center>
          <div class="g-recaptcha hidden" data-sitekey="публичный_ключ"></div>
        </center>
        <p class="text-danger hidden" id="msg"></p>
        
        2. Добавить в script.js после загрузки страницы такой код:
        if ($('.g-recaptcha').hasClass('hidden')) {
          var result = {};
          $('#messageForm input,#messageForm textarea').change(function(){
            //найти предков, имеющих класс .form-group (для установления success/error)
            var formGroup = $(this).parents('.form-group');
            //найти glyphicon (иконка успеха или ошибки)
            var glyphicon = formGroup.find('.form-control-feedback');
            //валидация данных с помощью HTML5 функции checkValidity
            if (this.checkValidity()) {
              //добавить к formGroup класс .has-success и удалить .has-error
              formGroup.addClass('has-success').removeClass('has-error');
              //добавить к glyphicon класс .glyphicon-ok и удалить .glyphicon-remove
              glyphicon.addClass('glyphicon-ok').removeClass('glyphicon-remove');
              result[this.id]=true;
            } else {
              //добавить к formGroup класс .has-error и удалить .has-success
              formGroup.addClass('has-error').removeClass('has-success');
              //добавить к glyphicon класс glyphicon-remove и удалить glyphicon-ok
              glyphicon.addClass('glyphicon-remove').removeClass('glyphicon-ok');
              result[this.id]=false;
            }
            var showCaptcha = true;
            if (Object.keys(result).length==5) {
              $.each(result,function(key,value){
                if (value==false) {
                  showCaptcha = false;
                  return false;
                }
              });
              if (showCaptcha) {
                $('.g-recaptcha').removeClass('hidden');
                $('#msg').removeClass('hidden');
              }
            }
          });
        }
        
        Принцип здесь простой. Проверяем каждый элемент после его изменения и записываем результаты в объект result. После этого проверяем количество ключей в объекте. Если их количество равно 5, то проверяем все ли они прошли валидацию. Если да, то отображаем гугл капчу.

        HTML и JavaScript код формы обратной связи
      2. Алексей # 0
        Будь Здрав, Шеф!
        Немного офтопа) Можешь подсказать хорошую литературу, чтобы с нуля изучить php. Хочу такие же вещи как ты вытворять в modx)
        В меню не хватает иконки для php)
        Лучи добра)
        1. Александр Мальцев # 0
          Изучать php можно с любой книги из серии для ничинающих. По структуре они примерно все одинаковые. Выбирай ту из них которая ближе к тебе по написанию.
        2. bill # 0
          здравствуйте.
          подскажите, пожалуйста, что надо изменить в форме, чтоб поля для файлов показывались не по мере добавления файлов, а все сразу?
          1. Александр Мальцев # 0
            В файле script.js удалите следующий кусок кода:
            // если выбран файл, то добавить ещё элемент "Выбрать файл"
            if ((e.target.files.length>0)&&($(this).next('p').next('input[name="images[]"]').length==0) && ($('input[name="images[]"]').length<countFiles)) {
              $(this).next('p').after('<input type="file" name="images[]"><p style="margin-top: 3px; margin-bottom: 3px; color: #ff0000;"></p>');
            }
            
            В файл index.html после строчек:
            <input type="file" name="images[]">
            <p style="margin-top: 3px; margin-bottom: 3px; color: #ff0000;"></p>
            
            добавьте ещё 4 точно таких же:
            <input type="file" name="images[]">
            <p style="margin-top: 3px; margin-bottom: 3px; color: #ff0000;"></p>
            <input type="file" name="images[]">
            <p style="margin-top: 3px; margin-bottom: 3px; color: #ff0000;"></p>
            <input type="file" name="images[]">
            <p style="margin-top: 3px; margin-bottom: 3px; color: #ff0000;"></p>
            <input type="file" name="images[]">
            <p style="margin-top: 3px; margin-bottom: 3px; color: #ff0000;"></p>
            
            1. bill # 0
              огромное Вам спасибо!
          2. Евгений # 0
            Александр, здравствуйте.

            Подскажите, пожалуйста, почему так происходит. Добавляю изображения к сообщению в форме. Они сохраняются в папку files на сервере, но не приходят в письме. Куда нужно смотреть?

            Заранее спасибо.
            1. Александр Мальцев # 0
              В файле process.php измени этот код
              // прикрепляем файл к письму
              if (isset($file)) {
                $mail->addAttachment($file);
              }
              
              на следующий:
              // прикрепляем файлы к письму
              if (isset($files)) {
                foreach ($files as $value) {
                  $mail->addAttachment($value);
                }
              }
              
              1. Евгений # 0
                Александр, спасибо большое, за столь быстрый ответ. И прошу прощения, что сам так долго отвечал…
                Все работает :)
            2. Евгений # 0
              И Александр, будьте добры, подскажите, как будет правильней сформировать две формы на одной странице.
              Одна полностью будет повторять тот функционал, который у вас есть. А на второй будут только два поля: имя и номер телефона.

              P.s. Сразу не понял, почему у меня не работает отправка, когда разместил обе формы. Просто проверка полей в первой проходит, а во второй они пустые. Поэтому отправки нет(((
              1. Александр Мальцев # 0
                В файле script.js отправку формы осуществляет следующий обработчик:
                // #messageForm - id формы
                $('#messageForm').submit(function (event) {
                  //...
                });
                
                Следовательно, необходимо сделать 2 таких обработчика. Один для одной формы, другой для другой.
                Далее сделать 2 файла для обработки формы на стороне сервера (например, process.php и process2.php). Или использовать один php-файл, но тогда необходимо проверять с какой формы пришёл ответ, и обрабатывать уже именно её.

                Кроме этого, если Вы собираетесь использовать в каждой форме Google reCaptcha, то проделать ещё следующее:
                1. Каждому блоку reCaptcha дать идетификатор:
                <!-- Например, для 1 формы -->
                <div id="recaptcha1"></div>
                
                <!-- Например, для 2 формы -->
                <div id="recaptcha2"></div>
                
                2. Использовать скрипт для отрисовки 2 гугловских капч
                <script src="https://www.google.com/recaptcha/api.js?onload=myCallBack&render=explicit" async defer></script>
                <script>
                  var recaptcha1;
                  var recaptcha2;
                  var myCallBack = function() {
                    // отрисовка recaptcha1 на элементе с id="recaptcha1"
                    recaptcha1 = grecaptcha.render('recaptcha1', {
                      'sitekey' : 'ваш ключ site_key' 
                    });
                    // отрисовка recaptcha2 на элементе с id="recaptcha2"
                    recaptcha2 = grecaptcha.render('recaptcha2', {
                      'sitekey' : 'ваш ключ site_key' 
                    });
                  };
                </script>
                
                3. Проверять капчу на сервере.
                1. Евгений # 0
                  Простите Александр, но я совсем туговат в этом плане. Вторую форму на страницу добавил. Дал ей имя messageForm1. Весь код первой формы скопировал один в один.

                  Код для рекапчи вставил, спасибо, обе показываются.

                  В script.js скопировал обработчик, который вы написали. Опять же сменил всего лишь messageForm на messageForm1. Но вторая форма ничего не делает при нажатии на «Отправить сообщение». Первая работает.

                  Александр, если Вас не затруднит, напишите пожалуйста правильный script.js для моего случая. Формы одинаковые. Заранее спасибо.
                  1. Евгений # 0
                    Александр, прошу прощения за беспокойство, во всем разобрался. Большое Вам спасибо, за то что комментируете ваш код. Даже не зная только javascript и php, добился нужного себе результата.
                    Спасибо за Ваш труд!
                2. Георгий Куракин # 0
                  Здравствуйте! Подскажите пожалуйста, как сделать, чтобы можно было загружать фотографии большого размера до 10шт. по 10 мб. я поменял $maxSizeFile = 10485760; в трех местах в файле script и process. Когда отправляю сообщение с прикрепленным файлом в 7мб выдает ошибку «Произошла ошибка при отправке формы на сервер.». Если я правильно понимаю, то это из за того, что не отправляется такой файл по почте. Мне не обязательно получать на почту. Можно просто ссылкой.
                  1. Александр Мальцев # 0
                    Попробуйте установить следующие директивы в php.ini:
                    upload_max_filesize = 10M
                    post_max_size = 10M
                    
                    А также в файле .htaccess:
                    php_value upload_max_filesize 10M
                    php_value post_max_size 10M
                    
                    1. Георгий Куракин # 0
                      Добавил только в .htaccess Все работает благодарю за подсказку и собственно за форму!
                      Еще такой вопрос: можно сделать так, чтоб была показана загрузка или хотя бы стрелка мышки в песочные часы переключалась. т.к. не понятно нажал «отправить» или нет?
                      1. Александр Мальцев # 0
                        Как это сделать, можно посмотреть в этом комментарии. Там же приведён готовый пример формы обратной связи с вращающейся иконкой.
                  2. Александр # 0
                    Александр, приветствую.

                    Столкнулся с такой проблемой.
                    Если на странице 1 модальное окно с формой, — то все отлично.
                    Если же на странице больше 1 модального окна с формами то Рекапча отображается только в самом первом, в остальных не отображается.
                    Можно-ли это как-то побороть?
                    1. Александр Мальцев # 0
                      Для решения проблемы воспользуйтесь этим комментарием.
                      1. Александр # 0
                        Отлично, отображается. благодарю.
                    2. Александр # 0
                      Александр, пытаемся сделать форму заказа обратного звонка.
                      Добавили на форму HTML:
                      HTML:
                      <div class="row">
                        <div class="col-sm-12">
                          Перезвоните мне пожалуйста
                        </div>
                      </div>
                      <div class="row">
                        <div class="col-sm-6">
                          <div class="form-group">
                            с <input type="time" id="timestart" name="timestart" class="form-control" required="required" min="" max="22:00" value="">
                          </div>
                        </div>
                        <div class="col-sm-6">
                          <div class="form-group">
                            до <input type="time" id="timeend" name="timeend" class="form-control" required="required" min="" max="22:00" value="">
                          </div>
                        </div>
                      </div>
                      

                      И написали простановку значений для этих двух полей.
                      JavaScript:
                      <script>
                      //какое завтра будет число?
                      var d = new Date();
                      day = d.getDate() + 1;
                      month = d.getMonth() + 1;
                      year = d.getFullYear();
                      DateToCall = (day + "." + month + "." + year +"г.");
                      //Начало и Конец рабочего дня
                      var wdstart = 8;
                      var wdend = 18;
                      //Текущее время
                      var totalSec = new Date().getTime() / 1000;
                      var hours = parseInt( totalSec / 3600 ) % 24+4;
                      var hoursend = hours + 1;
                      var minutes = parseInt( totalSec / 60 ) % 60;
                      //Начало периода времени звонка
                      var tstart = (hours < 10 ? "0" + hours : hours) + ":" + (minutes < 10 ? "0" + minutes : minutes);
                      //Конец периода времени звонка
                      var tend = (hoursend < 10 ? "0" + hoursend : hoursend) + ":" + (minutes < 10 ? "0" + minutes : minutes);
                      //Устанавливаем значения для начала периода звонка
                      timestart.setAttribute('min', tstart);
                      timestart.setAttribute('value', tstart);
                      //Устанавливаем значения для конца периода времени звонка
                      timeend.setAttribute('min', tend);
                      timeend.setAttribute('value', tend);
                      </script>
                      

                      Оно вроде бы все замечательно. берет текущее время, проставляет его в поле с началом, прибавляет к текущему времени 1 час, проставляет его в поле с концом, все замечательно, тут вопросов нет, но, допустим пользователь зашел на сайт после 18:00, когда рабочий день закончен, и почту никто не прочитает сегодня, вот тут и заковырка, как сделать так, чтобы если пользователь заказывает звонок после окончания рабочего дня, но до 23:59, то ему надо сказать, что позвонят ему только завтра и начало и конец выставить, соответственно 8:00 и 22:00.
                      Если пользователь — полуночник и запрашивает звонок в период между 00:00 и 7:59 то начало и конец — также выставить на 8:00 и 22:00.
                      Если запрашивает с 8:00 до 18:00 — то по принципу, как сейчас.
                      Как это можно реализовать?
                      1. Александр # 0
                        UPD: Поколдовал сам, получилось вот так.
                        HTML:
                        <div class="row">
                          <div class="col-sm-12">
                            Перезвоните мне пожалуйста <span id="when"></span><input type="hidden" id="cday" name="cday" value="">
                          </div>
                        </div>
                        <div class="row">
                          <div class="col-sm-6">
                            <div class="form-group">
                              с <input type="time" id="timestart" name="timestart" class="form-control" required="required" min="" max="22:00" step="1"
                                value="">
                            </div>
                          </div>
                          <div class="col-sm-6">
                            <div class="form-group">
                              до <input type="time" id="timeend" name="timeend" class="form-control" required="required" min="" max="22:00" step="1"
                                value="">
                            </div>
                          </div>
                        </div>
                        

                        JavaScript:
                        <script>
                          //какое послезавтра будет число?
                          var b = new Date();
                            b.setDate(b.getDate()+2);
                            atday = b.getDate();
                            atmonth = b.getMonth() + 1;
                            atyear = b.getFullYear();
                            aTomorrowСall = (atday + "." + (atmonth < 10 ? "0" + atmonth : atmonth) + "." + atyear + "г.");
                            
                          //какое завтра будет число и день недели?
                          var a = new Date();
                            a.setDate(a.getDate()+1);
                            tday = a.getDate();
                            tmonth = a.getMonth() + 1;
                            tyear = a.getFullYear();
                            TomorrowСall = (tday + "." + (tmonth < 10 ? "0" + tmonth : tmonth) + "." + tyear + "г.");
                            TomorrowWeekDay = a.getDay();
                          //А сегодня какое число и день недели?
                          var d = new Date();
                            day = d.getDate();
                            month = d.getMonth() + 1;
                            year = d.getFullYear();
                            TodayCall = (day + "." + (month < 10 ? "0" + month : month) + "." + year +"г.");
                            TodayWeekDay = d.getDay();
                          //Начало и Конец рабочего дня
                          var wdstart = 8;
                          var wdend = 18;
                          var lasthour = wdend - 1;
                          //Текущее время
                          var totalSec = new Date().getTime() / 1000;
                          var hours = parseInt( totalSec / 3600 ) % 24+4;
                          var hoursend = hours + 1;
                          var minutes = parseInt( totalSec / 60 ) % 60;
                          //Начало периода времени звонка
                          var tstart = (hours < 10 ? "0" + hours : hours) + ":" + (minutes < 10 ? "0" + minutes : minutes);
                          //Конец периода времени звонка
                          var tend = (hoursend < 10 ? "0" + hoursend : hoursend) + ":" + (minutes < 10 ? "0" + minutes : minutes);
                          
                          //Если сейчас рабочее время
                          if (hours >= wdstart) {
                            if (hours < wdend) {
                              //Если сегодня воскресение
                              if (TodayWeekDay = 0) {
                                //Показываем, что пользователь заказывает звонок на завтра
                                when.innerHTML = ('завтра ' + TomorrowСall);
                                //Устанавливаем дату звонка - завтра
                                cday.setAttribute('value', TomorrowСall);
                                //Устанавливаем значения для начала периода звонка
                                timestart.setAttribute('min', '08:00');
                                timestart.setAttribute('value', '08:00');
                                //Устанавливаем значения для конца периода времени звонка
                                timeend.setAttribute('min', '22:00');
                                timeend.setAttribute('value', '22:00');
                              }
                              else {
                                  //А вдруг запрос звонка происходит в последние 10 минуты рабочего времени
                                  if (hours >= lasthour) {
                                    if (minutes > 50) {
                                      //А вдруг это последние рабочие минуты субботы?
                                      if (TodayWeekDay = 6) {
                                        //Показываем, что пользователь заказывает звонок на послезавтра
                                        when.innerHTML = ('завтра ' + аTomorrowСall);
                                        //Устанавливаем дату звонка - послезавтра
                                        cday.setAttribute('value', аTomorrowСall);
                                        //Устанавливаем значения для начала периода звонка
                                        timestart.setAttribute('min', '08:00');
                                        timestart.setAttribute('value', '08:00');
                                        //Устанавливаем значения для конца периода времени звонка
                                        timeend.setAttribute('min', '22:00');
                                        timeend.setAttribute('value', '22:00');
                                      }
                                      else {
                                          //Показываем, что пользователь заказывает звонок на завтра
                                          when.innerHTML = ('завтра ' + TomorrowСall);
                                          //Устанавливаем дату звонка - завтра
                                          cday.setAttribute('value', TomorrowСall);
                                          //Устанавливаем значения для начала периода звонка
                                          timestart.setAttribute('min', '08:00');
                                          timestart.setAttribute('value', '08:00');
                                          //Устанавливаем значения для конца периода времени звонка
                                          timeend.setAttribute('min', '22:00');
                                          timeend.setAttribute('value', '22:00');	
                                      }
                                    }
                                  }
                                  else {
                                    //Устанавливаем дату звонка - сегодня
                                    cday.setAttribute('value', TodayCall);
                                    //Устанавливаем значения для начала периода звонка
                                    timestart.setAttribute('min', tstart);
                                    timestart.setAttribute('value', tstart);
                                    //Устанавливаем значения для конца периода времени звонка
                                    timeend.setAttribute('min', tend);
                                    timeend.setAttribute('value', tend);
                                  }
                              }
                            }
                          }
                          
                          //Если рабочее время еще не началось
                          if (hours < wdstart) {
                            //Если сегодня воскресение
                            if (TodayWeekDay = 0) {
                              //Показываем, что пользователь заказывает звонок на завтра
                              when.innerHTML = ('завтра ' + TomorrowСall);
                              //Устанавливаем дату звонка - завтра
                              cday.setAttribute('value', TomorrowСall);
                              //Устанавливаем значения для начала периода звонка
                              timestart.setAttribute('min', '08:00');
                              timestart.setAttribute('value', '08:00');
                              //Устанавливаем значения для конца периода времени звонка
                              timeend.setAttribute('min', '22:00');
                              timeend.setAttribute('value', '22:00');
                            }
                            else {
                              //Устанавливаем дату звонка - сегодня
                              cday.setAttribute('value', TodayCall);
                              //Устанавливаем значения для начала периода звонка
                              timestart.setAttribute('min', '08:00');
                              timestart.setAttribute('value', '08:00');
                              //Устанавливаем значения для конца периода времени звонка
                              timeend.setAttribute('min', '22:00');
                              timeend.setAttribute('value', '22:00');
                            }
                          }
                          //Если рабочее время уже закончилось
                          if (hours >= wdend) {
                            //А вдруг сегодня суббота?
                            if (TodayWeekDay = 6) {
                              //Показываем, что пользователь заказывает звонок на послезавтра
                              when.innerHTML = ('завтра ' + аTomorrowСall);
                              //Устанавливаем дату звонка - послезавтра
                              cday.setAttribute('value', аTomorrowСall);
                              //Устанавливаем значения для начала периода звонка
                              timestart.setAttribute('min', '08:00');
                              timestart.setAttribute('value', '08:00');
                              //Устанавливаем значения для конца периода времени звонка
                              timeend.setAttribute('min', '22:00');
                              timeend.setAttribute('value', '22:00');
                            }
                            else {
                              //Показываем, что пользователь заказывает звонок на завтра
                              when.innerHTML = ('завтра ' + TomorrowСall);
                              //Устанавливаем дату звонка - завтра
                              cday.setAttribute('value', TomorrowСall);
                              //Устанавливаем значения для начала периода звонка
                              timestart.setAttribute('min', '08:00');
                              timestart.setAttribute('value', '08:00');
                              //Устанавливаем значения для конца периода времени звонка
                              timeend.setAttribute('min', '22:00');
                              timeend.setAttribute('value', '22:00');
                            }
                        }
                        </script>
                        

                        Все отлично, протестировал, работает как надо.
                        Вопрос, а как сделать так, чтобы этот скрипт срабатывал не при загрузке страницы, а при открытии модального окна с формой?
                        1. Александр Мальцев # 0
                          Если вы используете Bootstrap Modal, то ваш код необходимо поместить в следующий:
                          //exampleModal - id модального окна
                          $('#exampleModal').on('show.bs.modal', function (event) {
                            //...
                          })
                          
                          1. Александр # 0
                            Благодарю
                            1. Александр # 0
                              Александр, приветствую.
                              Почему-то внезапно перестал отрабатывать скрипт (и соответственно отображать форму). Выдает ошибку Uncaught ReferenceError: аTomorrowСall is not defined.

                              Не подскажете в чем может быть проблема?
                              (из изменений были только: поправлены стили кнопки, которая вызывает модельное окно, и само модальное окно перенесено непосредственно под тэг body)

                              И в локале, где точно ничего не менялось и никуда не двигалось — произошло тоже самое.
                              1. Александр # 0
                                UPD: Причем так себя ведет когда скрипт запускается по открытии модального окна
                                jQuery(function($) {
                                $('#CallBackFrm').on('show.bs.modal', function (event) {
                                	...
                                })
                                });
                                1. Александр Мальцев # 0
                                  Посмотрите, на какой строчке возникает ошибка и значения переменных. Она обычно возникает, когда Вы хотите присвоить значение некоторой сущности, для которой это сделать нельзя.
                                  1. Александр # 0
                                    Это возникает вот в этом месте
                                    //Если рабочее время уже закончилось
                                      if (hours >= wdend) {
                                        //А вдруг сегодня суббота?
                                        if (TodayWeekDay = 6) {
                                          //Показываем, что пользователь заказывает звонок на послезавтра
                                          when.innerHTML = ('завтра ' + аTomorrowСall);
                                    И только если скрипт запускаем по открытию модального окна, завернув его в
                                    jQuery(function($) {
                                    $('#CallBackFrm').on('show.bs.modal', function (event) {
                                    	...
                                    })
                                    });
                                    Причем, возникать оно начало «само-по-себе» ничего, что могло бы повлиять не происходило, как и сказал выше.
                                    Если убираем «обертку»
                                    jQuery(function($) {
                                    $('#CallBackFrm').on('show.bs.modal', function (event) {
                                    	...
                                    })
                                    });
                                    То все работает, никаких ошибок не возникает.
                                    1. Александр Мальцев # 0
                                      Знак равенства в Javascript — это == (два знака равно). А у вас в if только один.
                                      1. Александр # 0
                                        Правильно-ли я понимаю, что два знака равно должно быть в строчке
                                        if (TodayWeekDay = 6) {
                                        ?
                                        Если да, то все стает еще интереснее. Исчезает ошибка, но если вызов окна происходит после 17:00 (конец рабочего дня), то никакие значения полям не выставляются,
                                        when.innerHTML = ('завтра ' + аTomorrowСall);
                                        тоже не отрабатывает.
                                        1. Александр # 0
                                          Пока вопрос снят.
                                          Дело было в путях к jQuery.
                              2. Александр # 0
                                Все вроде отлично работает. Но имел неосторожность протестировать на iphone.
                                Вскрылся баг. Safari не обращает никакого внимания на установленные скриптом значения, а именно не отображает value установленное скриптом, и не обращает внимания на то, что скрипт устанавливал значения min/
                                Может есть способы побороть?
                              3. Александр # 0
                                UPD:
                                И Хром на Андроиде тоже подкосячивает, он вроде-как все значения атрибутов устанавливает, но установленное скриптом значение value не отображает (надообязательно тыкнуться в поле и «подтвердить»).
                                1. Александр Мальцев # 0
                                  Может быть проще было бы написать с помощью jQuery.

                                  Работа с value в JavaScript осуществляется как свойством:
                                  //получить значение свойства value
                                  var value = document.getElementById('name').value;
                                  // установить значение свойству value
                                  document.getElementById('name').value = '08:00';
                                  
                                  Добавление своих пользовательских атрибутов осуществляется с помощью data-. Т.е. data-min и data-max.
                                  1. Александр # 0
                                    Может быть и проще с помощью jQuery, но я и в js-то валенок.
                                    С показом value, кстати не помогло через document.getElementById они устанавливаются, но не отображаются в полях (iphone + Safari и Android + Chrome).

                                    По поводу min и max — так вроде это не пользовательские атрибуты они вроде в спецификации HTML5 есть. и они отрабатываются в текущем виде на Android + Chrome, а вот Safari на iPhone их игнорит.
                                    1. Александр Мальцев # 0
                                      Немного не то имел ввиду.
                                      Когда вы устанавливаете значение value, обращаться к нему необходимо как к свойству, а не как к атрибуту:
                                      // т.е. вместо
                                      cday.setAttribute('value', TomorrowСall);
                                      // использовать следующее
                                      cday.value = TomorrowСall;
                                      
                                      Такие атрибуты в HTML5 есть, но вот их поддержка осуществляется только несколькими браузерами (Edge, Chrome, Opera и Android 4.4+). _http://caniuse.com/#search=date
                                      1. Александр # 0
                                        Отлично. Благодарю. Теперь выставленные значения отображаются
                                        По поводу min и max — ccылку посмотрел, правильно ли я понимаю, что эти ограничения выставить не получится для Safari на iOS или есть какой-то обходной путь?
                                        1. Александр Мальцев # 0
                                          Написать скрипт самостоятельно или использовать какой-нибудь готовый плагин для работы с датой (datepicker, datetimepicker или др.), который это поддерживает.
                              4. Владимир # 0
                                Здравствуйте Александр. Не могли бы Вы подсказать обработчик для простейшей формы: нет никаких ввода чего либо, только каптча.
                                Есть такой index.php:
                                <!DOCTYPE html>
                                <html>
                                
                                <head>
                                  <title>reCAPTCHA</title>
                                  <script src='https://www.google.com/recaptcha/api.js'></script>
                                </head>
                                
                                <body>
                                  <center>
                                    <form method="POST" action="go.php">
                                      <div class="g-recaptcha" data-sitekey="6Le7DQcUAAAAAD-IPHVHF_B84qcWaQKlMvqS_krZ"></div>
                                      <center><button type="submit" name="register" id="allpageinside_a_s_b_alongone" id="body_the_sign_up_button_captcha">Register</button></center>
                                    </form>
                                  </center>
                                </body>
                                
                                </html>
                                
                                Задача следующая: экшн ведет на go.php (например), при клике по кнопке без каптчи должна появиться ошибка-напоминание, что без каптчи никто никуда не пойдет? или просто переход не должен произойти.
                                Если каптча разгадана, то тогда осуществляется переход на go.php.
                                При переходе по прямому адресу site.ru/go.php вход не должен произойти, если можно сделать что-то типа переадресации на страницу с каптчей, в случае попытки захода на go.php минуя каптчу.

                                Все, что находил в сети, не подходит… Переделать — не хватает знаний.
                                Если Вам не сложно, и если эта задача действительно не сложная, то не могли бы помочь?
                                1. Владимир # 0
                                  или другой вариант: всё на одной странице. Содержимое индекса не должно быть видимым пока не будет пройдена каптча.
                                  Т.е заходим на index.php и там каптча, после ввода каптчи в этом же index.php открывается уже содержание страницы, а каптча исчезает.
                                  Видел на одном сайте такое. Скорее всего это будет проще сделать, чем первый вариант. И этот вариант даже будет лучше.
                                  И там тоже нажатие кнопки без каптчи не дает никакой результат, только после ввода каптчи появляется соджержимое страницы. А каптча исчезает.
                                  И пока находимся на этой странице — каптчи нет. При новом заходе на страницу каптча снова есть.
                                  Помогите решить задачу, а то уже перерыл весь гугл, и наш и зарубежный — нет таких вариантов, даже близко.
                                  1. Владимир # 0
                                    Вот вариант одностраничный:
                                    <?php 
                                    if (isset($_POST['submit'])) {
                                      $secret = '6LfE5hQTAAAAAIU5P_IQjg8JIZ_x4Rd4dSzysgSC';
                                      $response = $_POST['g-recaptcha-response'];
                                      $remoteip = $_SERVER['REMOTE_ADDR']; 
                                      $url = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=$secret&response=$response&remoteip=$remoteip");
                                      $result = json_decode($url, TRUE);
                                      if ($result['success'] == 1) {
                                        echo $_POST['myreq'];
                                      }
                                    }
                                    ?>
                                    <!doctype html>
                                    <html lang="en">
                                    
                                    <head>
                                      <meta charset="utf-8">
                                      <title>Google reCAPTCHA</title>
                                    </head>
                                    
                                    <body>
                                      <form action="" method="post">
                                        <input type="text" name="myreq">
                                        <div class="g-recaptcha" data-sitekey="6LfE5hQTAAAAAH2Aj5lMPSA4yUQzsEDGxoJbV4Ib"></div>
                                        <input type="submit" name="submit" value="Send Request!">
                                      </form>
                                    
                                      *ТУТ содержание страницы, которое не видно до ввода каптчи*
                                    
                                    </body>
                                    <script src='https://www.google.com/recaptcha/api.js'></script>
                                    
                                    </html>
                                    
                                    Нужно сделать без поля ввода текста и чтобы после ввода каптчи она исчезала и появлялось основное содержание страницы
                                    1. Александр Мальцев # 0
                                      Это будет выглядеть следующим образом:
                                      <!DOCTYPE html>
                                      <html lang="ru">
                                      <head>
                                        <meta charset="utf-8">
                                        <title></title>
                                      </head>
                                      <body>
                                      
                                      <?php
                                      $showform = true;
                                      if (isset($_POST['g-recaptcha-response'])) {
                                        // ваш секретный ключ
                                        $secret = 'ваш_секретный_код';
                                        require_once (dirname(__FILE__).'/recaptcha/autoload.php');
                                        // создать экземпляр службы recaptcha, используя секретный ключ
                                        $recaptcha = new \ReCaptcha\ReCaptcha($secret);
                                        // получить результат проверки кода recaptcha
                                        $resp = $recaptcha->verify($_POST['g-recaptcha-response'], $_SERVER['REMOTE_ADDR']);
                                        // если результат положительный, то...
                                        if ($resp->isSuccess()){
                                          $showform = false;
                                          ?>
                                      
                                          <!-- HTML-код, который будет отображаться при правильном вводе капчи  -->
                                          <p>Контент страницы...</p> 
                                      
                                          <?php
                                        } 
                                      }
                                      if ($showform==true) {
                                      ?>
                                      
                                      <!-- Форма с гугловской рекапчей -->
                                      <form action="<?php echo $_SERVER['REQUEST_URI']; ?>" id="captchaForm" method="post">
                                        <!-- Google reCAPTCHA -->
                                        <div class="g-recaptcha" data-sitekey="ваш_site_код"></div>
                                        <button name="send-message" type="submit" class="btn btn-primary pull-right">Отправить</button>
                                      </form><!-- Конец формы -->
                                      
                                      <?php
                                      }
                                      ?>
                                      
                                      <script src='https://www.google.com/recaptcha/api.js'></script>
                                      </body>
                                      </html>
                                      
                                      Вместо ваш_секретный_код и ваш_site_код вставить соответствующие ключи Google reCaptcha.
                                  2. Александр Мальцев # 0
                                    Это осуществляется так.
                                    1 файл (например, index.html):
                                    <!DOCTYPE html>
                                    <html lang="ru">
                                    <head>
                                      <meta charset="utf-8">
                                      <title></title>
                                    </head>
                                    <body>
                                    
                                    <!-- Форма с гугловской рекапчей -->
                                    <form action="go.php" id="messageForm" method="post">
                                      <!-- Google reCAPTCHA -->
                                      <div class="g-recaptcha" data-sitekey="ваш_сайт_код"></div>
                                      <button name="send-message" type="submit" class="btn btn-primary pull-right">Отправить</button>
                                    </form><!-- Конец формы -->
                                    
                                    <script src='https://www.google.com/recaptcha/api.js'></script>
                                    
                                    </body>
                                    </html>
                                    
                                    2 файл (например, go.php). Он будет проверять код reCaptcha. В случае ошибки, переправлять его (пользователя) на страницу, содержащую капчу гугл. В случае успеха, отображать содержимое этой формы.
                                    <?php
                                    $showError = true;
                                    if (isset($_POST['g-recaptcha-response'])) {
                                      $secret = 'ваш_секретный_ключ';
                                      require_once (dirname(__FILE__).'/recaptcha/autoload.php');
                                      // создать экземпляр службы recaptcha, используя секретный ключ
                                      $recaptcha = new \ReCaptcha\ReCaptcha($secret);
                                      // получить результат проверки кода recaptcha
                                      $resp = $recaptcha->verify($_POST['g-recaptcha-response'], $_SERVER['REMOTE_ADDR']);
                                      // если результат положительный, то...
                                      if ($resp->isSuccess()){
                                        $showError = false;
                                      }
                                    }
                                    if ($showError==true) {
                                      header('Location: http://site.ru/index.php');
                                      exit;
                                    }
                                    ?>
                                    <!DOCTYPE html>
                                    <html lang="ru">
                                    <head>
                                      <meta charset="utf-8">
                                      <title></title>
                                    </head>
                                    <body>
                                    
                                    <?php
                                    if ($showError==false) {
                                    ?>
                                    
                                    <!-- HTML-код, который будет отображаться при правильном вводе капчи  -->
                                    <p>Контент страницы...</p> 
                                    
                                    <?php
                                    }
                                    ?>
                                    
                                    </body>
                                    </html>
                                    
                                    1. Владимир # 0
                                      Что-то не идет: feex.ru/test/ — это вариант с файлом go
                                      feex.ru/test/index2.php — это Ваш первый код
                                      1. Александр Мальцев # 0
                                        Конечно не пойдёт, библиотеку recaptcha вы же не скопировали в свой проект.
                                        1. Владимир # 0
                                          Не скопировал)
                                          Теперь всё работает. Спасибо)
                                  3. Слава # 0
                                    Здравствуйте!
                                    У меня такой вопрос, возможно ли уведомлять юзера, что файл был принят/загружен, а то ошибки выдаются типа: (Файл не будет загружен, размер больше 512Кбайт), а по успеху тишина.
                                    Буду оч благодарен за помощь. Сам я 2-а по кушу в этом = )
                                    PS Форма у меня с обычной каптчей взятая тут: itchief.ru/lessons/php/feedback-form-for-website

                                    Поздно увидел с каптчей от гугла… переделывать не охота = )
                                    1. Александр Мальцев # 0
                                      Здравствуйте.
                                      Тут нет ничего сложно.
                                      Необходимо открыть файл script.js и изменить внутреннее содержимое блока
                                      if (e.target.files.length>0) {
                                        //...
                                      }
                                      
                                      на следующее:
                                      var file = e.target.files[0];
                                      if (file.size>maxSizeFile) {
                                        $(this).next('p').text('* Файл не будет отправлен, т.к. его размер больше 512Кбайт');
                                        $(this).next('p').css('color','red');
                                      }
                                      else if (!file.type.match(typeFile)) {
                                        $(this).next('p').text('* Файл не будет отправлен, т.к. его тип не соответствует разрешённому');
                                        $(this).next('p').css('color','red');
                                      }
                                      else if ((file.size<=maxSizeFile) && (file.type.match(typeFile))) {
                                        $(this).next('p').text('Файл удовлетворяет требованиям и будет отправлен');
                                        $(this).next('p').css('color','green');
                                      }
                                      else {
                                        if ($(this).next('p')) {
                                          $(this).next('p').text('');
                                        }
                                      }
                                      
                                      1. Слава # 0
                                        Спасибо за помощь!
                                    2. Александр # 0
                                      Александр, приветствую.

                                      Пытаюсь на сайт прикрутить 3 модальных окна с формами и с рекапчта, запутался совсем-совсем, из них отрабатывает только одна, при чем странно не выдает сообщение о успешной отправке сообщения.

                                      Можете помочь, — посмотреть, Может свяжемся по электронной почте.
                                      1. Александр # 0
                                        Почему сообщение не выводилось — разобрался.
                                        А вот почему две другие формы не отправляются не понимаю… (

                                        Где-то накосячил в js и php обрабтчиках

                                        Ссылка на zip архив
                                        форма обратного звонка — отрабатывает
                                        Остальные две — затыкаются после нажатия на кнопку отправки
                                        1. Александр Мальцев # 0
                                          Здравствуйте, Александр.
                                          Комментарий на эту тему:
                                          itchief.ru/lessons/php/how-to-install-recaptcha-on-website#comment-2852
                                          Ответ с виджета, если их несколько, необходимо получать по его идентификатору.
                                          Если виджеты, например, имеют идентификаторы recaptcha1 и recaptcha2, то и отправлять их ответ на сервер необходимо по id:
                                          var captcha = grecaptcha.getResponse(recaptcha1);
                                          // добавить в formData значение recapcha1
                                          formData.append('g-recaptcha-response', captcha);
                                          
                                          1. Александр # 0
                                            Александр, благодарю, за науку.
                                            В локале работает. буду пробовать на живом.
                                            1. Александр # 0
                                              Александр еще вопрос по путям к скриптам.
                                              Допустим все 6 скриптов проверки и обработки (3js+3php) мы положили в корень сайта.
                                              Подключая их на страницах src формируем через «location.origin + '/formcheck.js';».
                                              Это работает, пути в src тегов script прописываются.
                                              В этих js скриптах проверки форм, пытаюсь проделать тот-же фокус с путем к php, например:


                                              // Формируем путь к скрипту
                                              var ofcURLPHP = CurrentDomain + "/process.php";
                                              // технология AJAX
                                              $.ajax({
                                              //метод передачи запроса — POST
                                              type: «POST»,
                                              //URL-адрес запроса
                                              url: ofcURLPHP,
                                              //передаваемые данные — formData
                                              data: formData,


                                              И вот тут похоже, что в url: не пишется путь до скрипта, по нажатию на кнопку отправки формы, форма не отправляется и модальное окно закрывается.
                                              Можно как-то это вылечить?
                                              (Смысл задачи в том, чтобы на внутренних страницах сайта, имеющих, например путь site.ru/product/okno/okna.html не прописывать руками пути к скриптам обработчикам, не множить их в подпапках).
                                              1. Александр # 0
                                                С этим разобрался, не подключались JS хоть пути и прописывались.
                                                Все работает, только 1 форма начала вести себя, как во вчерашнем вопросе (не отсылается по нажатию кнопки)…
                                                После исправлений по вчерашней вашей рекомендации все работало.
                                                И в принципе в js только добавилось определение адреса, где php лежит.
                                                Cсылка на архив
                                                Форма про типовые.
                                                1. Александр # 0
                                                  Которая по кнопке «Хочу» открывается.
                                                  1. Александр Мальцев # 0
                                                    Проверьте значения переменной formValid и капчи перед if. Так как после проверки данные дальше уже идут на отправку.
                                                    console.log(formValid);
                                                    console.log(captcha.length);
                                                    if ((formValid) && (captcha.length)) {
                                                    
                                                    При сбросе reCaptcha также необходимо указывать идентификатор:
                                                    grecaptcha.reset(recaptcha1);
                                                    
                                                    1. Александр # 0
                                                      В консоли 2 строчки:
                                                      true
                                                      953.

                                                      Но самое странное не это.
                                                      Форма, которая по кнопкам «Хочу» заработала просто сама по-себе, но заболела форма про «перезвоните мне»
                                                      1. Александр # 0
                                                        А в каком именно месте надо сбрасывать recaptcha??
                                                        1. Александр # 0
                                                          Ага. нашел, где сбрасывается рекапча.

                                                          Проставил идентификаторы.
                                                          Та форма, что по кнопкам «Хочу» — работать перестала, за-то вылечилась форма запроса звонка.
                                                          1. Александр # 0
                                                            Убрал везде идентификаторы, все заработало. само по себе, все три формы.
                                                            Волшебство какое-то.
                                                            1. Александр # 0
                                                              А сегодня не работает, и не понятно почему.
                                                              Александр, может мы сможем это поправить возможно не безвозмездно.
                                            2. Александр # 0
                                              И еще вопрос появился, после того, как заработала форма про «Хочу», кнопок «Хочу» — 4 штуки, если 1 раз форма отработала, а пользователь, например хочет еще другое «Хочу», то во второй и следующие разы открывается модальное окно в котором форма скрыта, но отображается сообщение об успешной отправке первого запроса. Как быть с этим.
                                              1. Александр Мальцев # 0
                                                Необходимо переделать алгоритм в JavaScript так, чтобы он не скрывал форму, а очищал все заполненные поля для возможности повторной отправки формы. А также чтобы он отображал сообщение об успешной отправки, например, с помощью плагина jGrowl.
                                                1. Александр # 0
                                                  Подскажете, как это сделать? А-то я уже боюсь трогать, по принципу не навредить, а учитывая, что я чайник, навредить — это я запросто.
                                                  1. Александр # 0
                                                    Нашел вот такой уведомитель bootstrap-notify.remabledesigns.com, но как его прикрутить не знаю.
                                                    То есть мысль ясна: получить ответ от сервера, если все хорошо; очистить поля формы; форму (модальное окно) закрыть, всплывающее уведомление показать.
                                                    А вот как это сделать?
                                                    1. Александр Мальцев # 0
                                                      Если использовать jGrowl, то это будет осуществляться следующим образом:
                                                      1. Скачать и подключить к странице плагин jGrowl:
                                                      <!-- подключить файл стилей CSS jGrowl -->
                                                      <link rel="stylesheet" href="/feedback/css/jquery.jgrowl.min.css">
                                                      <!-- добавить темы сообщений -->
                                                      <style>
                                                        .message-success {
                                                          background-color: green !important;
                                                        }
                                                        .message-error {
                                                          background-color: brown !important;
                                                        }
                                                        .message-info {
                                                          background-color: black !important;
                                                        }
                                                      </style>
                                                      <!-- подключить скрипт jGrowl -->
                                                      <script src="/feedback/js/jquery.jgrowl.min.js"></script>
                                                      
                                                      2. Изменить параметры success и error метода jQuery ajax:
                                                      success: function(data) {
                                                        // разбираем строку JSON, полученную от сервера
                                                        var $data = JSON.parse(data);
                                                        // если сервер вернул ответ success, то значит двнные отправлены
                                                        if ($data.result == "success") {
                                                          // сбрасываем виджет reCaptcha
                                                          grecaptcha.reset();
                                                          // очистить форму
                                                          $('#messageForm').find('input,textarea').each(function() {
                                                            $(this).val('');
                                                            $(this).parents('.form-group')
                                                                     .removeClass('has-success has-error')
                                                                   .find('.form-control-feedback')
                                                                     .removeClass('glyphicon-ok glyphicon-remove');
                                                          });
                                                          // очистить файлы
                                                          $('#upload-files').html('<input type="file" name="images[]"><p style="margin-top: 3px; margin-bottom: 3px; color: #ff0000;"></p>');
                                                          // вывести сообщение об успешной отправки
                                                          $.jGrowl("Внимание!
                                                      Ваше сообщение успешно отправлено.", { life: 10000, theme: 'message-success' });
                                                        } else {
                                                          // вывести сообщение об ошибке
                                                          $.jGrowl("Внимание!
                                                      Произошла ошибка при отправке формы на сервер.", { life: 10000, theme: 'message-error' });
                                                          // сбрасываем виджет reCaptcha
                                                          grecaptcha.reset();
                                                          // выводим ошибки о невалидности полей формы
                                                          if ($data.name) {
                                                            $.jGrowl($data.name, { life: 10000, theme: 'message-error' });
                                                          }
                                                          if ($data.email) {
                                                            $.jGrowl($data.email, { life: 10000, theme: 'message-error' });
                                                          }
                                                          if ($data.message) {
                                                            $.jGrowl($data.message, { life: 10000, theme: 'message-error' });
                                                          }
                                                          // Если существует свойство msg у объекта $data, то...
                                                          if ($data.msg) {
                                                            // вывести сообщение об ошибке кода капчи
                                                            $.jGrowl($data.msg, { life: 10000, theme: 'message-error' });
                                                          }
                                                          if ($data.files) {
                                                            // вывести сообщение об ошибке, которая произошла при загрузке файлов
                                                            $.jGrowl($data.files, { life: 10000, theme: 'message-error' });
                                                          }
                                                        }
                                                      },
                                                      error: function(request) {
                                                        // вывести сообщение о том что произошла ошибка во время отправки данных
                                                        $.jGrowl('Произошла ошибка ' + request.responseText + ' при отправке данных.', { life: 10000, theme: 'message-error' });
                                                      }
                                                      
                                                      Готовый пример можно получить по ссылке: yadi.sk/d/IS2h3L4IyPK8w
                                                      1. Александр # 0
                                                        Таки как оказалось jGrowl-у тоже нужен bootstrap.js, как минимум чтобы программно закрыть модальное окно через $('feedbackForm').modal('hide'), и плюсом к тому без него не работает конструкция $.jGrowl…
                                                    2. Александр # 0
                                                      Александр, приветствую.

                                                      Подключил bootstrap-notify в локалке на тестовых страничках — работает как надо,
                                                      Когда подключаю его к сайту на joomla происходит следующее:
                                                      1. bootstrap-notify требует для работы bootstrap.js (он же нужен, чтобы модальное окно программно закрывать по .modal('hide'))
                                                      2. после подключения bootstrap.js к живому joomla сайту модальные окна сами закрываются едва открывшись.
                                                      в чем может быть проблема?
                                                      1. Александр Мальцев # 0
                                                        Не знаю, он мне как-то не приглянулся. Выше привёл пример с использованием jGrowl.
                                                  2. Александр # 0
                                                    Сейчас оно вот в таком виде
                                                    По кнопкам Заказа звонка и Запроса замеров вроде отрабатывает, по 4м кнопкам хочу, письмо отправляется, форма не прячется, сообщения о отправке не выдается в консоль выводится:
                                                    true
                                                    1209
                                                    Uncaught SyntaxError: Unexpected token < in JSON at position 1(…)
                                                    Ошибка синтаксиса ссылается на строку var $data = JSON.parse(data); файла formcheck.js
                                                    1. Александр Мальцев # 0
                                                      Это ошибка означает то, что сервер возвращает результат не соответствующий формату JSON.
                                                      Попробуйте проанализировать ответ, который приходит с сервера на вкладке браузера Network в панели разработчика. Может вы используете на стороне сервера некоторые поля, которые не указали в форме или что-то другое. Попробуйте проверить каждую форму по отдельности на предмет ошибок.
                                                      1. Александр # 0
                                                        Вот что в консоли во вкладке Network про файл process.php

                                                        Warning: session_start(): Cannot send session cookie — headers already sent by (output started at… /process.php:1) in… /process.php on line 3

                                                        Warning: session_start(): Cannot send session cache limiter — headers already sent (output started at… /process.php:1) in… /process.php on line 3
                                                        {«result»:«success»}

                                                        Но для меня это птичий язык...(
                                                        1. Александр # 0
                                                          Проверял по отдельности, каждая форма в отдельном html, результат тотже. что вместе, что по отдельности, косяк только с обработкой формы которая по кнопкам Хочу и в которую javascript-ом пишутся options в select
                                                          1. Александр # 0
                                                            Нашел.
                                                            Как оказалось файл process.php начинался с: " <?php", — (/пробел/<?php)
                                                            В жизни не подумал бы, что из-за этого…
                                                            1. Александр # 0
                                                              Вроде все работает,
                                                              Но странно ведет себя форма запроса звонка, непредсказуемо через раз, через два отправляется, когда не отправляется жалуется на то, что серверу пришло пустое поле name:
                                                              {result: «error», name: «Поле имя не должно быть пустым.»}
                                                              name
                                                              :
                                                              «Поле имя не должно быть пустым.»
                                                              result
                                                              :
                                                              «error»

                                                              Я в файле php проверку длины поменял на проверку непустое:
                                                              //получить имя, которое ввёл пользователь
                                                              if (isset($_POST['name'])) {
                                                              $name = $_POST['name'];
                                                              if (empty($name)) {
                                                              $data['name']='Поле имя не должно быть пустым.';
                                                              $data['result']='error';
                                                              }
                                                              } else {
                                                              $data['result']='error';
                                                              }

                                                              в js ничего не менялось.

                                                              Поле:
                                                              input type=«text» class=«form-control» id=«name» name=«name» required=«required» value="" placeholder=«Алексей Сергеевич Петров» minlength=«4» style=«border: 1px solid rgba(153, 153, 255, 0.5);width:100%;»

                                                              Где может быть засада?
                                                              причем на остальных формах с полем name я поступил точно также и они работают
                                                              1. Александр Мальцев # 0
                                                                Попробуйте, поискать ещё ошибки…
                                                        2. Георгий # 0
                                                          Здравствуйте! У Вас не найдется всплывающей формы без капчи и только двумя полями для заполнения «имя» и «телефон»? Нужно для обратного звонка. Буду очень благодарен!
                                                          1. Александр Мальцев # 0
                                                            Форма для обратного звонка: yadi.sk/d/unjPnijlyPuJV
                                                          2. Артем # 0
                                                            Добрый вечер!
                                                            Подскажите пожалуйста, скачал вашу форму обратной связи с reCaptcha и установил на Denwere, все вроде хорошо, но при отправке сообщения вываливается ошибка VM34651:1 Uncaught SyntaxError: Unexpected token < in JSON at position 0(…)success @ script.js:143i @ jquery-1.12.4.min.js:2fireWith @ jquery-1.12.4.min.js:2y @ jquery-1.12.4.min.js:4c @ jquery-1.12.4.min.js:4
                                                            Ругается вот на это: var $data = JSON.parse(data);
                                                            Код не менял, подскажите пожалуйста что сделать? Возможно это Denwer глючит?
                                                            1. Александр Мальцев # 0
                                                              Здравствуйте, Артем.
                                                              Такая ошибка говорит о том, что в процессе выполнения файла process.php возникает какая-то ошибка. Это приводит к тому, что не выполняется эта строчка:
                                                              echo json_encode($data);
                                                              
                                                              Т.е. мы не получаем ответ в формате json.
                                                              А JavaScript пытается разобрать то, что не является json. Поэтому он и «ругается» на эту строчку (var $data = JSON.parse(data)).
                                                              Вам необходимо посмотреть, какая возникает ошибка. Это можно, например, увидеть во вкладке Network панели разработчика браузера.

                                                              Надо пробовать на реальном сайте. В Denwer форма может не работать.
                                                              1. Артем # 0
                                                                Спасибо за ответ, но к сожалению все равно не работает. Запустил на хостинге.
                                                                Вот что говорит хром:
                                                                Request URL:http://1.u0154129.z8.ru/process.php
                                                                Request Method:POST
                                                                Status Code:500 Internal Server Error
                                                                Remote Address:80.93.62.153:80
                                                                ___________________________________
                                                                Connection:keep-alive
                                                                Content-Length:0
                                                                Content-Type:text/html
                                                                Date:Sat, 26 Nov 2016 10:55:12 GMT
                                                                Server:nginx/1.0.13
                                                                X-Powered-By:PHP/5.2.17
                                                                ___________________________________
                                                                Accept:*/*
                                                                Accept-Encoding:gzip, deflate
                                                                Accept-Language:ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4
                                                                Connection:keep-alive
                                                                Content-Length:1703
                                                                Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryNxsY49TtVGXm8BN4
                                                                Host:1.u0154129.z8.ru
                                                                Origin:http://1.u0154129.z8.ru
                                                                Referer:http://1.u0154129.z8.ru/
                                                                User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36
                                                                X-Requested-With:XMLHttpRequest
                                                                _________________________________________
                                                                ------WebKitFormBoundaryNxsY49TtVGXm8BN4
                                                                Content-Disposition: form-data; name=«name»

                                                                Иванов Иван Иванович
                                                                ------WebKitFormBoundaryNxsY49TtVGXm8BN4
                                                                Content-Disposition: form-data; name=«email»

                                                                ivan@ya.ru
                                                                ------WebKitFormBoundaryNxsY49TtVGXm8BN4
                                                                Content-Disposition: form-data; name=«message»

                                                                ddddddddddddddddddddddddddddddddddddddddddddddddddddd
                                                                ------WebKitFormBoundaryNxsY49TtVGXm8BN4
                                                                Content-Disposition: form-data; name=«phone»

                                                                +7 (920) 111-84-84
                                                                ------WebKitFormBoundaryNxsY49TtVGXm8BN4
                                                                Content-Disposition: form-data; name=«siteurl»

                                                                yandex.ru/
                                                                ------WebKitFormBoundaryNxsY49TtVGXm8BN4
                                                                Content-Disposition: form-data; name=«g-recaptcha-response»

                                                                03AHJ_VutRCRkrHFIns2gNeWUnuH6LlwwIPQyU0hjbe84chAWOZ7SK82bnkMaD_OAWEGpZpT_CRwKipqWoZHjRqfZwaEBQ4BE42YrWy9bd6Cztqkkz8RQN0MuTi3dUNtmRwmwOvesBkRFVse44Ra1TKmf7R_Rxl0CVJbQeUh05FDAd7Kim8pSVhP4nqUKhZyMzBs5cWUbyWNcUgHzhrLcFFmVM-GGyYNl6voK3_jT0Dzk2fmudbrRYZe-9EI_BOVw7lDtlaClLfELLGodzGk0RiVQb2rFgf98G35aPSijnqjaQV9TvjQPMvbYGKvjtpxx1kHRKRgqwatwynovJSsrwX2F3_XbYQr5l7wnaj3fRDYhLTdgJ4bXuZePwLhftK6VY-lNu60YQ5bsTDSkqDwOIQW3bbjDutcwCFWWh8Rv4yyQuH8eA19OiRYkz_N-_06SVO_rmhOMgipu1IQJ8yTp3m8Jfs8kpI4RBQNKI9wZxFaRMSXGf7vFCFZKe03bz6bIcXzceZRjxiW-s-1o-jYR9YvCifZ6BJ76DxIu8lkHywv4J0tFdRb1NoDQFmUtvrvOM-61aCEQDjCL6xFKgW0LqUWruZh2CMAGhyao8nJZnZIw9hySYUk2ejhcW5KNfxbMCEACX9TtiuHLfgDNr9P0Vg6A4oVvSKYsxO7VjmPZJGYRY4G2pW3tRtGlWNPbg2yRcYUT1QNls0-qj7N2EJRtglkOdVOz8gLk2m7BmTGwsh5uyw4plszexm1eFOzvTslbCJscWFC2bac3okp-3cCSGWwq5sBAnjpGOtIuEK6mC_bVxV9EC8mQFHFo1p9YE-3cNflkqe1Eg4wMIzBYfp5FI-wxLa-2y-trai5CWySacPQ9VLKXKUw3eXLgbjCZGxJ2OUERfPfCi68FoQjqzlmu88unbhEwaZAREi54fH6Ha4PTzseq_PzBDwlQ
                                                                ------WebKitFormBoundaryNxsY49TtVGXm8BN4--





                                                                В php я валенок, если окажите помощь, буду вам очень благодарен.
                                                                1. Александр Мальцев # 0
                                                                  По умолчанию эту форму необходимо поместить в каталог feedback на сервере или правильно настроить пути. Также стоит обратить внимание на версию php. Для работы php библиотеки Google reCapctha необходим php >= 5.3.2, а у вас установлен 5.2.17. При возникновении ошибки 500, желательно читать информацию из файла, в который записывает лог ошибок сервера.
                                                                  1. Артем # 0
                                                                    Спасибо большое.
                                                                    1. Артем # 0
                                                                      Александр, спасибо Вам, все заработало.
                                                                      Есть к Вам просьба, добавить несколько полей для заполнения в форму. Пробовал сделать сам, но не получилось, (выдает ошибку отправки формы на сервер)
                                                                      Если Вам не сложно помогите пожалуйста, нужны следующие поля: Имя, маил, №тел, Название организации, Тема, сообщение.

                                                                      Зарание спасибо.
                                                                      1. Александр Мальцев # 0
                                                                        Этот момент уже обсуждался не раз, наиболее просто это сделать так:
                                                                        1. Открыть файл script.js, найти в нём строчку
                                                                        $.ajax({
                                                                        
                                                                        и добавить перед ней необходимые поля в объект formData следующим образом:
                                                                        formData.append('имя_поля', $("#id_поля").val());
                                                                        
                                                                        'имя_поля' — это некоторое имя, которое затем на сервере можно будет получить так:
                                                                        $_POST['имя_поля']
                                                                        2. В файле process.php добавить переданные значения в тело письма (но при этом необходимо проверить, есть ли в массиве $_POST указанное имя):
                                                                        $output .= "Сообщение: " . $message . "\n";
                                                                        // дублируем этот блок столько раз, сколько необходимо полей добавить к телу письма
                                                                        if (isset($_POST['имя_поля'])) {
                                                                          $output .= "Имя_поля: " . $_POST['имя_поля'] . "\n";
                                                                        }
                                                                        
                                                              2. Дмитрий # 0
                                                                Александр, добрый день.
                                                                Существуют ли какие-либо «подводные камни» при установке recaptcha взамен ранее использовавшейся? Попытались решить вопрос с заменой капчи «наскоком» получили форму, которая отправляет сообщение независимо от результата обработки recaptcha.

                                                                Подозреваю, что нам надо правильно разместить и прописать у себя файлы process.php и autoload.php. Возможно что-то еще.

                                                                Заранее спасибо.

                                                                С уважением,
                                                                Дмитрий
                                                                1. Александр Мальцев # 0
                                                                  Здравствуйте, Дмитрий.
                                                                  Наверно что-то не так настроили. reCaptcha — это надёжная капча и проблем с обработкой её результатов не должно быть.

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