Форма обратной связи с использованием ajax, php и bootstrap

Форма обратной связи с использованием ajax, php и bootstrap
Содержание:
  1. Загрузка формы обратной связи
  2. Файловая структура формы обратной связи
  3. Установка формы обратной связи
  4. Как осуществляется валидация формы
  5. Описание формы обратной связи
  6. Код формы обратной связи
  7. Как удалить из формы капчу и пользовательское соглашение
  8. Настройка process.php (почта, капча и др.)
  9. Комментарии

Статья, в которой рассмотрим, как создать форму обратной связи для сайта, используя JavaScript, AJAX, популярный фронтенд фреймворк Bootstrap и PHP. Форма будет работать без перезагрузки страницы. Введённые данные будут отправляться на почту (email).

Загрузка формы обратной связи

Проект по созданию формы обратной связи (для Bootstrap 4) находится на гитхабе по адресу: https://github.com/itchief/simple-feedback-form.

Скачать эту форму можно также с Яндекс Диска по этому URL. Распространяется данная форма под лицензией MIT.

Демо формы обратной связи

Предыдущая версия AJAX формы обратной связи (для Bootstrap 3) доступна по этой ссылке.

Более сложные варианты форм обратной связи:

Файловая структура формы обратной связи

Форма обратной связи имеет следующую структуру:

feedback/
├── captcha/
│   ├── captcha.php
│   ├── oswald.ttf
│   └── background.png
├── css/
│   └── main.css
├── js/
│    ├── main.js
│    └── process-forms.js
├── logs/
│   ├── .htaccess
│   └── logs.txt
├── phpmailer/
│    └── ...
├── process/
│   ├── email.tpl
│   ├── email_client.tpl
│   └── process.php
├── vendors/
│   ├── bootstrap
│   └── jquery
└── index.html

Назначение файлов:

  • captcha.php - скрипт на языке php для генерации капчи;
  • oswald.ttf - шрифт, которой будет использоваться для вывода кода капчи на изображении;
  • background.png - фон, на который будет «накладываться» код капчи;
  • main.css - стили (не Bootstrap) для формы обратной связи;
  • main.js - скрипт, выполняющий инициализацию формы обратной связи;
  • process-forms.js - скрипт, обеспечивающий логику работы формы обратной связи на клиенте (в браузере);
  • logs.txt - текстовый файл, в который будет записываться лог после отправки формы обратной связи;
  • phpmailer - php-библиотека, которую будем использовать для отправки email-сообщений;
  • email.tpl - шаблон email-письма для получателя;
  • email_client.tpl - шаблон email-письма для отправителя;
  • process.php - скрипт, посредством которого будем обрабатывать форму на сервере;
  • index.html - HTML-документ, содержащий форму обратной связи;

В каталоге vendors расположены фреймворк Bootstrap и библиотека jQuery.

Установка формы обратной связи

По умолчанию контактная форма (папка feedback вместе со всем содержимым) должна быть помещена в корневую директорию сайта. Т.е. путь к файлу index.html должен быть таким:

/feedback/index.html

В проекте используются абсолютные пути к файлам. Это позволяет установить форму обратной связи очень просто, путём простого копирования HTML формы из файла index.html в любое место необходимой страницы сайта.

Настройка файлов при изменении структуры

Если нужно модифицировать структуру формы обратной связи, т.е. изменить расположение файлов, то в этом случае потребуется откорректировать пути в файлах index.html (или там где расположена форма) и process.php. Рассмотрим, как это выполнить более подробно.

Настройка путей к файлам в index.html

В файле index.html путь к php-обработчику формы задаётся с помощью атрибута формы action. Если обработчик перенесён в другое место, то значение данного атрибута необходимо изменить.

<form id="feedbackForm" action="/feedback/process/process.php" novalidate>

В файле index.html ещё устанавливается путь к капче. Если она расположена не по адресу /feedback/captcha/captcha.php, то значения атрибутов src и data-src необходимо откорректировать.

<img class="img-captcha" src="/feedback/captcha/captcha.php" data-src="/feedback/captcha/captcha.php">

Кроме этого к странице, в которой будет использоваться форма, должны быть подключены фреймворк Bootstrap 4 (bootstrap.js, bootstrap.css), библиотека jQuery (jquery.js) и скрипт process-forms.js.

...
<link rel="stylesheet" href="/feedback/vendors/bootstrap/css/bootstrap.min.css">
...
<script src="/feedback/vendors/jquery/jquery-3.3.1.min.js"></script>
<script src="/feedback/vendors/bootstrap/js/bootstrap.min.js"></script>
<script src="/feedback/js/process-forms.js"></script>

Инициализация формы выполняется следующим образом (в проекте для этой цели используется файл main.js):

//после загрузки DOM
$(function () {
  var form1 = feedbackForm();
  form1.init({
    id: '#feedbackForm'
  });
});

Настройка путей к файлам в process.php

В файле process.php для отправки писем используется библиотка PHPMailer. При модификации структуры проекта проверьте и при необходимости откорректируйте путь к этой библиотеки (PHPMailer), а также ещё к файлу logs.txt.

Как осуществляется валидация формы

В данной форме валидация осуществляется как на клиенте, так и на сервере.

Скриншот формы с ошибками валидации:

Форма обратной связи - Пример вывод ошибок валидации

На клиенте она осуществляется посредством механизма встроенным в браузер, в связи с этим текст сообщений может немного отличаться.

Установка требований к полям формы обратной связи определяется с помощью атрибутов type, required, minlength, maxlength, pattern и др.

Например, требование к полю name в данном проекте:

<!-- required="required" - обязательное поле -->
<!-- minlength="2" - количество символов не меньше 2 -->
<!-- maxlength="2" - количество символов не больше 30 -->
<input id="name" type="text" name="name" class="form-control" value="" placeholder="Имя" minlength="2" maxlength="30" required="required">

На сервере валидация данных формы осуществляется в файле process.php.

Например, валидация поля name осуществляется с помощью следующего php-кода:

if (isset($_POST['name'])) {
  $name = filter_var($_POST['name'], FILTER_SANITIZE_STRING); // защита от XSS
  $nameLength = mb_strlen($name, 'UTF-8');
  if ($nameLength < 2) {
    $data['name'] = 'Текст должен быть не короче 2 симв. Длина текста сейчас: '. $nameLength .' симв.';
    $data['result'] = 'error';
  } else if ($nameLength > 30) {
    $data['name'] = 'Длина текста не должна превышать 30 симв. (сейчас '. $nameLength .' симв.).';
    $data['result'] = 'error';
  }
} else {
  $data['name'] = 'Заполните это поле.';
  $data['result'] = 'error';
}

Описание формы обратной связи

Скриншот формы:

HTML дизайн формы обратной связи

Форма по умолчанию состоит из трёх основных полей (имени, email-адреса, сообщения), капчи, чекбокса и кнопки "Отправить сообщение".

При необходимости изображение, содержащее код капчи можно обновить (осуществить генерацию нового кода). Выполняется это действие посредством нажатия на соответствующую кнопку в форме.

После заполнения полей формы пользователь может с помощью соответствующей кнопки её отправить на сервер.

Отправка данных на сервер выполняется с помощью JavaScript (AJAX). Но перед тем как их передать серверу по технологии AJAX, он должен их проверить на корректность.

Все действия по обработке формы в браузере, а также обновление страницы после получения ответа от сервера выполняет код JavaScript, находящийся в файле process-forms.js.

Инициализация работы этого скрипта (process-forms.js) осуществляется с помощью кода расположенного в файле main.js.

Основные действия, которые выполняет сценарий JavaScript, расположенный в файле process-forms.js:

  • обновление кода капчи, посредством изменения атрибута src у изображения;
  • валидацию (проверку) полей формы перед отправкой их на сервер;
  • отправку данных формы на сервер методом POST по технологии AJAX;
  • получения ответа от сервера и отображения его результатов на странице;

После отправки формы на сервер, она передаётся для обработки файлу process.php.

Данный файл (process.php) выполняет следующие основные действия:

  • получение данных с отправленной формы;
  • проверку данных формы (полей, капчи) и формирования ассоциативного массива с результатами проверки;
  • в случае успеха проверки даных - отправка email письма получателю и отправителю;
  • отправка JSON ответа веб-браузеру с результатами.

Скриншот формы при её успешной отправки:

Скриншот формы обратной связи при успешной отправки

Принцип работы формы обратной связи представлен на схеме.

Принцип работы формы обратной связи

Код формы обратной связи

HTML код формы обратной связи (файл index.html):

Показать или скрыть код

<div class="card mx-auto mb-4 rounded-0" style="max-width: 35rem;">
  <div class="card-body position-relative">

    <!-- Форма обратной связи -->
    <form id="feedbackForm" action="/feedback/process/process.php" novalidate>
      <div class="form-row">
        <div class="col-sm-6">
          <!-- Имя пользователя -->
          <div class="form-group">
            <label for="name" class="control-label">Имя</label>
            <input id="name" type="text" name="name" class="form-control" value="" placeholder="Имя" minlength="2" maxlength="30" required="required">
            <div class="invalid-feedback"></div>
          </div>
        </div>
        <div class="col-sm-6">
          <!-- Email пользователя -->
          <div class="form-group">
            <label for="email" class="control-label">Email-адрес</label>
            <input id="email" type="email" name="email" required="required" class="form-control" value="" placeholder="Email-адрес">
            <div class="invalid-feedback"></div>
          </div>
        </div>
      </div>
      <!-- Сообщение пользователя -->
      <div class="form-group">
        <label for="message" class="control-label">Сообщение (не менее 20 символов)</label>
        <textarea id="message" name="message" class="form-control" rows="3" placeholder="Сообщение (не менее 20 символов)" minlength="20"
          maxlength="500" required="required"></textarea>
        <div class="invalid-feedback"></div>
      </div>
      <!-- Капча -->
      <div class="form-group captcha">
        <img class="img-captcha" src="/feedback/captcha/captcha.php" data-src="/feedback/captcha/captcha.php">
        <div class="btn btn-light position-relative refresh-captcha">Обновить</div>
        <div class="form-group">
          <label for="captcha" class="control-label">Код, показанный на изображении</label>
          <input type="text" name="captcha" maxlength="6" required="required" id="captcha" class="form-control captcha" placeholder="******"
            autocomplete="off" value="">
          <div class="invalid-feedback"></div>
        </div>
      </div>
      <!-- Пользовательское солашение -->
      <div class="form-group agreement">
        <div class="custom-control custom-checkbox">
          <input type="checkbox" name="agree" class="custom-control-input" id="customCheck">
          <label class="custom-control-label" for="customCheck">Нажимая кнопку, я принимаю условия
            <a href="#">Пользовательского соглашения</a> и даю своё согласие на обработку моих персональных данных, в соответствии
            с Федеральным законом от 27.07.2006 года №152-ФЗ «О персональных данных».</label>
        </div>
      </div>
      <!-- Сообщение при ошибке -->
      <div class="alert alert-danger form-error d-none">
        Исправьте данные и отправьте форму ещё раз.
      </div>
      <!-- Кнопка для отправки формы -->
      <div class="text-right submit">
        <button type="submit" class="btn btn-primary position-relative" disabled="disabled">Отправить сообщение</button>
      </div>
    </form>

    <!-- Сообщение об успешной отправки формы -->
    <div class="form-result-success d-none text-center justify-content-center align-items-center" style="position: absolute;
    top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,.6); color: #fff; font-size: 1.25rem;">
      <div class="alert alert-success rounded-0">Форма успешно отправлена. Нажмите на
        <a class="alert-link" href="#" data-reloadform="#feedbackForm">ссылку</a>, чтобы отправить ещё одно сообщение.</div>
    </div>

  </div>
</div>

JavaScript код (файл process-forms.js):

Показать или скрыть код

'use strict';
var feedbackForm = (function () {
  // переключить во включенное или выключенное состояние кнопку submit
  var _changeStateSubmit = function (element, state) {
    $(element)
      .closest('form')
      .find('[type="submit"]').prop('disabled', state);
  };
  // изменение состояния кнопки submit в зависимости от состояния checkbox agree
  var _changeAgreement = function (element) {
    _changeStateSubmit(element, !element.checked);
  };
  // обновление капчи
  var _refreshCaptcha = function (form) {
    var
      captchaImg = form.find('.img-captcha'),
      captchaSrc = captchaImg.attr('data-src'),
      captchaPrefix = captchaSrc.indexOf('?id') !== -1 ? '&rnd=' : '?rnd=',
      captchaNewSrc = captchaSrc + captchaPrefix + (new Date()).getTime();
    captchaImg.attr('src', captchaNewSrc);
  };
  // изменение состояния элемента формы (success, error, clear)
  var _setStateValidaion = function (input, state, message) {
    input = $(input);
    if (state === 'error') {
      input
        .removeClass('is-valid').addClass('is-invalid')
        .siblings('.invalid-feedback').text(message);
    } else if (state === 'success') {
      input.removeClass('is-invalid').addClass('is-valid');
    } else {
      input.removeClass('is-valid is-invalid');
    }
  };
  // валилация формы
  var _validateForm = function (_$form) {
    var valid = true;
    _$form.find('input,textarea').not('[type="file"],[name="agree"]').each(function () {
      if (this.checkValidity()) {
        _setStateValidaion(this, 'success');
      } else {
        _setStateValidaion(this, 'error', this.validationMessage);
        valid = false;
      }
    });
    return valid;
  };
  var _showForm = function (form, _isCaptcha, _isAgreeCheckbox) {
    if (!form.find('.form-error').hasClass('d-none')) {
      form.find('.form-error').addClass('d-none');
    }
    form.siblings('.form-result-success').addClass('d-none').removeClass('d-flex');
    form[0].reset();
    form.find('input,textarea').each(function () {
      _setStateValidaion(this, 'clear');
    });
    if (_isCaptcha) {
      _refreshCaptcha(form);
    }
    if (_isAgreeCheckbox) {
      _changeStateSubmit(form, true);
    }
  };

  return function () {
    var _defaults = {
      id: '#feedbackForm' // id формы обратной связи
    }
    var
      _form = $(_defaults.id)[0], // форма обратной связи
      _$form = $(_form),
      _action = $(_form).attr('action'),
      _isCaptcha = false,  // имеется ли у формы секция captcha
      _isAgreeCheckbox = false; // имеется ли у формы секция agreement

    // собираем данные для отправки на сервер
    var _collectData = function () {
      var data = new FormData(_form);
      return data;
    };

    // отправка формы
    var _sendForm = function (e) {
      e.preventDefault();
      if (!_validateForm(_$form)) {
        if (_$form.find('.is-invalid').length > 0) {
          _$form.find('.is-invalid')[0].focus();
        }
        return;
      }
      var request = $.ajax({
        type: "POST",
        url: _action,
        data: _collectData(), // данные для отправки на сервер
        contentType: false,
        processData: false,
        cache: false,
        beforeSend: function () {
          _changeStateSubmit(_$form, true);
        }
      })
        .done(_success)
        .fail(_error)
    };
    var _success = function (data) {
      // при успешной отправки формы
      if (data.result === "success") {
        _$form.parent().find('.form-result-success')
          .removeClass('d-none')
          .addClass('d-flex');
        return;
      }
      // если произошли ошибки при отправке
      _$form.find('.form-error').removeClass('d-none');
      _changeStateSubmit(_$form, false);
      // сбрасываем состояние всех input и textarea элементов
      _$form.find('input,textarea').not('[type="file"],[name="agree"]').each(function () {
        _setStateValidaion(this, 'clear');
      });
      // выводим ошибки которые прислал сервер
      for (var error in data) {
        if (!data.hasOwnProperty(error)) {
          continue;
        };
        switch (error) {
          case 'captcha':
            _refreshCaptcha(_$form);
            _setStateValidaion(_$form.find('[name="' + error + '"]'), 'error', data[error]);
            break;
          case 'log':
            $.each(data[error], function (key, value) {
              console.log(value);
            });
            break;
          default:
            _setStateValidaion(_$form.find('[name="' + error + '"]'), 'error', data[error]);
        }
        // устанавливаем фокус на 1 невалидный элемент
        if (_$form.find('.is-invalid').length > 0) {
          _$form.find('.is-invalid')[0].focus();
        }
      }
    };
    var _error = function (request) {
      _$form.find('.form-error').removeClass('d-none');
    };

    // устанавливаем обработчики событий
    var _setupListener = function () {
      $(document).on('change', _defaults.id + ' [name="agree"]', function () {
        _changeAgreement(this);
      });
      $(document).on('submit', _defaults.id, _sendForm);
      $(document).on('click', _defaults.id + ' .refresh-captcha', function (e) {
        e.preventDefault();
        _refreshCaptcha(_$form);
      });
      $(document).on('click', '[data-reloadform="' + _defaults.id + '"]', function (e) {
        e.preventDefault();
        _showForm(_$form, _isCaptcha, _isAgreeCheckbox);
      });
    }

    return {
      init: function (config) {
        _isCaptcha = _$form.find('.captcha').length > 0; // имеется ли у формы секция captcha
        _isAgreeCheckbox = _$form.find('.agreement').length > 0; // имеется ли у формы секция agreement
        $.each(config, function (key, value) {
          _defaults[key] = value;
        });
        _setupListener();
      }
    };
  }
})();

PHP код для формирование изображения, содержащего код капчи (файл captcha.php):

Показать или скрыть код

<?php
session_start();
$id = 'captcha';
if (isset($_GET['id'])) {
  $id = filter_var($_GET['id'], FILTER_SANITIZE_STRING);
}
$captchastring = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz';
$captchastring = substr(str_shuffle($captchastring), 0, 6);
$_SESSION[$id] = $captchastring;
$image = imagecreatefrompng(dirname(__FILE__) . '/background.png');
$colour = imagecolorallocate($image, 200, 240, 240);
$font = dirname(__FILE__) . '/oswald.ttf';
$rotate = rand(-10, 10);
imagettftext($image, 18, $rotate, 28, 32, $colour, $font, $captchastring);
header('Content-type: image/png');
imagepng($image);

PHP код, который выполняет обработку формы обратной связи на сервере (файл process.php):

Показать или скрыть код

<?php
header('Content-Type: application/json');
// обработка только ajax запросов (при других запросах завершаем выполнение скрипта)
if (empty($_SERVER['HTTP_X_REQUESTED_WITH']) || $_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest') {
  exit();
}
// обработка данных, посланных только методом POST (при остальных методах завершаем выполнение скрипта)
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
  exit();
}
/* 1 ЭТАП - НАСТРОЙКА ПЕРЕМЕННЫХ */
const
  IS_CHECK_CAPTCHA = true, // проверять капчу
  IS_SEND_MAIL = true, // отправлять письмо получателю
  IS_SEND_MAIL_SENDER = false, // отправлять информационное письмо отправителю
  IS_WRITE_LOG = true, // записывать данные в лог
  MAIL_FROM = 'no-reply@mydomain.ru', // от какого email будет отправляться письмо
  MAIL_FROM_NAME = 'Имя_сайта', // от какого имени будет отправляться письмо
  MAIL_SUBJECT = 'Сообщение с формы обратной связи', // тема письма
  MAIL_ADDRESS = 'manager@mydomain.ru', // кому необходимо отправить письмо
  MAIL_SUBJECT_CLIENT = 'Ваше сообщение доставлено'; // настройки mail для информирования пользователя о доставке сообщения
// 2 ЭТАП - ПОДКЛЮЧЕНИЕ PHPMAILER
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require_once('../phpmailer/src/Exception.php');
require_once('../phpmailer/src/PHPMailer.php');
require_once('../phpmailer/src/SMTP.php');
// 3 ЭТАП - ОТКРЫТИЕ СЕССИИ И ИНИЦИАЛИЗАЦИЯ ПЕРЕМЕННОЙ ДЛЯ ХРАНЕНИЯ РЕЗУЛЬТАТОВ ОБРАБОТКИ ФОРМЫ
session_start();
$data['result'] = 'success';
/* 4 ЭТАП - ВАЛИДАЦИЯ ДАННЫХ (ЗНАЧЕНИЙ ПОЛЕЙ ФОРМЫ) */
// проверка поля name
if (isset($_POST['name'])) {
  $name = filter_var($_POST['name'], FILTER_SANITIZE_STRING); // защита от XSS
  $nameLength = mb_strlen($name, 'UTF-8');
  if ($nameLength < 2) {
    $data['name'] = 'Текст должен быть не короче 2 симв. Длина текста сейчас: '. $nameLength .' симв.';
    $data['result'] = 'error';
  } else if ($nameLength > 30) {
    $data['name'] = 'Длина текста не должна превышать 30 симв. (сейчас '. $nameLength .' симв.).';
    $data['result'] = 'error';
  }
} else {
  $data['name'] = 'Заполните это поле.';
  $data['result'] = 'error';
}
// проверка поля email
if (isset($_POST['email'])) {
  if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) { // защита от XSS
    $data['email'] = 'Адрес электронной почты не корректный';
    $data['result'] = 'error';
  } else {
    $email = $_POST['email'];
  }
} else {
  $data['email'] = 'Заполните это поле.';
  $data['result'] = 'error';
}
// проверка поля message
if (isset($_POST['message'])) {
  $message = filter_var($_POST['message'], FILTER_SANITIZE_STRING); // защита от XSS
  $messageLength = mb_strlen($message, 'UTF-8');
  if ($messageLength < 20) {
    $data['message'] = 'Текст должен быть не короче 20 симв. Длина текста сейчас: '. $messageLength .' симв.';
    $data['result'] = 'error';
  } else if ($messageLength > 500) {
    $data['message'] = 'Длина текста не должна превышать 500 симв. (сейчас '. $messageLength .' симв.)';
    $data['result'] = 'error';
  }
} else {
  $data['message'] = 'Заполните это поле.';
  $data['result'] = 'error';
}
/* 5 ЭТАП - ПРОВЕРКА КАПЧИ */
if (IS_CHECK_CAPTCHA == true) {
  if (isset($_POST['captcha']) && isset($_SESSION['captcha'])) {
    $captcha = filter_var($_POST['captcha'], FILTER_SANITIZE_STRING); // защита от XSS
    if ($_SESSION['captcha'] != $captcha) { // проверка капчи
      $data['captcha'] = 'Код не соответствует изображению.';
      $data['result'] = 'error';
    }
  } else {
    $data['captcha'] = 'Ошибка при проверке кода';
    $data['result'] = 'error';
  }
}
/* 6 ЭТАП - ОТПРАВКА ПИСЬМА ПОЛУЧАТЕЛЮ */
if ($data['result'] == 'success' && IS_SEND_MAIL == true) {
  // получаем содержимое email шаблона
  $bodyMail = file_get_contents('email.tpl');
  // выполняем замену плейсхолдеров реальными значениями
  $bodyMail = str_replace('%email.title%', MAIL_SUBJECT, $bodyMail);
  $bodyMail = str_replace('%email.nameuser%', isset($name) ? $name : '-', $bodyMail);
  $bodyMail = str_replace('%email.message%', isset($message) ? $message : '-', $bodyMail);
  $bodyMail = str_replace('%email.emailuser%', isset($email) ? $email : '-', $bodyMail);
  $bodyMail = str_replace('%email.date%', date('d.m.Y H:i'), $bodyMail);
  // устанавливаем параметры
    $mail = new PHPMailer;
    $mail->CharSet = 'UTF-8';
    $mail->IsHTML(true);
    $fromName = '=?UTF-8?B?'.base64_encode(MAIL_FROM_NAME).'?=';
    $mail->setFrom(MAIL_FROM, $fromName);
    $mail->Subject = '=?UTF-8?B?'.base64_encode(MAIL_SUBJECT).'?=';
    $mail->Body = $bodyMail;
    $mail->addAddress(MAIL_ADDRESS);
    // отправляем письмо
    if (!$mail->send()) {
      $data['result'] = 'error';
    }
}
/* 7 ЭТАП - ОТПРАВКА ИНФОРМАЦИОННОГО ПИСЬМА ОТПРАВИТЕЛЮ */
if ($data['result'] == 'success' && IS_SEND_MAIL_SENDER == true) {
  try {
    // очистка всех адресов и прикреплёных файлов
    $mail->clearAllRecipients();
    $mail->clearAttachments();
    // получаем содержимое email шаблона
    $bodyMail = file_get_contents('email_client.tpl');
    // выполняем замену плейсхолдеров реальными значениями
    $bodyMail = str_replace('%email.title%', MAIL_SUBJECT, $bodyMail);
    $bodyMail = str_replace('%email.nameuser%', isset($name) ? $name : '-', $bodyMail);
    $bodyMail = str_replace('%email.date%', date('d.m.Y H:i'), $bodyMail);
    // устанавливаем параметры
    $mail->Subject = MAIL_SUBJECT_CLIENT;
    $mail->Body = $bodyMail;
    $mail->addAddress($email);
    // отправляем письмо
    $mail->send();
  } catch(Exception $e) {

  }
}
/* 8 ЭТАП - ЗАПИСЫВАЕМ ДАННЫЕ В ЛОГ */
if ($data['result'] == 'success' && IS_WRITE_LOG) {
  try {
    $name = isset($name) ? $name : '-';
    $email = isset($email) ? $email : '-';
    $message = isset($message) ? $message : '-';
    $output = "---------------------------------" . "\n";
    $output .= date("d-m-Y H:i:s") . "\n";
    $output .= "Имя пользователя: " . $name . "\n";
    $output .= "Адрес email: " . $email . "\n";
    $output .= "Сообщение: " . $message . "\n";
    file_put_contents(dirname(dirname(__FILE__)) . '/logs/logs.txt', $output, FILE_APPEND | LOCK_EX);
  } catch(Exception $e) {

  }
}
/* ФИНАЛЬНЫЙ ЭТАП - ВОЗВРАЩАЕМ РЕЗУЛЬТАТЫ РАБОТЫ */
echo json_encode($data);

Как удалить из формы капчу и пользовательское соглашение

Для удаления капчи из формы достаточно выполнить 2 действия:

  • удалить блок "Капча" из HTML-формы;
  • установить константе IS_CHECK_CAPTCHA в файле process.php значение false.

Для удаления пользовательского соглашения из формы достаточно его удалить из HTML-формы обратной связи.

Настройка process.php (почта, капча и др.)

Настройка формы на стороне сервера осуществляется посредством редактирования значений констант в файле process.php:

const
  IS_CHECK_CAPTCHA = true, // проверять капчу
  IS_SEND_MAIL = true, // отправлять письмо получателю
  IS_SEND_MAIL_SENDER = false, // отправлять информационное письмо отправителю
  IS_WRITE_LOG = true, // записывать данные в лог
  MAIL_FROM = 'no-reply@mydomain.ru', // от какого email будет отправляться письмо
  MAIL_FROM_NAME = 'Имя_сайта', // от какого имени будет отправляться письмо
  MAIL_SUBJECT = 'Сообщение с формы обратной связи', // тема письма
  MAIL_ADDRESS = 'manager@mydomain.ru', // кому необходимо отправить письмо
  MAIL_SUBJECT_CLIENT = 'Ваше сообщение доставлено'; // настройки mail для информирования пользователя о доставке сообщения

Для отправки сообщений библиотека PHPMailer использует php-функцию mail(). Поэтому убедитесь в том, она поддерживается тарифным планом хостинга и включена в настройках.

Если сообщения отправлять на почту не нужно, то константам IS_SEND_MAIL и IS_SEND_MAIL_SENDER необходимо установить значение false.

Комментарии: 330

SomMD
SomMD
Добрый день!
Пытаюсь прикрутить invisible reCAPTCHA к форме и постоянно выходит ошибка в консоли validateForm is not defined
Можете помочь в какую сторону копать? Без каптчи форма отлично и корректно работает.
itchief.ru/assets/uploadify/e/e/d/eed1db8ffbfc79987631e26fb747a41f.png
chuk
chuk
Здравствуйте!

Крутая форма, все что нужно и загрузка файлов и защита от спама (капча).
Вот только столкнулся с проблемой, форма проходит валидацию, но потом process.php зависает статус (pending) и через 3 минуты статус 504.

Посмотреть можно тут: vakarchuk.pro/feedback/

Настройки process.php проверял пару раз, указывал и Google и Yandex аккаунт внутри аккаунтов тоже все активировал (двухфакторуню откл., IMAP\POP вкл.) не хочет отправлять и все тут :(

Подскажите пожалуйста в чем проблема, куда копать?
chuk
chuk
Проблема точно в подключении!
В лог все пишет, в папку файлы загружает, но отправлять не хочет письма :(

Как решить-то? Что не так с настройками SMTP?
Перековырял все в настройках почтовика, проверил логины и пароли, ничего не помогло.

Может кто другой почтовик указывал? Рамблер или от хостинга?
Александр Мальцев
Александр Мальцев
Привет! В коде отправка письма настроена без использования SMTP. Это нужно дополнительно прописать. Если необходимо, то могу это сделать.
K Bel
K Bel
Здравствуйте!

Форма отрабатывает, process.php возвращает success, а затем происходит странное.
Не хочет отрабатывать код, оповещающий об успешной отправке формы:
// при успешной отправке формы
        if (data.result === "success") {
            $(this).parent().find('.form-result-success')
                .removeClass('d-none')
		.addClass('d-flex');
		alert('Работает');
            return;
        }
Специально добавленный alert работает, а .removeClass .addClass — нет.
В коде <div class=«form-result-success d-none text-center… не происходит никаких изменений.

Я в недоумении, что это может быть?
Александр Мальцев
Александр Мальцев
Проверьте, имеется ли на странице (после формы) элемент с классом «form-result-success». Если нет, то просто добавьте его.
Павел
Павел
Добрый день! Установил вашу форму на свой сайт amigoschool.ru, но почему то она не работает. Не работает даже Ваша страница index из папки feedback.

amigoschool.ru/feedback/index.html
Может быть у меня сервер не поддерживает?
Александр Мальцев
Александр Мальцев
Добрый день! Что не работает?
Александр
Александр
Добрый день! Форма устанавливается, все заполняет, проверки проходит. Но пишет заполните настройки, больше не чего не куда не отправляет. Как правильно настроить данную форму, что и где вписать нужно для корректной работы?
Александр Мальцев
Александр Мальцев
Здравствуйте! Настройка выполняется в файле «process.php» посредством установки значений константам (все они расположены в начале и имеют комментарии, поясняющие их назначение).
Александр
Александр
Все заполнено, но все равно не хочет работать. Возможно что не так что то делаю?
Александр Мальцев
Александр Мальцев
Посмотрите, какой ответ вам присылает сервер на вкладке Network в инструментах разработчика браузера для «process.php».
Павел
Павел
Добрый день, Александр!

К сожалению, не получается установить вашу форму обратной связи, т.к. на сайте у меня возникает конфликт файлов. Как только подключаю bootstrap.min.css все мои стили на сайте рушатся, но ваша форма работает.

Подскажите, пожалуйста, как можно устранить данную проблему или скопировать отдельные стили?
Павел
Павел
проблему решил
Александр Мальцев
Александр Мальцев
Привет! Отлично!
Павел
Павел
никак не могу найти где изменить размер checkbox, почему то выводится очень маленький.
Александр Мальцев
Александр Мальцев
В этом случае лучше использовать кастомный чекбокс, который можно настроить так как нужно.
Другой вариант использовать scale:
<input type="checkbox" name="agree" class="custom-control-input" id="customCheck" style="transform: scale(1.5);">
Павел
Павел
Спасибо за ответ!
Но все же вопрос с конфликтом файлов bootstrap.min.css. Как только его подключаю все мои стили на странице рушатся, но ваша форма работает.

Подскажите, пожалуйста, как можно устранить данную проблему или скопировать отдельные стили?
Александр Мальцев
Александр Мальцев
Если вы сами пишите стили для сайта, то и для формы их нужно просто создать в своём CSS файле. Файл «bootstrap.min.css» в этом варианте, конечно, подключать не нужно.
Например, на этой странице форма имеет дизайн, выполненный без Bootstrap. Все её стили находятся в «style.css». Возьмите их за основу, а дальше доработайте под свой дизайн.
Павел
Павел
Подскажите, пожалуйста, вывод ошибки «Заполните это поле.» находится только в файле process.php или где то еще?

Просто я перевел текст на английский, но он все равно упорно выдает на русском. Уже и кэш почистил и другим браузером смотрел — не помогает.
Александр Мальцев
Александр Мальцев
Валидация полей сначала выполняется в браузере, а только потом уже на сервере. Сообщения в первом случае выводятся на языке, который у вас установлен в самом браузере. Валидация на сервере выполняется уже только после того, как она успешна завершилась на клиенте и данные с формы были отправлены.
Andre Voda
Andre Voda
Здравствуйте Александр! У меня есть input, управляемый такой конструкцией:
<div class="preference-quantity">
                                        <div class="counter js-counter">
                                            <div class="counter__item">
                                                <a class="counter__minus js-counter-btn fa fa-minus" aria-hidden="true" data-action="minus"></a>
                                            </div>
                                            <div class="counter__item counter__item--center">
                                                <input name="bathroom" id="bathroom" class="counter__value js-counter-value" type="text" value="1" disabled="disabled" tabindex="-1"  min="0" max="9"  required/>
                                                <div class="invalid-feedback"></div>
                                            </div>
                                            <div class="counter__item">
                                                <a class="counter__plus js-counter-btn fa fa-plus" aria-hidden="true" data-action="plus"></a>
                                            </div>
                                        </div>
                                    </div>
Соответственно, в момент, предшествующий отправке данных, атрибут disabled=«disabled» должен быть удалён. Подскажите пожалуйста, если не трудно, что и где надо сделать в вашем скрипте формы обратной связи? Спасибо.
Александр Мальцев
Александр Мальцев
Здравствуйте!
Вы сами же ответили на свой вопрос. Да, disabled нужно удалить перед тем, как собирать данные формы с помощью FormData.
Для этого вам нужно немного доработать функцию _collectData:
var _collectData = function (_this) {
  // удалить disabled у [name="bathroom"]
  $(_this).find('[name="bathroom"]').prop('disabled', false);
  // получить данные формы, используя FormData 
  var data = new FormData(_this);
  // обратно вернуть disabled элементу [name="bathroom"]
  $(_this).find('[name="bathroom"]').prop('disabled', true);  
  // вернуть данные формы
  return data;
};
Andre Voda
Andre Voda
Понял, спасибо! Получилось.
А объясните пожалуйста, что означают различия в строках:
new FormData(_this);
и
new FormData(_this._form[0]);
Спасибо.
Александр Мальцев
Александр Мальцев
Различия в них заключается в том, что хранится в _this. В первом случае — просто DOM элемент формы. Во втором объект, а в нём в свойстве _form[0] уже DOM элемент формы.
Вообще, в FormData вам нужно передать DOM-элемент <form>, с которого нужно собрать данные. _this — это просто переменная (в данном случае параметр функции). Что в ней находится зависит от того, что туда помещено.
Узнать, что находится в _this можно, например, посредством вывода её значения в консоль:
console.log(_this);
new FormData(_this);
Также посмотреть её значения можно посредством установки точки останова на этой строчке на вкладке Sources в инструментах разработчика браузера.
Andre Voda
Andre Voda
В общем, поторопился я сказать, что получилось.
Не могу объединить данные от data и данные от output.
Исходная функция выглядит так:

var _collectData = function (_this) {

        _changeStateImages(_this, true);
        var output = new FormData(_this._form[0]);
        _changeStateImages(_this, false);
        for (var i = 0, length = _this._attachmentsItems.length; i < length; i++) {
            output.append('attachment[]', _this._attachmentsItems[i].file);
        }
    
        return output;// вернуть данные формы
    };

Пробовал так и сяк…
var _collectData = function (_this) {
$(_this).find('[name="bathroom"]').prop('disabled', false);  
  var data = new FormData(_this);  
  $(_this).find('[name="bathroom"]').prop('disabled', true);

_changeStateImages(_this, true);
        var output = new FormData(_this._form[0]);
        _changeStateImages(_this, false);
        for (var i = 0, length = _this._attachmentsItems.length; i < length; i++) {
            output.append('attachment[]', _this._attachmentsItems[i].file);
        }
// такие варианты:
// return {data, output};
// return [data, output];
// return data.concat(output);
};
… и прочее… Во всех случаях передаётся только output. В иных вообще ничего…
Спасите!
Александр Мальцев
Александр Мальцев
Должно быть как-то так:
var _collectData = function (_this) {
  _changeStateImages(_this, true);
  // удалить disabled у [name="bathroom"]
  $(_this._form[0]).find('[name="bathroom"]').prop('disabled', false);
  var output = new FormData(_this._form[0]);
  // обратно вернуть disabled элементу [name="bathroom"]
  $(_this._form[0]).find('[name="bathroom"]').prop('disabled', true); 
  _changeStateImages(_this, false);
  for (var i = 0, length = _this._attachmentsItems.length; i < length; i++) {
    output.append('attachment[]', _this._attachmentsItems[i].file);
  }
  return output;// вернуть данные формы
};
Andre Voda
Andre Voda
Александр, снова здравствуйте. Помогите пожалуйста разобраться в причине такого поведения форм: Я установил форму в вашем стандартном шаблоне и она прекрасно работает в папке /feedback/. Потом я создал в основной директории файл /feedback.html и заполнил его из шаблона, удалил лишнее и подставил нужные теги из вашего файла index.html. Комбинируя css из шаблона и из формы, добился нужного внешнего вида, но работает она неправильно: валидация на стороне клиента не проходит. reekoff.ru/feedback.html
Скриншоты прилагаю.
Спасибо.
itchief.ru/assets/uploadify/1/1/8/1180b25587e773868c3dd0c26165a6ed.png
itchief.ru/assets/uploadify/1/c/b/1cbc48a5cc7f44842962ed5e5e5648bd.png
Александр Мальцев
Александр Мальцев
Здравствуйте!
Вы в CSS не всё добавили. По умолчанию элементы с классом «invalid-feedback» не должны отображаться. Их следует показывать только когда поле не прошло проверку:
.invalid-feedback {
  display: none;
}
.form-control.is-invalid ~ .invalid-feedback {
  display: block;
}
Andre Voda
Andre Voda
Александр, эти элементы имеются в файле css/attachments.css, который подключён к странице feedback.html.
Файл attachments.css — это копия css файла из формы, из которого я удалил элементы, отвечающие за форматирование страницы.
Не могу найти ошибку.
Andre Voda
Andre Voda
Нашёл, что мешает bootstrap.min.css (версия Bootstrap v4.0.0-beta). Когда его отключаю, формат слетает, но форма работает корректно.
В файле index.html, где исходный текст формы, bootstrap вообще не подключён.
Может быть у меня какая-то другая версия формы? Я скачал её из GitHub: feedbackForm-v.3.0.1. Написано, последняя версия.
Может быть у меня Bootstrap неправильный?
Andre Voda
Andre Voda
А при замене файла bootstrap.min.css на любую более свежую версию, пропадает отображение чекбокса здесь:
<div class="terms-reminder">
     <label class="custom-control custom-checkbox">
         <input type="checkbox" class="custom-control-input">
          <span class="custom-control-indicator"></span>
          <span class="custom-control-description">Бутстрап Чекбокс<a href="#">terms & conditions</a></span>
      </label>
</div>
Александр Мальцев
Александр Мальцев
Так эта версия без Bootstrap. Её стили находятся в в файле style.css. Её описание приведено на этой странице.
Andre Voda
Andre Voda
Спасибо, разобрался с этим.
Подскажите пожалуйста, как сделать чтобы после отправки данных формы, эти же данные дополнительно отображать на той-же странице, на которой находится форма?
Спасибо.
Александр Мальцев
Александр Мальцев
Вам необходимо закомментировать или удалить строчки кода, которые очищают значения полей формы. Они находятся в функции, которая вызывается после прохождения ответа от сервера:
var _success = function (data) {
  ...
};
Andre Voda
Andre Voda
Вы имеете ввиду строки
/* if (_this._settings.isUseDefaultSuccessMessage) {
_this._form.parent().find('.form-result-success')
.removeClass('d-none')
.addClass('d-flex');
}
*/
Они просто оставят все строки формы заполненными, я хотел чтобы данные как бы параллельно уходили и в action=«feedback/process/process.php» и как бы если action="" и данные отображаем через echo
Александр Мальцев
Александр Мальцев
Наверно не так вас понял. Вы хотите данные куда-то вывести на страницу после отправки формы. Тогда вы можете просто взять их с самой формы после прихода успешного ответа об отправки с сервера и вывести их в нужное место на страницу, туда куда вам нужно. Если хотите с использованием сервера, то можете на сервере добавить их в массив $data, а затем, когда его получите на клиенте разобрать и вывести на страницу.
Про echo не понял. Здесь данные сервер передаёт клиенту в формате JSON.
Andre Voda
Andre Voda
Спасибо Александр. Я не настолько ещё продвинутый, это как сделать? Оба варианта не могли бы немного подробнее описать? Спасибо.
Andre Voda
Andre Voda
Здравствуйте Александр! Впервые встречаю в сети настолько полноценно и грамотно
выполненные пояснения к программам. Спасибо вам за огромный труд и терпение.
Благодаря вашим описаниям собрал нужную мне форму легко. Некоторые затыки случились в применении скрипта masked_input. Есть красивый шаблон, в котором не используются надписи над полями, а наименования полей реализованы плейсхолдерами. Не хочется отступать от дизайна. Вопрос в следующем. Как сделать, чтобы masked_input -маска отображалась только при наведении курсора на поле (on hover), а без фокуса показывался текст из плейсхолдера, если такое возможно с этим скриптом? Спасибо.
Александр Мальцев
Александр Мальцев
Здравствуйте! Так это работает по умолчанию.
<form id="feedbackForm" action="/examples/vendors/feedback/process/process.php" novalidate>
<!-- ... -->
<div class="form-group">
  <label for="phone" class="control-label">Телефон</label>
  <input id="phone" type="text" name="phone" class="form-control" placeholder="Телефон" required="required">
  <div class="invalid-feedback"></div>
</div>
<!-- ... -->
</form>
...
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.maskedinput/1.4.1/jquery.maskedinput.min.js"></script>
<script>
$(function(){
  $("#phone").mask("+7(999) 999-9999");
});   
</script>
Andre Voda
Andre Voda
Спасибо Александр за наводку! Оказывается, я применял другой скрипт, это в другой вашей теме по формам было. (http://angelwatt.com/coding/masked_input.php)
Этот проще в эксплуатации, хоть и не поддерживается уже: (cdnjs.cloudflare.com/ajax/libs/jquery.maskedinput/1.4.1/jquery.maskedinput.min.js)
Александр Мальцев
Александр Мальцев
Да и этот скрипт тоже не обновляется. Последняя версия 1.4.1 от 02.19.2016.
Tracktor
Tracktor
Здравствуйте, Александр. Уже давно пользуюсь данной формой, кое-что доделал для себя, в связи с этим переходить на более свежие варианты пока не хочется — придётся многое переделывать. Недавно столкнулся с такой проблемой — поменял пароль на email ящике, с которого должна уходить почта (письма отправляет sendmail для windows), после чего думал что поменял пароль в конфиге sendmail, но в итоге поменял его не в том месте. Но при этом форма продолжала делать вид что отправляет письма, то есть никаких ошибок не выводила. Пока выяснял в чём дело, дошёл до того что обычная функция php mail() тоже выдаёт true при попытке отправить письмо, то есть никаких ошибок — но письма не уходили… В связи с этим вопрос, можно ли как-то донастроить форму для проверки фактической отправки письма, или может, у меня что-то не так настроено в php? Куда посмотреть?
Александр Мальцев
Александр Мальцев
Привет! Функция mail возвращает true, если письмо было принято для передачи. Но это вовсе не означает, что оно достигло получателя.
Если вы хотите знать факт, то нужно смотреть логи программы sendmail.
Tracktor
Tracktor
Спасибо за ответ, но решение нашлось гораздо проще. Я настроил в файле verify.php phpmailer на отправку через свой smtp (
$mail->isSMTP();
), то есть в обход настроек php.ini — и теперь всё отлично проверяется по факту!

Теперь другой вопрос: почему-то в браузере Mozila Firefox (76.0.1 на данный момент) не работает отмена выбора прикрепляемого файла. То есть, по идее, если нажать на выбор файла, затем нажать Отмена, то форма должна написать, что файл не может быть отправлен так как не выбран, но файл остаётся на месте, и форма ничего не пишет. При этом в Maxthon5 (браузер на движке Webkit = Chrome), а также в самом Хроме всё работает. И дело не в форме, а видимо именно в браузере — даже простейший
<input type="file" />
в «песочнице» отрабатывает точно так же в тех же браузерах… Что с этим можно сделать?
Александр Мальцев
Александр Мальцев
У Firefox и других браузерах на этом движке есть такая особенность. В этом случае необходимо прикручивать к форме какие-то кнопки для удаления файлов.
Вот описание подобной задачи и её решение.
Виктор
Виктор
Добрый день спасибо за формы, все работает хорошо. Подскажите как прикрепить файл к автоответу для пользователя?
Александр Мальцев
Александр Мальцев
Здравствуйте!
Это можно осуществить посредством добавления следующего кода в «process.php»:
...
// переменная
$attachments = array();
// добавляем в массив путь до файла, который нужно прикрепить к письму
$attachments[] = 'полное_имя_файла';
// прикрепляем к письму файлы
foreach ($attachments as $attachment) {
  $mail->addAttachment($attachment);
}
// отправляем письмо
$mail->send();
...
Виктор
Виктор
Почему то не получается :(
Вот код:
// отправляем письмо
if (!$mail->send()) {
$data['result'] = 'error';
}

if (isset($email)) {
// очистка всех адресов и прикреплёных файлов
$mail->clearAllRecipients();
$mail->clearAttachments();
//формируем тело письма
$bodyMail = file_get_contents('email_client.tpl'); // получаем содержимое email шаблона
// выполняем замену плейсхолдеров реальными значениями
$bodyMail = str_replace('%email.title%', MAIL_SUBJECT, $bodyMail);
$bodyMail = str_replace('%email.nameuser%', isset($name)? $name: '-', $bodyMail);
$bodyMail = str_replace('%email.date%', date('d.m.Y H:i'), $bodyMail);

$mail->Subject = MAIL_SUBJECT_CLIENT;
$mail->Body = $bodyMail;
$mail->addAddress($email);

//$mail->addAttachment('/feedback/file/B8DF4DBD-E2C9-4708-B532-9CE4D565A5AD.pdf', 'file.pdf');
// $filename = $_FILES['feedback/file/B8DF4DBD-E2C9-4708-B532-9CE4D565A5AD.pdf'][«new.pdf»];
//$mail->addAttachment($uploadfile, $filename);
$attachments = array();
// добавляем в массив путь до файла, который нужно прикрепить к письму
$attachments[] = ('/feedback/file/B8DF4DBD-E2C9-4708-B532-9CE4D565A5AD.pdf');
// прикрепляем к письму файлы
foreach ($attachments as $attachment) {
$mail->addAttachment($attachment);
}
// отправляем письмо
$mail->send();
}

}
Александр Мальцев
Александр Мальцев
Вам нужно прописать абсолютный путь к файлу. Прочитать про путь к файлу более подробно можете в этой статье.
Виктор
Виктор
Получилось как то так:
$attachments[] = ('/sed/public_html/feedback/file/B8DF4DBD-E2C9-4708-B532-9CE4D565A5AD.pdf');
но файл по прежнему не приходит с письмом.

Александр Мальцев
Александр Мальцев
Вам необходимо написать как-то так:
$attachments[] = $_SERVER['DOCUMENT_ROOT'] . '/feedback/file/B8DF4DBD-E2C9-4708-B532-9CE4D565A5AD.pdf';
Виктор
Виктор
Спасибо огромное все получилось:)).
Aleksey
Aleksey
Добрый день!
Возникла необходимость реализации формы. Вроде бы добавил на сайт. Работает! Но решил добавить поле — Телефон. И форма перестала работать.

В JS файл добавил вот это -

//получаем phone, который ввёл пользователь
      var phone = $("#phone").val();
// добавить в formData значение 'phone'=значение_поля_email
      formData.append('phone', phone);
В файл process. php, соответственно -

//получить phone, которое ввёл пользователь
    if (isset($_POST['phone'])) {
      $phone = $_POST['phone'];
      if (!validStringLength($name,12,13)) {
        $data['phone']='Поле phone введено неправильно';
        $data['result']='error';
      }
    } else {
      $data['result']='error';
    }
// дальнейшие действия (ошибок не обнаружено)
  if ($data['result']=='success') {

    //1. Сохрание формы в файл
    $output = "---------------------------------" . "\n";
    $output .= date("d-m-Y H:i:s") . "\n";
    $output .= "Имя пользователя: " . $name . "\n";
    $output .= "Адрес email: " . $email . "\n";
	$output .= "Телефон: " . $phone . "\n";
    $output .= "Сообщение: " . $message . "\n";
    if (file_put_contents(dirname(__FILE__).'/message.txt', $output, FILE_APPEND | LOCK_EX)) {
      $data['result']='success';
    } else {
      $data['result']='error';         
    } 

    //2. Отправляем на почту
    // включить файл PHPMailerAutoload.php
    require_once dirname(__FILE__) . '/phpmailer/PHPMailerAutoload.php';
    //формируем тело письма
    $output = "Дата: " . date("d-m-Y H:i") . "\n";
    $output .= "Имя пользователя: " . $name . "\n";
    $output .= "Адрес email: " . $email . "\n";
	$output .= "Телефон: " . $phone . "\n";
    $output .= "Сообщение: " . "\n" . $message . "\n";
После этого вылезает ошибка http://prntscr.com/rbw3vx

кстати, на сайте также добавил согласие на обработку перс. данных.

Весь код сайта могу скинуть. Как дополнение, не проходит проверку чекбокс перс. данных. При первом заходе на сайт, надо чтобы он не был активен и не отправлялась форма, если не стоит галочка. Это доп. код. Если сможете помочь, подскажите как исправить и форму и чекбокс

Весь код сайта с формой:
<section class="mbr-section form1 cid-qOa0bjJldZ" id="form1-7">

    

    
   <div class="container">
        <div class="row justify-content-center">
            <div class="title col-12 col-lg-8">
                <h2 class="mbr-section-title align-center pb-3 mbr-fonts-style display-2">Обратная связь</h2>
                <h3 class="mbr-section-subtitle align-center mbr-light pb-3 mbr-fonts-style display-5">Для связи с нами заполните форму ниже </h3>
            </div>
        </div>
    </div>
      <div class="container">
        <div class="row justify-content-center">
            <div class="media-container-column col-lg-8" data-form-type="formoid">
                 <!--   <div data-form-alert="" hidden="">
                        Спасибо! Ваше сообщение отправлено!
                    </div> -->

                    
            
<div class="row row-sm-offset">
                            <div class="col-md-4 multi-horizontal">
                                <div class="form-group">
        <!-- Контейнер, содержащий форму обратной связи -->
        <div class="panel panel-info">
        
          
          <!-- Содержимое контейнера -->
          <div class="panel-body">
 
            <!-- Сообщение, отображаемое в случае успешной отправки данных -->
            <div class="alert alert-success hidden" role="alert" id="successMessage">
              <strong>Внимание!</strong> Ваше сообщение успешно отправлено.
            </div>
 
            <!-- Форма обратной связи -->
            <form class="mbr-form" id="contactForm">
              <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 class="col-sm-6">
                  <!-- Phone пользователя -->
                  <div class="form-group has-feedback">
                    <label for="phone" class="control-label">Введите номер телефона</label>
                    <input type="phone" id="phone" name="phone" class="form-control" required="required"  value="" placeholder="Например, +7-911-123-45-67" maxlength="30">
                    <span class="glyphicon form-control-feedback"></span>
                  </div>
                </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>
              <!-- Изображение, содержащее код капчи -->          
                <img id="img-captcha" src="/feedback/captcha.php">
              <!-- Элемент, обновляющий код капчи -->
                <div id="reload-captcha" class="btn btn-default"><i class="glyphicon glyphicon-refresh"></i> Обновить</div>
                <!-- Блок для ввода кода капчи -->
                <div class="form-group has-feedback">
                <label id="label-captcha" for="captcha" class="control-label">Пожалуйста, введите указанный на изображении код:</label>
                  <input id="text-captcha" name="captcha" type="text" class="form-control" required="required" value="" autocomplete="off" minlength="6" maxlength="6">
                  <span class="glyphicon form-control-feedback"></span>
              </div>
 
              <!-- Кнопка, отправляющая форму -->  
              <button type="submit" name="submit" class="btn btn-primary pull-right">Отправить сообщение</button>
            </form><!-- Конец формы -->
 
          </div>
        </div><!-- Конец контейнера -->
 
      </div>
    </div>
  </div>
 
  <script src="/feedback/js/jquery-3.1.0.min.js"></script>
  <script src="/feedback/js/bootstrap.min.js"></script>
  <script src="/feedback/script.js"></script>

                    
                    
                    <div>
<input type="checkbox" id="politics" onclick="check();" value="" autocomplete="off" /> Я прочитал(а) <a href="/policy.html" style="color:#fff;">Правила</a> и даю свое согласие на обработку моих персональных данных, в соответствии с Федеральным законом от 27.07.2006 года №152-ФЗ «О персональных данных».
</div>
<script>
function check() {
var submit = document.getElementsByName('submit')[0];
if (document.getElementById('politics').checked)
submit.disabled = '';
else
submit.disabled = 'disabled';
}
</script>

            </div>
        </div>
    </div>
</section>
Александр Мальцев
Александр Мальцев
Для отключения проверки добавьте в «main.js» ключ isAgreement со значение false:
$(function () {
  var form1 = new ProcessForm();
  form1.init({
    isAgreement: false
  }); 
});
Aleksey
Aleksey
Спасибо за комментарий. Это для чекбокса реализация? Только у меня нет файла «main.js». Можно прямо в коде HTML прописать?

И как добавить доп. поле телефон? и какие надо правки внести в код?
Александр Мальцев
Александр Мальцев
Значит нужно поправить существующий код, в котором у вас осуществляется инициализация модального окна.
Поле телефон вы же уже добавили в форму.
Aleksey
Aleksey
Простите, не понял. Соообщение об ошибке всё равно выскакивает и

Хотя, как вы пишите, я добавил верно везде поле телефон
Александр Мальцев
Александр Мальцев
Посмотрите, что конкретно возвращает вам сервер. Может на какой-то строчке ошибка.
Aleksey
Aleksey
http://prntscr.com/rbz2lv
Вот такой ответ сервера выдаётся
Александр Мальцев
Александр Мальцев
Уберите проверку телефона:
//получить phone, которое ввёл пользователь
if (isset($_POST['phone'])) {
  $phone = $_POST['phone'];
} else {
  $data['result']='error';
}
Если всё будет хорошо, значит вы не корректно выполняете его проверку.
Aleksey
Aleksey
Да, сработало! Сообщение отправилось и пришло на почту. Но нет данных о номере телефона, хотя форма на сайте присутствует. Как тогда отправлять данные номера телефона через форму? Чтобы он приходил в письме?
Александр Мальцев
Александр Мальцев
Посмотрите какие поля у вас уходят на сервер, при отправке формы.
Aleksey
Aleksey


Правильно ли я смотрю? Тот код, что попросили удалить выше, для проверки номера телефона. Может его надо как-то подправить? Добавить проверку нормальную? Я просто не знаю что написать. PHP только начинаю изучать, поэтому могу ошибаться
Aleksey
Aleksey
Сообщение на почту приходит. Там есть поле Телефон, но оно пустое. не заполнено.
Александр Мальцев
Александр Мальцев
Посмотрите какие поля у вас уходят на сервер, при отправке формы. Для этого перейдите в браузере в инструменты разработчика, далее на вкладку «Network», на ней выберите файл «process.php», после этого перейдите в раздел «Headers», а в нём в «Form Data». Теперь посмотрите, что уходит на сервер, а в частности уходит ли значение поля телефон.
Aleksey
Aleksey
screen

Значение поля телефон уходит, но в письме, которое приходит на почту, эьтого значения нет
screen2

Александр Мальцев
Александр Мальцев
Сделайте архив формы и пришлите мне его на email (адрес указан в футере сайта), посмотрю из-за чего это может быть.
Aleksey
Aleksey
Отправил на почту
Пётр
Пётр
Здравствуйте. Попробовал прикрутить вашу форму. Но просто даже при попытке открыть голую форму вот такая ерунда — joxi.ru/LQ2K8dTw4Y8wAj

На сайт пробовал приспособить — то же самое. В чём может быть проблема?
Александр Мальцев
Александр Мальцев
Здравствуйте! Проверьте подключение CSS и JavaScript файлов.
Евгений
Евгений
Может кто подскажет
Добавил в форму:
<div class="form-group">
	<label for="tip">Список</label>
	<select id="tip" name="tip" class="form-control" onmousedown="$(':first-child', this).remove(); this.onmousedown = null;" required="required">
	<option disabled selected value>Выберите пункт</option>
	<option value="1">Пункт 1</option>
	<option value="2">Пункт 2</option>
	<option value="3">Пункт 3</option>
	<option value="4">Пункт 4</option>
	</select>
</div>
Свойство required=«required» для select не работает.
Как выполнить проверку выбора одного из пунктов данного списка и подсвечивать поле красной или зеленой рамкой как другие поля из формы.

Использую эту форму: itchief.ru/php/feedback-form-for-website#id-12
Ошибся с публикацией)))

Всем Спасибо!
Александр Мальцев
Александр Мальцев
Измените класс select на custom-select и добавьте в .form-group элемент .invalid-feedback:
<div class="form-group">
  <label for="tip">Список</label>
  <select id="tip" name="tip" class="custom-select" onmousedown="$(':first-child', this).remove(); this.onmousedown = null;" required>
    <option disabled selected value>Выберите пункт</option>
    <option value="1">Пункт 1</option>
    <option value="2">Пункт 2</option>
    <option value="3">Пункт 3</option>
    <option value="4">Пункт 4</option>
  </select>
  <div class="invalid-feedback"></div>
</div>
В javascript файле найдите функцию _validateForm и добавьте в неё select:
...
var _validateForm = function (form) {
var valid = true;
$(form).find('input, textarea, select').not('[type="file"], [name="agree"]').each(function () {
  if (this.checkValidity()) {
    ...
oleg
oleg
Добрый день использую форму обратной связи на Bootstrap 3
на openserverе открывается капча
joxi.ru/n2YjjYLibae17A

на хостере капчи нет,
joxi.ru/KAxaagpCZDKNYr

выдает ошибку
[23-Jul-2019 14:52:22 Europe/Moscow] PHP Warning: imagettftext(): Could not find/open font in /home/o/olegma3k/baptistisrael.org/public_html/fonts/captcha.php on line 27

можете пояснить, благодарю
Александр Мальцев
Александр Мальцев
Добрый день. Проверьте есть ли у вас в папке, где находится файл «captcha.php», файл «oswald.ttf».
oleg
oleg
Проблема решилась, нашел в инете
прописал следующий код в файле captcha.php
putenv('GDFONTPATH='. realpath('.'));
перед $font = 'oswald.ttf';

Валерчик
Валерчик
Здравствуйте.
Подскажите пожалуйста, как правильно разместить вот такой блок с инпутами type=«image»:
<div class="form-group has-feedback">
	<label for="image" class="control-label">Выберите картинку:</label>
	<input type="image" id="" name="image" src="001.jpg" class="form-control"  value="Вариант 1" />
	<input type="image" id="" name="image" src="002.jpg" class="form-control"  value="Вариант 2" />
</div>
Я добавил строки в «process.php» и «script.js», но у меня ошибка: «Произошли ошибки при отправке формы на сервер»
Александр Мальцев
Александр Мальцев
Здравствуйте.
Элемент input с type=«image» — это кнопка отправки для HTML формы в виде изображения. Поэтому данный фрагмент кода, в таком виде как он есть, не совсем понятен.
Сбор данных в представленной в статье форме осуществляется посредством FormData. Для добавления информации о выбранной картинке в данные, отправляемые на сервер, соответственно нужно их просто добавить в FormData.
Vladimir
Vladimir
Добрый день! Всё сделал по инструкции, но письмо на почту не приходит. Где копать?
Кроме этого ещё нужно где-нибудь вносить изменения?
/* 1 ЭТАП — НАСТРОЙКА ПЕРЕМЕННЫХ */
const
IS_CHECK_CAPTCHA = true, // проверять капчу
IS_SEND_MAIL = true, // отправлять письмо получателю
IS_SEND_MAIL_SENDER = true, // отправлять информационное письмо отправителю
IS_WRITE_LOG = true, // записывать данные в лог
MAIL_FROM = 'prime@bk.ru', // от какого email будет отправляться письмо
MAIL_FROM_NAME = 'Владимир', // от какого имени будет отправляться письмо
MAIL_SUBJECT = 'Сообщение с формы обратной связи', // тема письма
MAIL_ADDRESS = '9600504@bk.ru', // кому необходимо отправить письмо
MAIL_SUBJECT_CLIENT = 'Ваше сообщение доставлено'; // настройки mail для информирования пользователя о доставке сообщения
Vladimir
Vladimir
Всё, разобрался. E-mail отправителя поставил адрес почты хостинга, с которого отправляется письмо и всё заработало) Огромное спасибо за Вашу работу!
Hi
Hi
хэлов, как это можно запустить на xampp, что там нужно написать, чтобы запустилось? я прописал там по этой инструкции но ничего не работает qaru.site/questions/3398/how-to-configure-xampp-to-send-mail-from-localhost И путь нужно писать так -require_once('feedback/phpmailer/src/SMTP.php'); или по другому как то? Сейчас когда нажимаю отправить, высвечивается — Исправьте данные и отправьте форму ещё раз. И если удалить пользовательское соглашение из html, то на кнопку — отправить сообщение, невозможно нажать, а пользовательское соглашение мне не нужно. И можно ли здесь сделать reCAPTCHA, без ввода данных, а просто при нажатии на кнопку, чтобы срабатывало?
Александр Мальцев
Александр Мальцев
Не знаю, XAMPP не пользуюсь. Из аналогичных инструментов отправка по SMTP точно работает на портативной серверной платформе Open Server.
Петр
Петр
Всем и Шефу привет!

Горит проблема — может кто-нибудь помочь?

Нужно поставить цель из яндекс-метрики на успешную отправку формы (не просто по клику на кнопку отправить)

Яндекс предлагает делать это так:

<form action="" method="POST" type="submit" onsubmit="yaCounterXXXXXX.reachGoal ('form1')">

    <input name="name" placeholder="Ваше имя" required> 

    <input type="email" name="mail" placeholder="Ваш email" required="Введите Ваш email"> 

    <button>Отправить</button>

</form>
но это, как мне кажется, конфликтует с тутошним вариантом.

Как бы интегрировать подобный функционал в вашу форму?

Заранее огромное спасибо!
Александр Мальцев
Александр Мальцев
Так и добавьте код в блок, который выполняется при успешной отправке формы (process-forms.js):
// при успешной отправки формы
if (data.result === "success") {
  yaCounterXXXXXX.reachGoal('form1');
  $(this).parent().find('.form-result-success')
    .removeClass('d-none')
    .addClass('d-flex');
    return;
}
Петр
Петр
Спасибо, шеф! А если форм несколько? Одна на получить консультацию, а другая на вызов мастера.
Петр
Петр
Если я правильно понял, нужно создать два файла process-forms.js?
Александр Мальцев
Александр Мальцев
Зачем? Просто добавляете к формам атрибут, например, data-title. А в качестве значения устанавливаете необходимое название форм.
<!-- Первая форма -->
<form id="feedbackForm1" action="/feedback/process/process.php" data-title="form1" novalidate>
...
</form>

<!-- Вторая форма -->
<form id="feedbackForm2" action="/feedback/process/process.php" data-title="form2" novalidate>
...
</form>
В JavaScript:
// при успешной отправки формы
if (data.result === "success") {
  var formTitle = $(this).attr('data-title');
  yaCounterXXXXXX.reachGoal(formTitle);
  $(this).parent().find('.form-result-success')
    .removeClass('d-none')
    .addClass('d-flex');
    return;
}
Петр
Петр
Спасибо большое, Александр! Выручили. Всех благ!
Вадим
Вадим
Александр, вроде такой ошибки ни у кого еще не было. Я поместил ваш index.html во всплывающее окно, — и каждый раз при нажатии на кнопку открывается форма с надписью «Форма успешно отправлена. Нажмите на ссылку, чтобы отправить ещё одно сообщение.» yadi.sk/i/CKkC1jcsGmjpCw То есть ни валидации, ни отправки, ни возможности отправить форму. Как такое может быть?
Александр Мальцев
Александр Мальцев
Так сказать не могу. В любом случае это потребует доработки формы. Как сделать форму во всплывающем окне подробно описано в этой статье.
Рушан
Рушан
Здравствуйте!
Правильно ли я понимаю это обработчик формы?
<?php
  // отправляем данные формы на почту
  // включить файл PHPMailerAutoload.php
  require_once dirname(__FILE__) . '/phpmailer/PHPMailerAutoload.php';
  //формируем тело письма
  $output .= "Имя пользователя: " . isset($_POST['name']);
  // ... другие поля

  // создаём экземпляр класса PHPMailer
  $mail = new PHPMailer;
  $mail->CharSet = 'UTF-8'; 
  $mail->From      = 'от куда';
  $mail->FromName  = 'имя сайта';
  $mail->Subject   = 'Сообщение с формы обратной связи';
  $mail->Body      = $output;
  $mail->AddAddress('IT.Rush@yandex.ru');
  // отправляем письмо
  $mail->Send();      
?>

А что это за код?
require_once dirname(__FILE__). '/phpmailer/PHPMailerAutoload.php';
Я получается подключил вот эти файлы:
Скрипт:
$(function() {
  // при отправке формы contactForm на сервер (id="contactForm")
  $('#contactForm').submit(function(event) {
    // отменяем стандартное действие браузера
    event.preventDefault();
    // создаём объект, который будет содержать данные для отправки
    var formData = new FormData();
    // добавить в formData значение поле name (id поля = name)
    // первый параметр - получаем значение поля
    // имя, под которым данное поле будет доступно в массиве $_POST на сервере
    formData.append($("#name").val(), name);
    // ... повторяем данное действие для всех необходимых полей
    // т.е. добавляем в formData все данные которые хотим отправить на сервер
      
    //отправляем данные на сервер (AJAX)
    $.ajax({
      //метод передачи запроса - POST
      type: "POST",
      //URL-адрес запроса (подключение файла process.php для обработки формы) 
      url: "/process.php",
      //передаваемые данные - formData
      data: formData,
      // не устанавливать тип контента, т.к. используется FormData
      contentType: false,
      // не обрабатывать данные formData (т.к. они уже и так обработаны объектом FormData)
      processData: false,
      // отключить кэширование результатов в браузере
      cache: false,
      //при успешном выполнении запроса
      success : function(data){
        // ... написать действия, которые будут отображаться пользоваетлю
        // в зависимости от полученного ответа с сервера
        // т.е. если пришёл один ответ, то значит то что форма отправилась
        // если другой, то что произошла ошабка и форма не отправилась
        // результат ответа сервера формируется в файле process.php (обычно с помощью if)
      },
      error: function (request) {
        // отобразить ошибку
      }        
    });
  });
});
И вот это файл PHP:
<?php
// отправляем данные формы на почту
// включить файл PHPMailerAutoload.php
require_once dirname(__FILE__). '/phpmailer/PHPMailerAutoload.php';
//формируем тело письма
$output .= «Имя пользователя: ». isset($_POST['name']);
//… другие поля

// создаём экземпляр класса PHPMailer
$mail = new PHPMailer;
$mail->CharSet = 'UTF-8';
$mail->From = 'от куда';
$mail->FromName = 'имя сайта';
$mail->Subject = 'Сообщение с формы обратной связи';
$mail->Body = $output;
$mail->AddAddress('IT.Rush@yandex.ru');
// отправляем письмо
$mail->Send();
?>
Если да, то теперь при нажатии на кнопку отправить нечего не происходит.
Помогите пожалуйста!
Заранее благодарю!
Рушан
Рушан
Здравствуйте!
Я только изучаю Javaskript и с PHP вообще не как.
Сложно ли будет написать PHP обработчик для этой формы?
<form id="feedbackForm" action="process.php" role="form">
 	<div class="form-group">
		<div class="input-group">
			<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
 <input id="inputname" type="text" class="form-control" placeholder="Ваше Имя">		 
	 </div>
		</div>
		<div class="form-group">
			<div class="input-group">
 <span class="input-group-addon"><i class="glyphicon glyphicon-envelope"></i></span>
<input id="inputemail" name="email" type="email" class="form-control" placeholder="Ваш Email">
								  
				</div>
</div>
						   <div class="form-group">
							   <textarea class="form-control" rows="3"></textarea>
						  </div>
						  <div class="checkbox">
							<label>
							
							</label>
						  </div>
						  <button type="submit" class="btn btn-default">Отправить</button>
						</form><!--form-end-->
Заранее благодарю!
Александр Мальцев
Александр Мальцев
Здравствуйте!
В статье есть пример PHP обработчика для формы. Можете взять его за основу. Он снабжён комментариями, так что наверно будет не сильно сложно разобраться, как он работает.
Vera
Vera
Здравствуйте, спасибо за урок, все работает, письма приходят и отправителю и получателю, но после нажатия кнопки Отправить не появляется сообщение «Ваше сообщение отправлено» и не очищаются поля. В каком файле и какой код отвечает за это? И еще я бы хотела, чтобы сообщение «Ваше сообщение отправлено» появлялось просто строчкой под формой, так же как появляются сообщения об ошибках, как это можно сделать?
Александр Мальцев
Александр Мальцев
Здравствуйте! Это должно работать по умолчанию. Посмотрите, какой ответ приходит от сервера (на вкладке Network в инструментах разработчика).
Vera
Vera
там должны быть показаны ошибки? ошибок нет…
Александр Мальцев
Александр Мальцев
Необязательно. Как посмотреть ответ, который пришёл с сервера приведено в этом комментарии. Только вместо verify.php нужно смотреть process.php, т.к. запрос отправляется на него.
Vera
Vera
Все посмотрела, ответ success приходит, добавила id msgSubmit,
трудности с последним пунктом: 3. Проверьте, соответствует ли у вас кодировка, в которой сервер присылает ответ с кодировкой файла script.js.
Ответ это: {«result»:«success»}? Его нужно прописать в файле script.js? В какой строке?
Александр Мальцев
Александр Мальцев
Необходим был только ответ. Эти действия выполнять не нужно.
Для отображения сообщения об успехе используется элемент с абсолютным позиционированием. Может проблема в этом. Проверьте установлено ли для элемента в котором расположена форма относительное позиционирование? Т.е. класс position-relative.

Vera
Vera
нет, position absolute
Vera
Vera
Здравствуйте, Александр, я нашла, в чем проблема, вдруг кому-то тоже будет полезно, у меня бутстрап 3, а у вас 4, я, по неопытности, не обратила на это сразу внимания, сейчас добавила нужные классы и все теперь работает, спасибо :-)
Максим
Максим
Добрый день! Вставил форму на сайт и после этого поменялся шрифт всего сайта, для body стиль определил сам, и до подключения формы, все норм было… Куда копать не подскажите?
Александр Мальцев
Александр Мальцев
Добрый день!
Если используете какую-то сборку Bootstrap (главное чтобы она была 4 версии), то данный файл подключать не нужно:
<link rel="stylesheet" href="/feedback/vendors/bootstrap/css/bootstrap.min.css">
А также проверьте последовательность подключения CSS:
Bootstrap CSS -> Ваш файл стилей
В Bootstrap CSS шрифт задаётся так:
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.5;
  color: #212529;
  text-align: left;
  background-color: #fff;
}
Шрифт, устанавливаемый Bootstrap можно отключить с помощью удаления CSS-свойства font-family.
Максим
Максим
Благодарю, помогло. Примерно это и сделал. Спасибо за хорошую форму обратной связи. Ваша форма лучшая в интернете!
Kvarcus
Kvarcus
Спасибо за форму и полезный ресурс.
Отдельное Спасибо за комментарии!
Приведенная выше проблема с кодировкой решается заменой строчки №47 в class.phpmailer.php
public $CharSet = 'iso-8859-1';
на
public $CharSet = 'UTF-8';
Сергей
Сергей
Привет Шеф! Спасибо за форму, работу!
Ну а по сути:
Помоги если есть время решить проблему с уведомлениями при приклеплении файлов.
Я использую плагин для стилизация чекбосов и прочей муры, а файл script.js выводит уведомление в
<p></p>
и как я понял он должен быть расположен непосредственно под инпутом (у меня так и есть), но плагин для стилизации закрывает перед
<p>
и уведомления
типа: * Файл не будет отправлен, т.к. его размер больше 512Кбайт и етс не работают.
Как выйти из положения в данной ситуции и что нужно переделать в этом куске:
$(document).on('change','input[name="images[]"]',function(e){
  // если выбран файл, то добавить ещё элемент "Выбрать файл"
  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></p>');
  }
  // если выбран файл, то..
  if (e.target.files.length>0) {
    // получить файл
    var file = e.target.files[0];
    // проверить размер файла
    if (file.size>maxSizeFile) {
      $(this).next('p').text('* Файл не будет отправлен, т.к. его размер больше 512Кбайт');
    } else if (!file.type.match(typeFile)) { // проверить тип файла
      $(this).next('p').text('* Файл не будет отправлен, т.к. его тип не соответствует разрешённому');
    } else {
      // убираем сообщение об ошибке
      if ($(this).next('p')) {
        $(this).next('p').text('');
      }
    }
  } else {
    // если после изменения файл не выбран, то сообщаем об этом пользователю
    $(this).next('p').text('* Файл не будет отправлен, т.к. он не выбран');
  }
});
Может можно как то по айди? Я в этом двоешник)
Вот что получается: скриншот
Александр Мальцев
Александр Мальцев
Привет! Спасибо. А в форме будет один элемент для прикрепления файлов или несколько?
Алексей
Алексей
Александр, прекрасные формы, спасибо Вам огромнейшее!!!
У меня единственная проблема возникает на локальной машине, это либо работает отправка на почту, но не работает оповещение о том что форма отправлена.
Если убираю код отправки на почту — срабатывает оповещение что сообщение отправлена.
// отправляем письмо
if ($mail->Send()) {
$data['result']='success';
} else {
$data['result']='error';
}

Возвращаю код — письмо приходит на почту, но оповещение не срабатывает, подскажите пожалуйста как мне быть, спасибо!
fedro
fedro
Добрый день, использую phpmailer для отправки по smtp.
Все работает до тех пор, пока не делаю:
if ($mail->Send()) {
  $data['result']='success';
} else {
  $data['result']='error';
}
Как понимаю обработчик получает ответ от почтового сервера Яндекс и json_encode($data) вызывает ошибку.
Как решить такого рода проблему?
Вот что пишет Response: скриншот
Александр Мальцев
Александр Мальцев
Добрый день!
Попробуйте создать простой php файлик с отправкой почты с помощью phpmailer и включите показ ошибок. Откройте полученный файлик в браузере и посмотрите, какие у вас ошибки возникают. Так отладить будет попроще.

В этой конструкции нет ошибки.
if ($mail->Send()) {
$data['result']='success';
} else {
$data['result']='error';
} 
Если функция Send() вернула положительный результат, то записывается 'success'. А если нет, то 'error'.
Алексей
Алексей
Получилось как то найти решение проблемы?
Сергей
Сергей
fedro
как понимаю обработчик получает ответ от почтового сервера яндекс и json_encode($data) вызывает ошибку.
как решить такого рода проблему.
Вам ответ приходит в html формате. В JSON не может быть html тегов. От этого и ошибка. Посмотрите в консоль
Ihar
Ihar
Добрый вечер!
Давно пользуюсь вашей формой, недавно увидел что можно установить «recaptcha» от гугл, подскажите пожалуйста как вырезать старую «буквенно-числовую» и установить новую recaptcha?
Спасибо!
Александр Мальцев
Александр Мальцев
Добрый вечер! Эти статьи уже есть. Вот статья, в которой для защиты формы используется invisible reCAPTCHA. А в этой — обычная reCaptcha V2.
Ihar
Ihar
Спасибо за ответ, это я изучил как делать. Основной вопрос: как убрать старую капчу которая сама генерирует буквы и числа, из самой первой версии, этак полутора годовалой?
Ihar
Ihar
вот моя форма , так и не понял как вырезать капчу… помогите плиз и если можно по возможности туда впихнуть reCaptcha
Яна
Яна
Добрый день!
Подскажите, где искать ошибку?
Проблема с капчей, сервер присылает ответ: скриншот
Куда смотреть, что делать?
Александр Мальцев
Александр Мальцев
Добрый день. Это означает что ответ, который вы ввели в форме, не совпадает с тем, который хранится в сессионной переменной code на сервере.
Может эта сессионная переменная используется ещё в каком-нибудь месте и её значение переписывается. Попробуйте изменить её имя на другое (например, на captchacode). Это изменение необходимо сделать в файлах process.php, captcha.php и index.html.
Может это связано с кэшом. Попробуйте отправку формы осуществить из режима инкогнито.
Николай
Николай
Добрый день! Залил файлы на сайт сделал все изменения как в описании. Ввод данных и капчи проходит на ура, а вот при нажатии на отправить выводит ошибку «Произошла ошибка при отправке формы на сервер». Что это может быть и как решить данную проблему. Хостинг поддерживает отправку писем, так как другие формы отправки работают, просто очень понравилась ваша.
Скриншот
Николай
Николай
При загрузке чистого файла с вашего сайта, ошибка такая же.
Александр Мальцев
Александр Мальцев
У вас ошибка возникает при проверке кода капчи на сервере. Проверьте, что вы правильно указали в форме публичный и секретный ключ, который вы получили с сервиса Google reCAPTCHA. Форма с Google reCAPTCHA не будет работать, пока вы не введёте эти ключи.
Николай
Николай
а сейчас вообще при нажатии отправить не чего не происходит
Николай
Николай
и куда какой ключ по файлам
Александр Мальцев
Александр Мальцев
Это всё показано в этой теме: Форма с Google reCaptcha
Роман
Роман
Доброго времени суток!
Помогите направить в нужную сторону, где ошибка?
Все получилось сделать, но очень криво отображается всплывающее окно (см. снимок экрана)
Роман
Роман
Более того, весь функционал не работоспособен.
Александр Мальцев
Александр Мальцев
На скриншоте видно, что вы просто открываете php файл в браузере. Так конечно ничего у вас работать не будет. Чтобы это работало необходимо иметь веб-сервер и загружать файлы туда. Обращаться к страницам сайта необходимо через доменное имя. В качестве веб-сервера можно использовать, например, локальные сборки для Windows (denwer, openserver или т.п.) или виртуальный хостинг.
Максим Хализов
Максим Хализов
Доброго дня, Дорогой Шеф! Подскажите пожалуйста, я решил сделать форму по вашему уроку, но столкнулся с проблемой. Хочу растянуть container в котором находиться form до низа окна просмотра в браузере. Но в интернете не нашел адаптивного решения кроме как на JS(но я ещё с ним не знаком и не смог разобраться) Задача растянуть container до низа окна, а так же отцентрировать вложенный в него col-lg-12 по вертикали (тут a полагаю нужно будет прописать margin: auto auto;). Растянуть надо так, чтобы не было скролинга и при этом на разных мониторах он не появлялся. Пробовал прописать height: 100vh; но тогда из-за navbar появлялся скролинг на 51px. Я пробовал сделать так: height: calc(100hv-51px); но код не сработал, видимо отнимать от vh нельзя. Прилагаю картинки для визуального понимания задачи. Заранее огромное спасибо, Шеф)
<img
src=«https://itchief.ru/assets/uploadify/a/1/b/a1bf923986a5efe47347abdff87ec073s.jpg» class=«fancybox thumbnail center»>


<img
src=«https://itchief.ru/assets/uploadify/0/7/b/07b61ff962b835dc8390bfac70a16ba6s.jpg» class=«fancybox thumbnail center»>
Александр Мальцев
Александр Мальцев
Добрый!
Подобную задачу более просто решить на CSS Flexbox.
1. HTML-код:
<body>
    <div class="container">
        <div class="row wrapper">
            <header class="header">
                <!-- Заголовок (меню) -->
            </header>
            <main class="main">
                <div class="form-container">
                    <div class="col-sm-6 col-sm-offset-3">
                        <!-- Форма обратной связи -->
                        <div class="panel panel-success" style="margin-bottom: 0px;">
                            <div class="panel-heading">
                                <h2 class="h3 panel-title">Форма обратной связи</h2>
                            </div>
                            <div class="panel-body">
                                HTML-форма...
                            </div>
                        </div>
                    </div>
                </div>
            </main>
        </div>
    </div>
</body>
2. CSS-код:
html {
  height: 100%;
}
body {
  min-height: 100%;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
.wrapper {
  min-height: 100vh;
  background: pink;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -ms-flex-direction: column;
  flex-direction: column;
}
.header {
  position: relative;
  min-height: 1px;
  height: 51px;
  background: green;
}
.main {
  position: relative;
  min-height: 1px;
  -webkit-box-flex: 1;
  -ms-flex: 1 0 auto;
  flex: 1 0 auto;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  background: orange;
}
.form-container {
  max-width: 100%;
  -webkit-box-flex: 1;
  -ms-flex: 1 0 100%;
  flex: 1 0 100%; 
}
Максим Хализов
Максим Хализов
Спасибо) Работает)
Юлия
Юлия
ПРивет! А с чем может быть связано то, что я не могу скачать Архив формы? даже сама ссылка не загружается и не переходит на ссылку «Этот каталог»…
Александр Мальцев
Александр Мальцев
Добрый день. Скорее всего у вас нет доступа к сервисам Яндекса. Ссылка в хранилище Google: архив формы обратной связи.
Юлия
Юлия
Oгромное спасибо! Вы реально самые крутые! Люди с большим сердцем! Hадеюсь, что вся ваша доброта, Вам вернется в 100-кратном размере :)
Алексей
Алексей
Александр, подскажите, как при успешном запросе отправить ответное письмо клиенту в стиле «Ваш запрос получен, мы обработаем его в течении часа»? Спасибо!
Александр Мальцев
Александр Мальцев
Здравствуйте, просто необходимо отправить ещё одно письмо. Как это сделать можете посмотреть в этой форме (файл process.php, строчки кода 112-127): yadi.sk/d/lIiDYSz93KewPg
Ihar
Ihar
Привет! Очень крутая формочка! Подскажите пожалуйста как из этой формы оставить для ввода только Имя и Телефон?
Александр Мальцев
Александр Мальцев
Привет! Спасибо! Посмотри этот каталог, там есть различные варианты форм обратной связи, а также такие, которые содержать только имя и телефон. Уже столько разных вариантов форм было создано на базе этой…
maxlan
maxlan
В форме переделаны поле «email»находится под полем «имя». На другом сайте форма изначальная и в ней нет проблемы с капчей.
Что может быть???
Александр Мальцев
Александр Мальцев
Проверьте структуру HTML кода формы (открывающие и закрывающие теги).
maxlan
maxlan
Здравствуйте! Когда отправляется сообщение с неправильно набранным кодом капчи окно капчи пропадает и появляется после нажатия кнопки обновить. В остальном работает.
Спасибо.
maxlan
maxlan
И еще при отправке выдается сообщение о успешной отправке но на майл сообщение не приходит. И после обновления страницы в полях остается текст.
Александр Мальцев
Александр Мальцев
Для того чтобы браузер не сохранял данные добавьте к форме атрибут:
autocomplete="off"
Если сообщения не приходят, значит их блокирует фильтр хостера. Ознакомься с этими комментариями:
itchief.ru/lessons/php/feedback-form-for-website#comment-3956
itchief.ru/lessons/php/feedback-form-for-website#comment-3937
maxlan
maxlan
Здравствуйте.
Установил форму. После загрузки страницы нет картинки капчи, но она появляется после клика кнопки обновить. При переходе или обновлении страницы опять пропадает. Что может быть.
Спасибо.
Александр Мальцев
Александр Мальцев
Проверьте в файле HTML строчку, а именно путь к файлу captcha.php:
<img id="img-captcha" src="/feedback/captcha.php">
SonyaDB
SonyaDB
Добрый день Александр!
С картинкой все нормально, получилось, но при отправке пишет что Произошла ошибка при отправке данных.
Никак не могу понять с чем это связанно.
Пожалуйста помогите.
Александр Мальцев
Александр Мальцев
Здравствуйте. Слишком мало информации. Даже не знаю, что вам подсказать. Для начала проверьте, поддерживается ли у вас php функция mail. Следующий этап — это проверка логов в браузере и на сервере. А так можете почитать комментарии к статье тех пользователей, кто тоже сталкивался с подобной проблемой…
SonyaDB
SonyaDB
Добрый день!
Я установила форму но у меня не показывает картинку капчи, при этом в отдельном окне фон открывается.
Помогите разобраться.
Спасибо!
alinka
alinka
Здравствуйте, Александр! я не люблю читать комменты по вырезанию капчи и добавления полей, сделала сама, но теперь, через неделю мучений (нужно было все-таки дочитать страницу до конца) форма заработала как надо, но появилась другая проблема.
У меня одностраничник и нужно разместить 3 разные формы отправки сообщений. Но даже две формы друг с другом конфликтуют при проверке полей и отправке.
Не очень теперь хочется искать другие варианты реализации, т.к. Ваша форма отлично работает.

Можно ли как-то заставить 3 формы работать на одностраничном сайте?
Александр Мальцев
Александр Мальцев
Здравствуйте. Это можно сделать, но изначально форма не затачивалось под это.
Основные действия:
1. Проверить чтобы элементы в формах имели разные id, т.к. добавление данных для отправки идёт именно по им.
2. Сделать копии каталога feedback. Например, feedback1, feedback2 и feedback3. Соотвественно, подключить 3 файла script.js, каждый из которых будет отправлять свою форму на обработку в соответствующий файл process.php. Исправить в них идентификаторы (id), пути и т.д.

Решение конечно не оптимальное, но простое.
alinka
alinka
Ответ конечно не тот, который хотела бы услышать.
Заставили вы меня изучить js — который мне не хотелось вообще трогать.

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

В скрипте есть описание что нужно добавить и изменить, чтобы работали разные формы.
Александр Мальцев
Александр Мальцев
Просто не вижу смысла описывать действия по изменению скриптов… В ближайшее время есть планы выпустить новую переработанную версию формы обратной связи, которую будет не только просто настраивать, но она будет и более универсальной. С её помощью можно будет очень просто решить и вашу задачу. Если есть время, то можете подождать…
Юрий
Юрий
Здравствуйте, Александр! Попытался вырезать каптчу и получаю такую ошибку.
Не подскажите, где и что копать?
itchief.ru/assets/images/bootstrap/0939ba30d2660046eb150c3bbe987f11.jpeg
Александр Мальцев
Александр Мальцев
Здравствуйте, Юрий. Тут дело не в капчи, а в неверно настроенных путях. Форма (а точнее скрипт) пытается отправить запрос в process.php по указанному вами пути, а его в этом месте нет (ошибка 404).
Юрий
Юрий
Спасибо, что ответили. Вернул эту строку на место, как и было по-умолчанию
url: "/feedback/process.php",
и теперь, когда жму отправить, то сверху красным шрифтом, вылазит весь код страницы с ошибкой вместе) Если извлечь саму ошибку, то она звучит так: Произошла ошибка при отправке данных. Все таки лишнее вырезал похоже. Но я прочел все ваши советы по удалению полей и непосредственно капчи, но видимо код с тех пор обновился и они уже не работали. Вобщем удалял до тех пор, пока перестало появляться сообщение "… заполните это поле"))) Если вам не трудно, посмотрите сам код yadi.sk/d/WRGxNXil33Di2U
Юрий
Юрий
Хочу добавить, что когда установил сначала форму с капчей, то не смог проверить на работоспособность, т.к. картинка капчи была видна, а шрифт нет.
Юрий
Юрий
Продвинулся все-таки я дальше в правильном направлении) Папку feedback я закинул теперь в корень сайта, а не в папку темы, как изначально. Поменял пути и теперь сообщения сохраняются в файл, но выскакивает ошибка «Произошли ошибки при отправке формы на сервер.» и на адресс не приходит.
Юрий
Юрий
Ура! Не правильно указал AddAddress, теперь все ок! Спасибо за ваши труды и помощь!
Сергей Горин
Сергей Горин
Добрый день, Александр! И снова обращаюсь к Вам с просьбой о помощи, теперь уже по данной теме. Подскажите пожалуйста, как в php реализовать возможность отправки содержимого полей формы с поддержкой html тегов? И второй вопрос: как сделать, чтобы письмо приходило не в виде обычного текста, а в виде html-разметки с css-оформлением? Буду Вам признателен за простейшие примеры кода!
Александр Мальцев
Александр Мальцев
Здравствуйте.
Для этого необходимо указать, что тело письма будет представлять собой html. Это осуществляется посредством добавления следующей инструкции в код:
$mail->IsHTML(true);
Этот режим позволит формировать тело письма, с помощью html тегов и css:
$output = '<h3 style="color:red;">Сообщение с формы обратной связи</h3>';
$output .= '<hr>';
$output .= '<p><b>Данные, оставленные пользователем в форме обратной связи:</b></p>';
...
Сергей Горин
Сергей Горин
Огромное спасибо, Александр! Предложенное Вами решение оказалось куда проще, чем я мог себе представить ))
Artem
Artem
Что не могу понять… Ввожу правильную каптчу — «Произошли ошибки при отправке формы на сервер.»
В консоли смотрю, приходит POST'ом, нор всё время — {«result»:«error»}

Artem
Artem
Ах да, в папке проекта создаётся файлик «message.txt» с сообщениями из формы, но всё равно — {«result»:«error»}
Александр Мальцев
Александр Мальцев
Значит, у вас всё отлично отрабатывает до этого момента. После этого в файле process.php идёт отправка формы на указанный email. Там и возникает ошибка… Скорее всего, вы имеете хостинг (тариф хостинга), который просто не позволяет отправлять почту.
Artem
Artem
Проект пока даже не на хостинге, а на локальном сервере… Но по идее в Open Server и в Xampp должны приходить письма! Но ни там, ни там ничего не наблюдается =(
Александр Мальцев
Александр Мальцев
Если есть заглушка, то должно…
Определите в каком месте возникает ошибка и тогда будет всё понятно.
Для этого необходимо добавить после каждой из строчек
$data['result']='error'
дополнительное описание:
$data['errortext']='строчка 109 или при mail send';
Artem
Artem
Да, ошибка в этом блоке, в самом конце:

if ($mail->send()) {
        $data['result']='success';
    } else {
        $data['result']='error';
    }
Прошёлся по трейсу в классе… Метод send, preSend и вот наконец punyencodeAddress

if ($this->has8bitChars($domain) and @mb_check_encoding($domain, $this->CharSet)) {
                $domain = mb_convert_encoding($domain, 'UTF-8', $this->CharSet);
                if (($punycode = defined('INTL_IDNA_VARIANT_UTS46') ?
                    idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS4) :
                    idn_to_ascii($domain)) !== false) {
                    return substr($address, 0, $pos) . $punycode;
                }
            }
Редактор пишет в строке idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS4), что передаются 3 параметра, а в реализации самого метода idn_to_ascii всего 2. Пробовал удалять или 0 или константу INTL_IDNA_VARIANT_UTS4 — но тогда: только переменные передаются по ссылке!

function idn_to_ascii($utf8_domain, &$errorcode = null) { }
Где же я так нагрешил по крупному то(((
Александр Мальцев
Александр Мальцев
Это что-то с локальным сервером… Попробуйте сменить его на какой-то другой.
Artem
Artem
Эммм, дома дебиан — Xampp, на работе Windows — Open Server… Всё одно и тоже! Хорошо попробую — Wampp на ноуте завтра
Artem
Artem
Вообщем разместил на хостинг форму! То же самое:
«Произошли ошибки при отправке формы на сервер.»
Artem
Artem
А вот оно даже как… Сейчас стал отлаживать и в
$data['result']='error'

выходит в строке, если данные передаются не постом… То есть в 66 строке! Это как оно так может быть, что не POST?
В script.js ничего не менял:
$('#contactForm').submit(function(event) {

//отправляем данные на сервер (AJAX)
$.ajax({
//метод передачи запроса — POST
type: «POST»,
//URL-адрес запроса
url: «process.php»,
//передаваемые данные — formData
data: formData,
// не устанавливать тип контента, т.к. используется FormData
contentType: false,
// не обрабатывать данные formData
processData: false,
// отключить кэширование результатов в браузере
cache: false,
//при успешном выполнении запроса
success: function(data)
Что же это за наваждение какое-то! Думал на сервере будет всё ок! Но нет же…
Artem
Artem
После долгих попыток, попробовал использовать из коробки и просто переходить по ссылки, а не внедрять на главную страницу… Теперь:

SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
var $data = JSON.parse(data);
Александр Мальцев
Александр Мальцев
Это означает то, что у вас файл process.php не отрабатывает до конца и в нём где-то возникает ошибка. Т.е. он не возвращает JSON.

Определить ошибку можно так. Открыть в браузере консоль разработчика, перейти на вкладку Network и посмотреть, какой ответ приходит с сервера. Скорее всего, будет выведена ошибка, которая происходит на какой-то строчке. После этого будет понятно, что необходимо изменить, чтобы её не возникало. Может быть, нет на хостинге какой-то функции…
Юрий
Юрий
Здравствуйте. Александр.
Подскажите как добавить в форму возможность отправки любого файла, а не только картинки?
И что делать с нечитаемыми иероглифами в отправляемом письме — приходит вот такое Сообщение:
Спасибо.
Александр Мальцев
Александр Мальцев
Необходимо в файлах php и js убрать строчки, которые отвечают за проверку расширения файлов.

Проверьте есть ли у вас в файле php, который отвечает за отправку писем, строчка:
$mail->CharSet = 'UTF-8';
Эта строчка должна распологаться после:
$mail = new PHPMailer;
qwerty1
qwerty1
Александр, подскажите, как добавить в форму чекбокс согласия обработки и два выпадающих списка?
Александр Мальцев
Александр Мальцев
Для добавления в форму обратной связи чекбокса (checkbox) необходимо выполнить следующие действия:
  1. Вставка элемента input с type, равным checkbox в HTML форму:
    <!-- Чексбокс -->
    <div class="checkbox">
      <label>
        <input type="checkbox" name="agreement" id="agreement"> Я согласен на обработку данных
      </label>
    </div>
  2. Установка кнопке submit не активное состояние:
    <button type="submit" class="btn btn-primary pull-right" disabled="disabled">Отправить сообщение</button>
    
  3. Добавление скрипта, устанавливающего активность кнопки в зависимости от состояния чекбокса:
    <script>
    $(function() {
      $('#agreement').change(function() {
        if ($(this).prop('checked') == true) {
          $('#contactForm button[type="submit"]').prop('disabled', false);
        } else {
          $('#contactForm button[type="submit"]').prop('disabled', true);
        }
      });
    });
    </script>
    
Александр Мальцев
Александр Мальцев
Для добавления выпадающего списка в форму обратной связи выполните следующие шаги:
  1. Вставьте в форму необходимый раскрывающий список (например, содержащий размеры) (файл index.html):
    <div class="form-group">
      <label for="size">Выберите размер:</label>
      <select class="form-control" id="size" name="size">
        <option disabled selected value> -- выберите размер -- </option>
        <option>XS</option>
        <option>S</option>
        <option>M</option>
        <option>L</option>
        <option>XL</option>
        <option>XXL</option>
      </select>
    </div>
    
  2. Добавьте значение выбранного пункта меню в объект formData (файл script.js — для отправки на сервер):
    // если пользователь выбрал поле, то добавляем его в formData
    if ($('#size').val()) {
      formData.append('size', $('#size').val());
    }
    
  3. Получаем значение на сервере (если оно есть) и добавляем его в тело письма для отправки на почту (файл process.php). Или любое другое необходимое действие.
    if (isset($_POST['size'])) {
      $output .= "Размер: " . $_POST['size'];
    }
    
Добавление второго списка выполняем аналогично.
qwerty1
qwerty1
Спасибо за оперативность. Все понятно просто!
yachmen
yachmen
Александр, капча в форме перестала отображаться. И демо-вариант так же не отображается.
Спасибо, в демо исправил. А в какой ещё форме не отображается?
yachmen
yachmen
Я скачал исходники и проверил на своем сервере — увидел проблему с капчей, только после этого решил проверить демо на вашем сайте.
Александр Мальцев
Александр Мальцев
По умолчанию необходимо директорию feedback из архива скопировать в корень сайта.
yachmen
yachmen
Сделал именно так и обнаружил проблему с отображением капчи, глянул в демку — абсолютно такая же проблема. Можете обновить исходники?
yachmen
yachmen
Александр, закинул содержимое архива в корень — форма отображается корректно. Создал несколько подкаталогов на сайте, закинул содержимое туда — форма не отображается. Это потому что пути не абсолютные? Или еще какая то проблема?
Александр Мальцев
Александр Мальцев
Пути абсолютные. Если вам необходимо переместить форму, то для этого достаточно лишь переместить файл index.html в необходимую директорию и дать ему нужное имя. А весь каталог feedback так и оставить в корне.

Если вам необходимо по другому, то в этом случае надо будет настроить пути.
Аноним
Аноним
Произошла ошибка при отправке формы на сервер.
Что это за ошибка?
Александр Мальцев
Александр Мальцев
Если у Вас в браузере ошибок не возникло, то скорее всего это произошло при отправке письма:
// отправляем письмо
if ($mail->Send()) {
  $data['result']='success';
} else {
  $data['result']='error';
}
Удалите этот код и проверьте появляется ли ошибка.

Если Вы хотите настроить более детальный вывод ошибок, то их необходимо добавить в php (например, $data['error-send']):
// отправляем письмо
if ($mail->Send()) {
  $data['result']='success';
} else {
  $data['result']='error';
  $data['error-send'] = 'Произошла ошибка при отправке письма!';
}
А потом в файле script.js настройте их вывод в необходимое место:
else {
  // если сервер вернул ответ error, то делаем следующее...
  $('#error').text('Произошли ошибки при отправке формы на сервер.');
  // проверяем вернул ли сервер ошибку 'error-send' и если да, то добавим её к выводу
  if ($data['error-send']) {
    $('#error').html($('#error').html()+$data['error-send']);
  }
}
Т.е. это можно выполнить до какой-угодной деталлизации.
Artyom
Artyom
Блин, спасибо Вам Оооогроомное! ))
Все работает, все нормально! Буду всем советовать!
Скажите, а как можно добавлять и убирать поля?
И можно ли настроить отправку с формы, на три разных почтовых ящика?
Александр Мальцев
Александр Мальцев
Инструкцию по работу с полями, можете взять со станицы, на которой рассмотрено создание контактной формы с вложениями. Она расположена в секции «Руководство по добавлению полей в форму».
Для того чтобы отправить форму на 3 email адреса достаточно продублировать эту строчку ещё 2 раза:
$mail->AddAddress( 'email1@mail.ru' );
$mail->AddAddress( 'email2@mail.ru' );
$mail->AddAddress( 'email3@mail.ru' );
Artyom
Artyom
Извините за кучу вопросов, но возникло еще несколько:
1) Эта ссылка на «контактную форму с вложениями» подходит и для изменений этой контактной формы?
2) Я вот перенес форму на хостинг, все заработало. Но когда снес стили Bootstrap'а, форма выдает ошибку Post500 в .php файле. Это как-то связано с отсутствием Bootstrap'а?
3) Можно ли данный скрипт компилировать и минифицировать с остальными .js скриптами?

Заранее благодарен за быстрые ответы! Буду рекомендовать этот источник всем своим друзьям и знакомым! )
Александр Мальцев
Александр Мальцев
1. Да, в ней только добавлены алгоритмы для загрузки файлов на сервер.
2. Скорее всего снесли кроме Bootstrap что-то ещё. Bootstrap — это только оформление. Проверьте может ещё что-то удалили…
3. Да, можете скопировать содержимое в свой js-файл и сжать его.
Artyom
Artyom
Спасибо большое, сейчас буду разбираться!
Artyom
Artyom
Здравствуйте!
Спасибо за Ваш труд, но вот такая вот вышла ошибка, когда раскрыл проект на OpenServer, подскажите пожалуйста, что не так? Скриншот.
Александр Мальцев
Александр Мальцев
Скорее всего, вы неправильно указали путь к файлу process.php.
Чтобы проверить из коробки, скачайте архив формы обратной связи по ссылке в статье, распакуйте его и загрузите его в корень сайта (директорию feedback). После этого форма обратной связи будет доступна по ссылке протокол://имя_домена/feedback/index.html.
Аноним
Аноним
11 февраля 2016, 16:09 you wrote:
«Эти сообщения выдаёт встроенный валидатор браузера. Если браузер на английском языке, то и сообщения будут на английском.»

Действительно, переключил браузер на украинский, відповідає тепер на соловьїній, що "… має бути три".
Проблема вот какая:
Использую Вашу замечательную форму в сайте гуцульского журнала. Объяснить гуцулам (а их много, 2000 тис. тираж) как изменить язык бровзера = принципиально невозможно.

Нельзя ли «эти сообщения» принудительно перевести в теле капчи, чтобы они не зависисели ни от бровзера ни от языковых настроек?

Заранее благодарен, AndrewO
Александр Мальцев
Александр Мальцев
Используйте службу Google Translate API v2 чтобы перевести сообщения, которые поступают с сервера.
Документация: cloud.google.com/translate/v2/quickstart
Аноним
Аноним
Спасибо!
Аноним
Аноним
Александр!
Спасибо большое! По аналогии (благодаря Вашим ответам) удалось запустить родные формы с «родным» скриптом — forms.js и MailHandler-ом! Спасибо!
Теперь, когда соберусь с духом вставить в форму отправку файлов и каптчу — буду Вас «донимать» немного… :)

Спасибо!
Аноним
Аноним
добрый день. возникла проблема — необходимо добавлять разных адресатов в некоторой зависимости.
В форме добавила скрытый инпут
<input type="hidden" id="recipient" name="recipient" value="<?echo $academy_contact_email?>">
В script.js добавила получение значения этого поля
var recipient = $("#recipient").val();
formData.append('recipient', recipient);
в process.php
$mail->AddAddress($_POST['recipient']);
Отображается ошибка «Произошли ошибки при отправке формы на сервер.» В чем тут проблема может быть?
Александр Мальцев
Александр Мальцев
Всё ваши действия правильные. Попробуйте проверить, что у Вас подставляется вместо <?echo $academy_contact_email?>. Или для проверки замените этот php-код на обычное текстовое значение.
Аноним
Аноним
Александр, спасибо что оперативно реагируете, но сейчас в Вашей «демо формы обратной связи» так и не смог увидеть надпись «сообщение отправлено».( Вводил как и правильные по количеству символов поля, так и неправильные, но конечного результата так и не увидел… Но это может я «туплю»… Обращаюсь к пользователям: может еще кто попробует?
Аноним
Аноним
Александр, спасибо за пример. Есть вопрос:
в файле process.php есть проверка длины поля NAME (от 2 до 30), также проверка длины поля Message (от 20 до 500 символов).
Но если взять демо-версию отправки формы, то она отправляет (пишет «Сообщение отправлено») при name=a, email=a@a, message=a (т.е. по одному символу в поле Name и Message). Почему не срабатывают проверки на длину поля из process.php?
Александр Мальцев
Александр Мальцев
Поправил и внёс небольшие улучшения в скрипт. Проверяйте…
Аноним
Аноним
Присоединяюсь к числу выражающих огромную благодарность за Ваши труды, Александр!

Замечу, что у меня на PHP 7 с ходу не заработало — оказался не установленным модуль php-gd. Выдавало ошибку
PHP Fatal error:  Uncaught Error: Call to undefined function imagecreatefrompng() in /var/www/html/feedback/captcha.php:13\nStack trace:\n#0 {main}\n
Решается простой установкой (на примере Ubuntu):
apt-get install php-gd
и перезагрузкой апача
service apache2 reload
В случае с shared-хостингом, вероятно, необходимо обратиться к компании, предоставляющей услуги хостинга.

Так же хочу спросить — как сделать распознавание капчи нечувствительным к регистру?
Александр Мальцев
Александр Мальцев
На 61 строчке в файле process.php замените эту
if ($_SESSION["code"] != $captcha) {
на следующую
if (mb_strtolower($_SESSION["code"], 'UTF-8') != mb_strtolower($captcha, 'UTF-8')) {
Аноним
Аноним
Александр, спасибо.
То, что Вы ответили, я теоретически понял сразу, прочитав Вашу статью. В Вашем примере все файлы уже собраны — и script.js и .php и .css (но я правильно понимаю — .css и шрифты, например, нужны именно для Вашего варианта формы?).
Просто меня, как неспеца сбило с толка — Ваш файл index.html. Если я Вас правильно сейчас понял, то мне необходимо в скрипте script.js и в файлах .php — phpmailer и process точно прописать значения полей форм? Т.е, — value? Там, где это надо…
Т.е. в скрипте, например, где нужно прописать значение поля «name», я должен взять его отсюда:
<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>
?!
Или этого не достаточно (при условии, что скрипт подключится к странице, т.е. «пропишется», например, в contacts.html)? Поясните, пожалуйста, на пальцах, я не сайтостроитель и делаю не магазин, но очень бы надо…
И если на нескольких страницах формы, как к ним ко всем подключить?
Т.е. по сути 2 простых вопроса (простых для спецов) — КАК подключить и КАК подключить не одну форму, т.е. на разных страницах?!

Заранее — спасибо большое!
Александр Мальцев
Александр Мальцев
1. Подключить файл script.js ко всем необходимым страницам (который, например расположен в корне сайта).
<script src="/script.js"></script>
1.1. Минимальное содержимое файла без проверки:
// после загрузки веб-страницы
$(function() {
  // при отправке формы contactForm на сервер (id="contactForm")
  $('#contactForm').submit(function(event) {
    // отменяем стандартное действие браузера
    event.preventDefault();
    // создаём объект, который будет содержать данные для отправки
    var formData = new FormData();
    // добавить в formData значение поле name (id поля = name)
    // первый параметр - получаем значение поля
    // имя, под которым данное поле будет доступно в массиве $_POST на сервере
    formData.append($("#name").val(), name);
    // ... повторяем данное действие для всех необходимых полей
    // т.е. добавляем в formData все данные которые хотим отправить на сервер
      
    //отправляем данные на сервер (AJAX)
    $.ajax({
      //метод передачи запроса - POST
      type: "POST",
      //URL-адрес запроса (подключение файла process.php для обработки формы) 
      url: "/process.php",
      //передаваемые данные - formData
      data: formData,
      // не устанавливать тип контента, т.к. используется FormData
      contentType: false,
      // не обрабатывать данные formData (т.к. они уже и так обработаны объектом FormData)
      processData: false,
      // отключить кэширование результатов в браузере
      cache: false,
      //при успешном выполнении запроса
      success : function(data){
        // ... написать действия, которые будут отображаться пользоваетлю
        // в зависимости от полученного ответа с сервера
        // т.е. если пришёл один ответ, то значит то что форма отправилась
        // если другой, то что произошла ошабка и форма не отправилась
        // результат ответа сервера формируется в файле process.php (обычно с помощью if)
      },
      error: function (request) {
        // отобразить ошибку
      }        
    });
  });
});
Ваше основное действие — это добавление следующих строчек:
formData.append(значение_поля, имя_его_на_сервере);
Подключение файла php в этом скрипте осуществяется на строчке:
url: "/process.php"
2. В файле process.php написать то, что вы хотите сделать с данными формы (например, отправить их на почту).
<?php
  // отправляем данные формы на почту
  // включить файл PHPMailerAutoload.php
  require_once dirname(__FILE__) . '/phpmailer/PHPMailerAutoload.php';
  //формируем тело письма
  $output .= "Имя пользователя: " . isset($_POST['name']);
  // ... другие поля

  // создаём экземпляр класса PHPMailer
  $mail = new PHPMailer;
  $mail->CharSet = 'UTF-8'; 
  $mail->From      = 'от куда';
  $mail->FromName  = 'имя сайта';
  $mail->Subject   = 'Сообщение с формы обратной связи';
  $mail->Body      = $output;
  $mail->AddAddress('куда');
  // отправляем письмо
  $mail->Send();      
?>
В этом коде убраны все проверки, осталось только основное действие. Этот код использует библиотеку phpmailer.
Аноним
Аноним
Здравствуйте!
Спасибо за статью! Кое-что для себя усвоил. Но «свои варианты» пока нИАсилил, поэтому прошу помощи (увы, не спец...).
Скажите, пожалуйста, как сделать, чтобы мои формы — их 2 варианта — «включились» в работу? Ну, во первых, они, конечно, отличаются от Вашего примера, но это, наверное, не сильно важно — могу разобраться…
Код первой формы —
<div class="col-lg-8 col-md-8 col-sm-8 address">
                        <h2>Форма обратной связи</h2>
                        <form id="contact-form" class="contact-form">
                          <div class="success"> Сообщение отправлено! <strong>Мы ответим в ближайшее время.</strong> </div>
                          <fieldset>
                            <div class="coll-1">
                              <div class="txt-form">Name<span>*</span></div>
                              <label class="name">
                                <input type="text" value="Имя*:">
                                <span class="error">*Это невалидное имя. Заполните, пожалуйста, на латинице.</span> <span class="empty">*Поле обязательно к заполнению.</span> </label>
                            </div>
                            <div class="coll-2">
                              <div class="txt-form">Email<span>:</span></div>
                              <label class="email">
                                <input type="email" value="E-mail*:">
                                <span class="error">*Это невалидный email адрес.</span> <span class="empty">*Поле обязательно к заполнению.</span> </label>
                            </div>
                            <div class="coll-3">
                              <div class="txt-form">Phone:</div>
                              <label class="phone notRequired">
                                <input type="tel" value="Phone:">
                                <span class="error">*Это невалидный телефонный номер.</span> <span class="empty">*Поле обязательно к заполнению.</span> </label>
                            </div>
                            <div class="clear"></div>
                            <div>
                              <div class="txt-form">Comment<span>*</span></div>
                              <label class="message">
                                <textarea>Сообщение*:</textarea>
                                <span class="error">*Сообщение слишком короткое.</span> <span class="empty">*Поле требуется к заполнению.</span> </label>
                            </div>
                            <div class="clear"></div>
                          </fieldset>
                          <div class="buttons-wrapper clearfix"><a href="mailto:..." class="btn-link btn-link2" data-type="submit">отправить<span></span></a><strong>*ПОЛЯ ОБЯЗАТЕЛЬНЫЕ К ЗАПОЛНЕНИЮ</strong></div>
                        </form>
                    </div>
И, собственно, второй:
<form id="contact-form2" class="reservation-form">
                          <div class="success">Reservation form submitted! <strong>We will be in touch soon.</strong> </div>
                          <fieldset>
                            <div class="coll-1">
                              <div class="txt-form">name:<span></span></div>
                              <label class="name">
                                <input type="text" value="Name:">
                                <span class="error">*This is not a valid name.</span> <span class="empty">*Поле обязательно к заполнению.</span> </label>
                            </div>
                            <div class="coll-2">
                              <div class="txt-form">Email<span>:</span></div>
                              <label class="email">
                                <input type="email" value="E-mail:">
                                <span class="error">*Это невалидный email адрес.</span> <span class="empty">*Поле обязательно к заполнению.</span> </label>
                            </div>
                            <div class="coll-3">
                              <div class="txt-form">phone:</div>
                              <label class="arrival notRequired">
                                <input type="tel" value="Phone:">
                                <span class="error">*Это невалидный номер телефона.</span> <span class="empty">*Поле обязательно к заполнению.</span> </label>
                            </div>
                            <div class="coll-4">
                              <div class="txt-form">phone:</div>
                              <label class="Length of stay notRequired">
                                <input type="tel" value="Fax:">
                                <span class="error">*Это невалидный номер телефона.</span> <span class="empty">*Поле обязательно к заполнению</span> </label>
                            </div>
                            <div class="clear"></div>
                            <div>
                              <div class="txt-form">Comment<span>*</span></div>
                              <label class="message">
                                <textarea>Сообщение:</textarea>
                                <span class="error">*Сообщение слишком короткое.</span> <span class="empty">*Поле обязательно к заполнению.</span> </label>
                            </div>
                            <div class="clear"></div>
                          </fieldset>
                          <div class="buttons-wrapper clearfix"><a href="#" class="btn-link btn-link2" data-type="submit">послать<span></span></a><a href="#" class="btn-link btn-link2" data-type="reset">стереть<span></span></a></div>
                        </form>
По сути, они, вроде, одинаковые…
Но вот как их подключить? Из Вашей статьи понял, что нужен каталог feedback со всем необходимым. Потому как смотрю — в шаблоне его нет, соответственно — и script.js и process.php нет и т.д. Допустим, я скачаю Ваш пример — там это есть, но мне не очень понятно, как тогда поменять данную Вами форму на свои? У Вас файл index.html, а у меня основная форма в contacts.html и вторая — на других страницах… Где что прописывать? Как их подключить? Если Вам не очень трудно подсказать, конечно…
И ещё. Зашёл по ссылке почитать о том, как добавить вложение для форм. Ещё пока не разбирался детально — просто с отправкой бы разобраться, но хотел спросить — там универсальное решение? Т.е. от кода формы не зависит? А то это тоже будет головная боль, а очень надо!!!
Спасибо!
Всего доброго!
Александр Мальцев
Александр Мальцев
Вы привели только HTML формы, которые сами по себе работать не будут. Они просто выводятся, как и другой контент HTML документа. Для того чтобы они работали необходимо иметь как минимум серверный скрипт php, который будет получать данные формы и выполнять необходимые действия (например, отправлять форму на почту). Если вы хотите реализовать форму обратной связи без перезагрузки, то ещё понадобится JavaScript код (AJAX).
Насчёт структуры… Каталог feedback просто содержит файлы, необходимые для работы формы. Т.е. тут всё собрано в одном каталоге для удобства (просто скопируй и готово). Если вы хотите подключать форму обратной связи к нескольким страницах, то тут возможно потребуется более грамотная организация файлов.
Какое имя использовать вообще не важно (index.html или contacts.html), т.к. вы подключает всё к нему, а не его.

Вы можете использовать и свои формы. Тут это не важно. Самое главное — это название полей, формы и т.д. Т.е. то, что используют скрипты javascript и php. Название каждого файла подробно описано, т.е. вам необходимо только их грамотно подключить к своим файлам (contacts.html и т.д.) и всё. Тоже качается и вложений.
Аноним
Аноним
Александр, ещё раз огромное спасибо за форму! Просто супер!

Ещё один вопрос... В функционале присутствует файл «message.txt», куда автоматически записываются все отсылаемые формой данные. Подскажите, можно ли как-то безболезненно отказаться от этой функции (это наиболее приемлемый вариант) или же чтобы файл самоочищался через какой-то промежуток времени, скажем 1 раз месяц?
Александр Мальцев
Александр Мальцев
Откройте файл process.php и удалите из него следющий код:
//1. Сохрание формы в файл
$output = "---------------------------------" . "\n";
$output .= date("d-m-Y H:i:s") . "\n";
$output .= "Имя пользователя: " . $name . "\n";
$output .= "Адрес email: " . $email . "\n";
$output .= "Сообщение: " . $message . "\n";
if (file_put_contents(dirname(__FILE__).'/message.txt', $output, FILE_APPEND | LOCK_EX)) {
  $data['result']='success';
} else {
  $data['result']='error';         
} 
Аноним
Аноним
Александр, подскажите где можно изменить ограничение по отправляемому количеству знаков в сообщение? До 1000 знаков письма отправляются, а вот если больше, то «Произошли ошибки при отправке формы на сервер.».

Я ставлю форму для вопросов от своих пользователей, и, порой, они бывают довольно-таки объемными, так как в моей тематике вопросы идут с детальным описанием. Нужно хотя бы 3-5 тысяч знаков. Можно ли такое где-то указать, и в каких файлах?

Заранее благодарен.
Александр Мальцев
Александр Мальцев
В файле process.php верификация длины сообщения осуществляется с помощью кода (например, максимальную длину установить 20000):
//получить сообщение, которое ввёл пользователь
if (isset($_POST['message'])) {
  $message = $_POST['message'];
  if (!validStringLength($message,20,20000)) {
    $data['message']='Поле сообщение содержит недопустимое количество символов.';     
    $data['result']='error';   
  }      
} else {
  $data['result']='error';
} 
В файле index.html длина ограничивается атрибутом maxlength (например, 20000):
<textarea id="message" class="form-control" rows="3" minlength="20" maxlength="20000" required="required"></textarea>
Больше никаких ограничений нет. Если не поможет, то необходимо проверить настройки php. Например, настройку post_max_size = 10M.
Pastuh
Pastuh
Александр, а почему бы не использовать SMTP для отправки почты с формы обратной связи. Как правило все тоже самое, только люди могут подключить себе яндекс почту(бесплатный сервис), гугл почту(платный сервис), или настроить свой почтовый сервис(много заморочек).
Просто при отправке писем через php mail, чаще всего такие письма будут залетать в спам, что не есть приятно, и по итогу, мы получим финт конем, что какая ни будь почтовая система наш IP забанит, а вытаскивать его ой как тяжко. Ибо в данном случае у нас нет SSL сертификата, DKIM подписи, SPF запись вряд ли у домена настроена и тд и тп.

Просто я могу дописать ваш код, и скинуть сюда реализацию с SMTP, ну и мини гайдик как зарегистрировать доменную почту на яндексе. Просто мне кажется это бы дало больше плюсов пользователям.
Александр Мальцев
Александр Мальцев
Да, для сайта это лучше. Но это более сложно реализации. Конечно, любой владелец сайта в этом заинтересован, чтобы его письма не попали в спам. Но изначально не стал усложнять отправку писем через Яндекс.

Если у Вас уже есть готовое решение, то поделитесь. Многие пользователи будут Вам благодарны.
Аноним
Аноним
Здравствуйте! Спасибо за форму. Отлично всё реализовано!
Есть один момент, который я хотел бы попросить Вас подправить. Я-то разобрался с ним, а вот новички могут споткнуться на нем…

При скачивании и разархивации сборки формы (также и в варианте с модальным окном) у нас все файлы находятся в папке «feedback» в ней же лежит и файл index.html, а пути ко многим файлам и скриптам почему в кодах прописаны так:

<link rel="stylesheet" href="/feedback/css/bootstrap.min.css">
Соответственно сама форма (и её стили) по умолчанию не будет работать пока не поудаляешь /feedback/ во всех файлах. Возможно я что-то не так делал, но как бы я не пытался распаковать архив — итог один и тот же.

И если не сложно, подскажите можно ли как-то реализовать капчу таким образом, как в этой Вашей форме комментариев (вводить сумму чисел, а не набор букв)? А ещё чтобы была возможность указать галочкой пункт «Отправить копию письма себе на ящик».

Заранее благодарен!
Александр Мальцев
Александр Мальцев
По умолчанию пакет формы обратной связи должен располагаться в директории feedback, которую необходимо поместить в корневой каталог на сервере. Если файл index.html переименовать и перенести в другое место, то пути к файлам сохраняться (из-за их абсолютности) и всё будет работать. Это основной принцип размещения файлов.
Если нужно какое-то другое поведение, то тут не угадаешь. В этом случае придётся настраивать пути к файлам в зависимости от задачи.
Александр Мальцев
Александр Мальцев
Замена капчу на сумму двух цифр.
1. Изменить содержимое файла captcha.php на следующий:
<?php
session_start();
$minCaptcha = 1;
$maxCaptcha = 10;
$a = mt_rand($minCaptcha, $maxCaptcha);
$b = mt_rand($minCaptcha, $maxCaptcha);
$_SESSION['code'] = $a + $b;
header("Content-Type: text/html; charset=utf-8");
echo "Введите сумму " . $a . " + " . $b 
?>
2. В файл script.js внести следующие изменения:
2.1. Изменить captcha.length!=6 на !captcha.length, а captcha.length==6 на captcha.length.
2.2. После загрузки страницы добавить:
// отобразить код капчи
$.get("/feedback/captcha.php",function(data){
  $('#captcha').text(data);
});
2.3. В содержимое блока
else if ($data.result == "invalidCaptcha") {
добавить
// выводим новый код капчи
$.get("/feedback/captcha.php",function(data){
  $('#captcha').text(data);
});
3. В index.html блок капчи изменить на следующий:
<!-- Блок для ввода кода капчи -->
<div class="form-group has-feedback">
  <label id="captcha" for="captcha" class="control-label"></label>
  <input id="text-captcha" name="captcha" type="text" class="form-control" required="required" value="" autocomplete="off" minlength="1">
  <span class="glyphicon form-control-feedback"></span>
</div>
Александр Мальцев
Александр Мальцев
Добавление чекбокса «Отправить копию письма себе на ящик».
В index.html после блока ввода капчи добавить:
<div class="checkbox">
  <label>
    <input id="copymail" type="checkbox"> Отправить копию письма себе на ящик
  </label>
</div>
В файл script.js после кода
//получаем капчу, которую ввёл пользователь
var captcha = $("#text-captcha").val();
ввести следующий
//получаем значение чекбокса "Отправить копию письма"
var copymail = $('#copymail').prop('checked');}
В файл process.php после строчки
$mail->AddAddress( 'myemail@mail.ru' );
необходимо вставить следующие:
if (isset($_POST['copymail'])) {
  if ($_POST['copymail']==true) {
    $mail->AddAddress( $email );
  }
}
Александр Мальцев
Александр Мальцев
Бесплатно скачать готовую форму обратной связи с цифровой капчей a+b и флажком для отправления копии письма себе на ящик можно с помощью следующей ссылки:
feedback with number captcha and checkbox
Аноним
Аноним
Огромное Вам спасибо, Александр! Мира Вам, счастья и богатства!
Виталий
Виталий
что-то не работает, все равно не отправляет копию на вторую почту var copymail = $('#copymail').prop('checked');} убирал скобку в конце }
Александр Мальцев
Александр Мальцев
Может быть, у вас браузер js-скрипт закэшировал. Попробуйте это выполнить в браузере в режиме инкогнито.
Аноним
Аноним
Здравствуйте Александр.

Подскажите пожалуйста в чём может быть проблема? Установил вашу форму обратной связи всё работает отлично :-) но появилась не большая не приятность заметил сегодня.Дело в том что ваш стил формы влияет на мои стили сайта не могу понять по чему, хотя ваш файл стилей вынесен в другую папку, но при установке кода подключения стилей формы
на самой страничке обратной связи не много падают мои стили, как решить этот вопрос.
Александр Мальцев
Александр Мальцев
Здравствуйте.
Самый простой способ — это подключить свои стили в конце (после стилей формы обртаной связи).
Если это не сработает, то можно самому оформить форму. Для этого удалить link c bootstrap.css и скопировать в ваш файл недостоющие стили из bootstrap.css или консоли разработчика браузера.
Если разбираться не хочется, то можно поступить проще, например, вставить форму обратной связи через iframe.
<iframe src="index.html" width="700" height="1000" frameborder="0"></iframe>
Где index.html — путь до файла, где расположена форма обратной связи.
Аноним
Аноним
Здравствуйте Александр.
Отличный скрипт формы обратной связи, большое спасибо за ваш труд.
Подскажите пожалуйста в чём может быть проблема? после установки кода формы в страничку, форма по чему то уходит в право страницы, а не по центру как должна быть.
где в стилях поправить расположение, или размер формы изменить.
Александр Мальцев
Александр Мальцев
Положение формы определяется 3 строчкой. При этом она занимает всю доступную ширину. По умолчанию она занимает 1/2 ширину этого контейнера (если ширина страницы >=768px) и всю ширину (если ширина страницы <768px). При этом (если ширина страницы >=768px), то установлен отступ слева, равный 1/4 ширине контейнера.
<div class="container">
  <div class="row">
    <div class="col-sm-6 col-sm-offset-3">
      <!-- Форма ... -->
    </div>
  </div>
</div>
При желании эту строчку можно изменить, задать ей фиксированную ширину или что-то другое.
<div style="width: 500px; margin: 0 auto;">
  <!-- Форма ... -->
</div>
Более подробно ознакомиться с сеткой Bootstrap можно в теме: Как работает сетка Bootstrap.

Но скорее всего это связано с тем, что Вы хотите вставить её куда-то в страницу. Для этого Вам необходимо скопировать её так (без верхних контейнеров):
<div class="col-sm-6 col-sm-offset-3">
  <!-- Форма ... -->
</div>
Аноним
Аноним
Здравствуйте, Александр, спасибо вам за ваш просветительский труд. Вопрос такой, по умолчанию, при удачной отправке, выводится сообщение «Ваше сообщение успешно отправлено», но форма не перезагружается и для отправки нового сообщения приходится перезагружать страницу, это так задумано или у меня что-то не правильно работает? Вставлял форму через iframe
Александр Мальцев
Александр Мальцев
Здравствуйте. Так было и задумано.
Если Вам необходимо обеспечить возможность отправлять несколько сообщений без перезагрузки страницы, то необходимо очищать форму и показывать сообщение (например, в модальном окне).
В форме обратной связи сообщение об успехе в модальном окне отображается так.
Скачать сборку можно по следующей ссылке:
yadi.sk/d/oAcdsgL5uCZze
Аноним
Аноним
Добрый день! Отличный статья, отличный код — каждый шаг закоментирован!!! Браво… Но, блин, не обновляется каптча(( Всё проверил, пути исправил на абсолютные("/") и лежат на своих местах… В консоли ошибка в файле script.js:
ReferenceError: $ is not defined
<анонимная>

Не пойму где ошибка и как исправить(((
Александр Мальцев
Александр Мальцев
Здравствуйте.
Эта ошибка говорит о том, что у Вас не подключена библиотека jQuery. Необходимо её подключить.

Но зачем там что-то подправлять (в архиве лежит готовая сборка). Ваша задача скачать архив, распаковать его, и залить готовый каталог feedback на сервер.
После этого в браузере набираете:
имя_сайта/feedback/
Примечание: в архиве находится сборка feedback, работающая на последней jquery (3.1.0) и bootstrap (3.3.7). Также в ней поправлены некоторые моменты, оставленные в комментариях пользователями сайта.
Аноним
Аноним
Спасибо большое! Всё заработало… Было подключено jquery.easing-1.3.js — подумал этого достаточно =( Помутнение какое-то, не иначе ))
Аноним
Аноним
Попробуйте перед captcha.php добавить «feedback» получится feedback/captcha.php Капча появится, только форма всё равно не работает…
У меня проблема в том что я нажимаю «отправить», страница обновляется и дописывается адрес name=Тест&email=dfgdfg%40masd.ru&captcha=3n862n и всё. Дальше никак не идёт, может быть я что-то пропустил? кстати галочка о том что я верно ввёл капчу тоже не появляется, видимо проблема именно в ней.
Аноним
Аноним
Не понимаю ничего (
content-type почему-то text/html
Хотя в самом php файле caprtcha прописано:
header('Content-type: image/png');    
Что делать? Скриншот.
Аноним
Аноним
Хелп, каптча не работает

надпись в консли:
GET _http://n1foto.com/captcha.php 500 (Internal Server Error)

путь проверил, файл лежит по месту. Подскажите, что делать?
Александр Мальцев
Александр Мальцев
Это происходит, потому что файл «captcha.php» имеет не правильный формат. Данный файл необходимо сохранить в кодировке UTF-8 без BOM. Иначе к файлу добавляются дополнительные символы, и он становится не image.
Т.е. в Вашем примере значение Content-Type равно:
Content-Type:text/html; charset=UTF-8
А должно быть так.
Ваша задача сводится в сохранении файла в каком-нибудь текстовом редакторе (например, Visual Studio Code) с кодировкой UTF-8 без BOM.
Аноним
Аноним
Александр, спасибо за ответ.

Проверил кодировку, она и есть — UTF-8 без BOM…

Александр Мальцев
Александр Мальцев
Проверьте наличие шрифта oswald.ttf в директории:
$font = dirname(__FILE__).'/oswald.ttf';
Если не поможет, то необходимо смотреть логи, т.е. искать из-за чего происходит ошибка.
Аноним
Аноним
Приветствую.

Форма работает, все хорошо, но не всегда капча вписывается в дизайн. Возможно ли прикрутить к этой форме гулову ReCaptcha?
Александр Мальцев
Александр Мальцев
Напишу как это сделать в виде отдельной статьи.
Аноним
Аноним
Отлично. Было бы не плохо
Аноним
Аноним
Здравствуйте… Спасибо большое за вашу интересную статью. У меня проблема такова все работает за исключением того что нет самой каптчи…
Аноним
Аноним
Спасибо за форму. Всё прекрасно работает. Но почему-то, после показа сообщения об успешной отправке, при обновлении страницы форма остается с заполненными полями. Как сделать, чтобы введенная ранее информация не сохранялась?
Александр Мальцев
Александр Мальцев
Спасибо за отзыв. Для этого необходимо добавить к форме атрибут autocomplete=«off»:
<form id="messageForm" autocomplete="off">
...
</form>
Аноним
Аноним
Подскажите, пробую изменить форму, добавив к ней группу радио-инпутов (всего два), с обычными ответами: «да» и «нет».
<div class="form-group has-feedback">
     <label for="gurt" class="control-label">Необходимость поселения в общежитие:</label>
     <input type="radio" id="gurt" name="gurt" class="radio-inline" value="Yes"><label for="gurt1"> Да</label>
     <input type="radio" id="gurt" name="gurt" class="radio-inline" value="No"><label for="gurt2"> Нет</label>
<span class="glyphicon form-control-feedback"></span></div>
Так вот. Не передаются в письмо данные выбора этих полей. Вообще передаются, но только одно — первое в группе. Т.е. выбор не действует. Где у меня ошибка? Дополнения внес в файлы verify.php и script.js.
Аноним
Аноним
Я так и не смог настроить формирование капчи. Форму установил, пути вроде везде поправил, но текст капчи не отображается. проверил в консоли разработчика, никаких ошибок нет. скрипт отрабатывает и по иждее должен вернуть сформированное изображение…
подскажите, может кто сталкивался с этим?
Аноним
Аноним
отключил капчу, но и без нее не отрабатывает. но появилась новая ошибка в консоли:
Uncaught TypeError: Cannot read property 'length' of undefined(anonymous function) @ script.js:1m.event.dispatch @ jquery-1.11.3.min.js:1r.handle @ jquery-1.11.3.min.js:1
Аноним
Аноним
Разобрался) Спасибо за статью!
Аноним
Аноним
Как дела с доработкой, можно надеяться?
Александр Мальцев
Александр Мальцев
Да, можно. В ближайшее время сделаю.
Александр Мальцев
Александр Мальцев
Это реализовано в следующей статье: Форма обратной связи для сайта.
Аноним
Аноним
Заранее спасибо.
Аноним
Аноним
Спасибо за рабочую форму, отлично работает и файлы отправляются, и в случае ошибки сообщение выводит, и при отправке иконку ожидания поставил — за это отдельное спасибо.
Есть две просьбы, нельзя ли прикрутить фильтр расширений отправляемых файлов по маске и отправку нескольких файлов с ограничением по длине и количеству отправляемых файлов?
Александр Мальцев
Александр Мальцев
Хорошо, рассмотрю такую возможность.
Аноним
Аноним
потерто…
Аноним
Аноним
я скачал папку с архивом, а как ее установить на сайт?
Александр Мальцев
Александр Мальцев
Тут не надо ничего устанавливать. Форму обратной связи копируете из файла index.html в необходимую страницу. Остальные файлы просто копируете в структуру Вашего сайта. После этого проверяете пути и при необходимости изменяете.
Аноним
Аноним
Александр, добрый день.
Установил форму, но почему то не отображается что письмо отправлено(не отправлено)
Хотя письма приходят все нормально

С кодировкой вроде бы все хорошо.

Вот что пишет закладка response

Warning: session_start(): Cannot send session cache limiter — headers already sent (output started at /var/www/user/data/www/ХХХХ/feedback/verify.php:1) in /var/www/user/data/www/ХХХХ/feedback/verify.php on line 3
success

ХХХХ русский сайт
Александр Мальцев
Александр Мальцев
Сохраните файлы так, чтобы они имели кодировку UTF-8 без BOM.
Михаил
Михаил
Здравствуйте, спасибо за урок и подробные ответы на вопросы.
У меня есть ошибки, с которыми разобраться не получилось пока.

1. В HTML форме на сайте, на 58 строку, ругается ValidatorW3 (в демо это 63 строка) Есть способ исправить?

2. В Safari выскакивает ошибка, в папке /css/bootstrap.min.css.map — нет такого файла. Есть без .map -нужен или не нужен он?
Александр Мальцев
Александр Мальцев
Код HTML поправил на соответствие стандарту.
Файл с расширением map используется только для отладки. Скорее всего в Safari в инструментах разработчика у Вас включена соответствующая опция (CSS source maps). Если Вы не собираетесь настраивать bootstrap.min.css, то он не нужен.
Аноним
Аноним
Здравствуйте! Установила форму, поправила пути, с капчей что-то не получается. Фоновое изображение есть, а символы которые надо ввести не отображаются. Что я делаю не так?
Александр Мальцев
Александр Мальцев
Проверьте, скорее всего у Вас возникают проблемы с функцией php imagettftext. Данная функция предназначена для рисование текста на изображении шрифтом TrueType.
Аноним
Аноним
Не рисует капчу, то есть фон есть, а символов нет… В консоле ошибок нет, ответ сервера 200.
В чем проблема может быть и куда копать?

И как вообще можно отключить капчу?
Аноним
Аноним
_http://fs-db.ru/feedback/ я не вижу ошибок в консоле, кроме кривой кодировки в комментариях
Александр Мальцев
Александр Мальцев
Вам надо смотреть файл captcha.php.
Аноним
Аноним
Добрый день, сколько не старался я внести изменения для отправки файла, так ничего и не получилось ( если вам не трудно можете описать подробнее изменение скрипта. Спасибо!
Аноним
Аноним
На сколько я понимаю конкретно вот эта строка отправляет данные на почту, но о каком то прикрепленном файле тут речи не идет
$success = mail($emailTo, $subject, $body, "From: mail@mail.ru \r\n");
Александр Мальцев
Александр Мальцев
Использовать этот комментарий:
itchief.ru/bootstrap/feedback-form#comment-1766

Загрузку на сервер файла сделал в вышепредставленном комментарии, а про отправку забыл.

Для этого необходимо изменить код файла verify.php.
Для отправки почты вместо функции mail будем использовать скрипт PHPMailer.
github.com/PHPMailer/PHPMailer
1. Пример с вложением:
<?php
// включить файл PHPMailerAutoload.php
require('путь/до/PHPMailerAutoload.php');
//открываем сессию
session_start();
//получить имя, которое ввёл пользователь
$name = $_POST["name"];
//получить email, которое ввёл пользователь
$email = $_POST["email"];
//получить сообщение, которое ввёл пользователь
$message = $_POST["message"];
//если пользователь правильно ввёл капчу то
if ($_SESSION["code"] == $_POST["captcha"]) {
  //формируем тело письма
  $bodytext = "--------------------------------------\n";
  $bodytext .= date("Y.m.d H:i")."\n";
  $bodytext .= "Содержимое заполненных пользователем полей:\n";
  $bodytext .= "Имя: ".$name."\n";
  $bodytext .= "Email: ".$email."\n";
  $bodytext .= "Сообщение: \n".$message."\n";
  // создаём экземпляр класса PHPMailer
  $mail = new PHPMailer;
  
  $mail->From      = 'email@mysite.ru';
  $mail->FromName  = 'Имя сайта';
  $mail->Subject   = 'Сообщение с формы обратной связи';
  $mail->Body      = $bodytext;
  $mail->AddAddress( 'myemail@mail.ru' );

  if ( $_FILES['file']['error']==0 ) {
    move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/'.$_FILES['file']['name']);
    // прикрепляем файл
    $mail->addAttachment('uploads/'.$_FILES['file']['name']);
  }
  // отправляем письмо
  $success = $mail->Send();

  //Если действия были успешны, то отправляем "success"
  if ($success) {
    echo "success";
  }
  //иначе отправляем "invalid"
  else {
    echo "invalid";
  }
}
else {
  //если пользователь ввёл неправильную капчу, то отправляем "invalidcaptcha"
  echo 'invalidcaptcha';
}
2. Файл в качестве ссылки:
  $bodytext = "--------------------------------------\n";
  $bodytext .= date("Y.m.d H:i")."\n";
  $bodytext .= "Содержимое заполненных пользователем полей:\n";
  $bodytext .= "Имя: ".$name."\n";
  $bodytext .= "Email: ".$email."\n";
  $bodytext .= "Сообщение: \n".$message."\n";
  $mail = new PHPMailer;
  if ( $_FILES['file']['error']==0 ) {
    move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/'.$_FILES['file']['name']);
    $file = $_FILES['file']['name'];
    $path = 'uploads/'.$file;
  }
  // добавляем ссылку на файл
  $bodytext .= 'Файл:\n'.'<a href="http://mysite.ru/'.$path.'">'.$file.'</a>';
  $mail->From      = 'email@mysite.ru';
  $mail->FromName  = 'Имя сайта';
  $mail->Subject   = 'Сообщение с формы обратной связи';
  $mail->Body      = $bodytext;
  $mail->AddAddress( 'myemail@mail.ru' );

  $success = $mail->Send();
Аноним
Аноним
Добрый день.
Спасибо, все работает. А как сделать отправку к примеру 3-х файлов — нужно сделать у них name=files[]?

Также у меня почему-то на хостинге от NIC.ru ответ при отправке success? но часть скрипта, которая убирает класс hidden не срабатывает. То есть форма уходит, но на появляется сообщение об успешности отправки(((
Аноним
Аноним
Здравствуйте! Установила форму на хостинге всё работает письма доходят, но при отправки сообщения не выводится надпись, что оно отправлено, т.е. — «Внимание! Сообщение отправлено.» — не появляется. Что надо сделать? Спасибо.
Александр Мальцев
Александр Мальцев
Аноним
Аноним
У меня картинка-капча не отображается никак не пойму с чем связано? Как решить проблему?
Аноним
Аноним
Вопрос снимаю, на хостинге все работает. Отлично. Спасибо.
PaveL
PaveL
Доброго времени суток, большая благодарность за уроки.
Реализовал форму на сайте, все отправляет как нужно. Но заметил следующую вещь — с локального сервера, когда тестирую, при нажатии отправить письмо отправляется и появляется надпись — «Спасибо! Ваше письмо отправлено». Но вот выгружая сайт на хостинг и заполняя всю туже форму, при нажатии на отправить — письмо отправляется, но надпись «Спасибо! Ваше письмо отправлено» не появляется, а вся форма остается и заполненные поля отмечены галочками. Вот и задумался с чем это связано, буду благодарен за совет.
С Денвера все отлично! Вот скриншот.
С Хостинга ( — скриншот.
Александр Мальцев
Александр Мальцев
Нажать в браузере клавишу F12->Network->verify.php->вкладка «Response». Посмотреть какой приходит ответ. Но, это не success. Т.е. возникает какая-то ошибка в файле verify.php (Например, хостинг не предоставляет доступ к функции mail. Это очень характерно для бесплатных хостингов — они запрещают рассылать письма) или в какой-то другой строчке… Надо, анализировать…

Также к скрипту в статье можно добавить следующий код:
//если получен ответ invalid, то значит произошла ошибка при отправке данных
if (text == "invalid") {
  //скрыть форму обратной связи
  $('#messageForm').hide();
  //изменить содержимое элемента, имеющего id msgSubmit
  $('#msgSubmit').html('<strong>Внимание!</strong> Сообщение не отправлено. Попробуйте позже');
  //удалить класс hidden
  $('#msgSubmit').removeClass('hidden');
}
Так как хостинге, хоть и очень редко, но бывают сбои. Можно пользователя уведомить о том, что произошла какая-то ошибка и попросить его отправить данную форму позже.
oleg
oleg
Александр добрый день.
Подскажите куда конкретно прописать данный код?
И еще. Если произойдет какая-то ошибка при отправлении письма, код сработает?
Спасибо
Александр Мальцев
Александр Мальцев
Код необходимо поместить в то же место, где мы обрабатываем и другие ответы от сервера.
success : function(text) {
  //если получен ответ invalid, то значит произошла ошибка при отправке данных
  if (text == "invalid") {
    //скрыть форму обратной связи
    $('#messageForm').hide();
    //изменить содержимое элемента, имеющего id msgSubmit
    $('#msgSubmit').html('<strong>Внимание!</strong> Сообщение не отправлено. Попробуйте позже');
    //удалить класс hidden
    $('#msgSubmit').removeClass('hidden');
  }
  //если получен ответ success, то значит данные отправлены
  if (text == "success") {
    //скрыть форму обратной связи
    $('#messageForm').hide();
    //удалить у элемент, имеющего id msgSubmit, класс hidden
    $('#msgSubmit').removeClass('hidden');
  }
Конечно, будет.
PaveL
PaveL
Александр, но дело в том что письма с хостинга приходят тут проблем нет, проблема в том что форма не принимает вид как не Денвере (появляется надпись — «Спасибо! Ваше письмо отправлено»). Всю голову сломал ) так и не могу понять в чем дело что я делаю не так? и сделал чтобы сообщение которое отправляют в файл «message» записывался, тоже все работает… а вот просто не пишет что письмо отправлено и не сворачивается форма вообщем. Хостинг не бесплатный, все поддерживает. Просто не понятно, могу выложить пример для наглядности, буду очень благодарен за дельный совет.
PaveL
PaveL
Вопрос снят, долго искал проблему и как говорится кто ищет тот находит )) проблема заключалась в кодировке на хостинге, принудительно в параметрах выставил и все заработало. Очень благодарен за уроки. А на таких запинках все детально изучаешь и разбираешься во всем, оно и к лучшему наверное… всем удачи! Спасиб что не оставили мой вопрос без внимания.
Аноним
Аноним
Привет, почему капчу не выводит просто синий квадратик?
Александр Мальцев
Александр Мальцев
Открывай в браузере консоль разработчика и изучай сообщения (ошибки) во вкладке Network и Console.
Андрей
Андрей
Спасибо за код. Скачал, откорректировал пути и всё заработало. Очень круто!
А возможно-ли добавить индикатор прогресса, который будет крутиться после нажатия «Отправить» до момента появления сообщения об успешной отправки. А то этот промежуток времени непонятно происходит-ли что-нибудь или нет.
Александр Мальцев
Александр Мальцев
Сделать можно, но насколько это актуально. Время замерял?
Например, на самом простом хостинге (специально замерил):
— запрос без вложений: 0.3 секунды;
— запрос с файлом 4 Мб: 3-4 секунды.
Т.е. такую вещь актуально делать если есть вложения более 3Мб.
Сделать можно так:
1. В форме немного изменяем блок с кнопкой submit на:
<!-- Кнопка, отправляющая форму по технологии AJAX --> 
<div class="pull-right">
  <img id="loading" src="feedback/5.gif" style="margin-right: 10px;" class="hidden">
  <button type="submit" class="btn btn-primary">Отправить сообщение</button>
</div>
2. В JavaScript добавить перед success:
//при успешном выполнении запроса
beforeSend: function () {
  $('#loading').removeClass('hidden');
},
complete: function () {
  $('#loading').addClass('hidden');
},
Вращающуюся иконку (изображение) можно скачать с сайта _http://preloaders.net/en/search/rotating. Размер иконки желательно установить 34px.
Андрей
Андрей
Я для начала на «домашнем» сервере страницы верстаю, у меня на нём письмо без вложений уходит на 3-4 сек, вот и заметил «пустоту» действий. Значок вставил, теперь всё отлично стало. Спасибо.
Аноним
Аноним
Добрый день!
Детально все прочитал, столкнулся с проблемой такой:
в текстовый файл запись осуществляется, а при другой настройке на почту письма не приходят! Подскажите в чем проблема
Александр Мальцев
Александр Мальцев
Посмотреть работает ли функция mail на хостинге.
Аноним
Аноним
Спасибо за скрипт!
Подскажите, а как убрать капчу?
А защиту сделать с помощью скрытого поля?
Аноним
Аноним
Для того, чтобы убрать капчу из этой формы, Вам нужно убрать весь код, отвечающий за ее вывод в html коде формы (в примере строки 52-61)
А далее в файле script.js убрать строки, отвечающие за ее проверку (в примере строки 37-55) и убрать закрывающую на строке фигурную скобку на строке 100
А затем в файле verify.php убрать условие, проверяющее капчу: строки 11 и 42-46.
Александр Мальцев
Александр Мальцев
Добавить к форме скрытое поле:
<input type="hidden" id="robots" name="robots" value="">
В файле verify.php необходимо обработку форму производить только после того, если данное поле пустое:
<?php
if($_POST['robots'] = '') {
  //обработка формы
}
?>
Можно, также сделать немного по другому. Например, после загрузки страницы, выполнять скрипт, который будет изменять значение данного поля на нечто другое.
$(function() {
  setTimeout(function() {
    document.getElementById('robots').value='CODE';
  },5000);
});
Ну соответственно и скрипт поменять:
if (!empty($_POST['robots']) && ($_POST['robots']=='CODE')) {
  //обработка форма
};
Спам роботы используют сложные алгоритмы, которые способны обойти различную защиту. Поэтому в первую очередь стоит подумать об усилении защиты, чем об её упрощении. Так чем сайт будет более популярен, тем больше шанс попасть под спам атаку…
oleg
oleg
Александр, здравствуйте.
Еще такой вопрос. Как расширить немного поля, чтобы текст поместился полностью, и чтобы поля были ровными.
Сейчас мои поля выглядят вот так.
Имя и контактный телефон урезан
Убирал свойство в файле «bootstrap.min.css»:
.form-control {
  display: block;
}
Поля показываются, но при этом разбросанные. Мне надо немного их расширить?
Спасибо.
Александр Мальцев
Александр Мальцев
Попробуйте изменить значение отступа справа.
form-control {
  padding-right: 6px !important;
}
oleg
oleg
Александр, добрый день, проблема не решилась.
В результате, такой результат: скриншот
Текст-подсказка снова урезаны.
Александр Мальцев
Александр Мальцев
Тут вариантов много. Можно, например, расстояние между блоками уменьшить или что-то другое сделать. Ещё зависит от того адаптивная у Вас форма или нет.
Тут желательно данную ситуацию представить на jsfiddle.
Аноним
Аноним
Александр, здравствуйте. Спасибо за материал.
Подскажите как передать параметром из index.html-файла
электронный (несколько электронных) адрес для отправки в файл verify.php.
Это нужно когда на сайте есть несколько форм по отправке обратного адреса.
Спасибо
Александр Мальцев
Александр Мальцев
Спасибо, Олег.
Можно использовать скрытые поля в форме:
<input type="hidden" name="sendemail" value="name1@mail.ru,name2@mail.ru">
А в файле verify.php их получать и подставлять в функцию mail:
$sendemail = $_POST["sendemail"];
$success = mail($sendemail, $subject, $body, "From: myemail@mail.ru \r\n");
oleg
oleg
Получилось только нужно написать так
<input type="hidden" id="sendemail" name="sendemail" value="name1@mail.ru,name2@mail.ru"> 
и в файле script.js дописать соответственно
спасибо
Аноним
Аноним
Спасибо!
А как отправлять сразу на сколько $emailTo?
Александр Мальцев
Александр Мальцев
Через запятую:
$emailTo = 'email1@mail.ru'.', ';
$emailTo.= 'email2@mail.ru';
Аноним
Аноним
Здравствуйте. Большое спасибо за урок. Прям спасли =)
Не подскажете, как в файле verify.php указать кодировку для письма? А то некоторые почтовые клиенты ругаются.
Спасибо.
Александр Мальцев
Александр Мальцев
Здравствуйте.
Попробуйте так:
//7. Отправляем на почту
$header = "MIME-Version: 1.0\r\n";
$header.= "Content-Type: text/html; charset=UTF-8\r\n";
$header.= "From: myemail@mail.ru\r\n";
$success = mail($emailTo, $subject, $body, $header);
Аноним
Аноним
Спасибо, сработало. Только теперь перенос строк отключился, но это мелочи =)
Аноним
Аноним
Александр, огромное спасибо вам за форму. У меня, как и у Ивана была проблема с кодировкой. Дописал предложеные вами строчки, теперь проблем нет, но отключился перенос строк, все сплошным текстом. Подскажите в чем может быть проблема?
Аноним
Аноним
Сам отвечу на свой вопрос. Поменял Content-Type: text/html на Content-Type: text/plain и текст стал нормально переноситься.
Аноним
Аноним
Добрый день.

Можно ли, добавить в форму
отправку файлов input type=«file»?
Александр Мальцев
Александр Мальцев
Здравствуйте.
Для этого придется произвести следующие изменения.
1. В файле index.html:
<!-- Добавить к форме атрибут enctype="multipart/form-data" -->
<form id="messageForm" enctype="multipart/form-data">
...
<!-- Ну и собственно разместить сам элемент -->
<input type="file" name="image" id="image" value="">
2. В файле verify.php (например, перед строчкой 30 — отправкой на почту):
//сохраняем исходный путь к файлу в переменную
$sourcePath = $_FILES['file']['tmp_name'];
//перемещаем файл в папку uploads, если ошибок нет
if ( 0 < $_FILES['file']['error'] ) {
  echo 'Error: ' . $_FILES['file']['error'] . '
';
}
else {
  move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/'.$_FILES['file']['name']);
}
3. В файле script.js немного изменяем скрипт:
if (formValid && captcha.length==6) {
  var name = $("#name").val();
  var email = $("#email").val();
  var message = $("#message").val();
  var captcha = $("#text-captcha").val();
  // изменения
  var file_data = $('#image').prop('files')[0];  
  var form_data = new FormData();                  
  form_data.append('file', file_data);
  form_data.append('name', name);
  form_data.append('email', email);
  form_data.append('message', message);
  form_data.append('captcha', captcha);
  //конец изменений
  $.ajax({
    type: "POST",
    url: "/feedback/verify.php",
    //изменения
    data: form_data,
    contentType: false,
    processData: false,
    cache: false,
    //конец изменений
    success : function(text){
      if (text == "success"){
        $('#messageForm').hide();
        $('#msgSubmit').removeClass('hidden');
      }
      ...
Ну и конечно создать на сервере необходимые каталоги.
Аноним
Аноним
Странно, все сделал как Вы написали — само письмо приходит, но без вложения. Подскажите почему может так получиться?
Александр Мальцев
Александр Мальцев
Ответ в этом комментарии:
itchief.ru/bootstrap/feedback-form#comment-20755
Аноним
Аноним
Здорово подключил все работает
отправляется как нужно
но сначала не работало
P.S
поправил пути к файлам и все забартало
Аноним
Аноним
Поставил форму на сайт, все работает отлично, но скрытые надписи "Внимание, сообщение отправлено!" и "Пожалуйста, введите указанный на изображении код:" всегда видны перед отправкой. То есть как правила они должны быть скрытыми, а на сайте всегда видны перед input-ами и после каптчи.

Спасибо.
Александр Мальцев
Александр Мальцев
Во-первых скрыта только первая надпись. Для этого используется класс Bootstrap hidden:
<!-- Сообщение, отображаемое в случае успешной отправки данных -->
<div class="alert alert-success hidden" role="alert" id="msgSubmit">
<strong>Внимание!</strong> Сообщение отправлено.
</div>
Если не работает, то проверьте свои стили.
Аноним
Аноним
А не подскажете какая будет строка в файле .css этот класс Bootstrap?
Александр Мальцев
Александр Мальцев
#msgSubmit {
  display: none !important;
}
Аноним
Аноним
Спасибо за статью!
Но есть одна проблемка… Делаю сайт на самописном движке. На главной странице все работает, а вот на других страницах ничего не работает: капча выводится, но не обновляется; сообщение не отправляется, получается не срабатывает JS. Код вынесен в отдельный файл и подключатся ко всем страницам.
Аноним
Аноним
Еще добавлю, что использую ЧПУ. Скорей всего с этим связано…
Аноним
Аноним
У меня была такая же проблема.
Открыл стили bootstrap.min.css и заменил все url(../fonts/glyphicons-... на url(http://mysite.com/mail/fonts/glyphicons-... и все получилось.

Удачи.
Александр Мальцев
Александр Мальцев
Измени пути на абсолютные (/..).
Аноним
Аноним
это я уже сделал давно. jquery отрабатывает, все картинки отображаются, а ajax в никакую…
Аноним
Аноним
Простите…
перекодировал без BOM… полет нормальный!
Аноним
Аноним
Письма теперь отправляет (если в адресе было admin@mysite.ru, то не работало)
А вот с кодировкой проблема, что в форме, так и в сообщении
Как быть?
Аноним
Аноним
все поставил как написано, НО текст весь ?????, а не буквы (не понимает русский)
И сообщения не доходят!
В текстовой файл пишет, но опять все внутренние названия ??????, а не буквы (не понимает русский)
Аноним
Аноним
Привет, подскажи, а можно ли всплывающие подсказки о неверном заполнении полей показывать на английском языке? если да то как? не нашел откуда он эти фразы берёт «Заполните это поле», «Адрес должен содержать....» и т.д.
И Ещё уменьшил количество символов до 4 в файле
captcha.php
$captchastring = substr(str_shuffle($captchastring), 0, 6);
поменял на
$captchastring = substr(str_shuffle($captchastring), 0, 4);

Но подсказка по прежнему хочет чтобы я 6 символов вводил, где ещё нужно править?
Александр Мальцев
Александр Мальцев
Эти сообщения выдаёт встроенный валидатор браузера. Если браузер на английском языке, то и сообщения будут на английском.
Это необходимо поменять ещё в HTML файле в следующей строчке (59):
<input id="text-captcha" name="captcha" type="text" class="form-control" required="required" value="" minlength="4" maxlength="4">
И в файле script.js (строчки 42 и 55):
if (captcha.length!=4) {
if (formValid && captcha.length==4) {
Аноним
Аноним
Александр, форма заработала, ничего не менял, как-то так, сам не понял, спасибо!
Аноним
Аноним
Поставил форму на сайт с html, подобная установлена но без капчи и стали приходить спам-письма.
Нашел в поиске эту форму отправки, установил, но она не работает, т.е. капча имеется, показываются нужные надписи и если капча введена неправильно, тоже это информация выходит.
При правильном заполнении пишет, что письмо отправлено, но в почтовый ящик она не приходит.
Файл index вынес из папки и его переименовал. В строчку 13 $emailTo и 30 From: вписал свой емейл Подскажите где искать?
Александр Мальцев
Александр Мальцев
1. Проверьте ошибки на клиенте (в браузере) в панели разработчика во вкладке Console и Network. Во вкладке Network посмотрите какой приходит ответ.
2. Попробуйте проверить все пути…
3. Проверьте ошибки на сервере

Попробуйте на время заменить функцию mail на вывод в файл, и проверьте попадают в него данные или нет.
Аноним
Аноним
Александр, спасибо за ответ, вот такой ответ нашел, может не то: unreachable code after return statement. До этого на всякий случай файл php сохранил без бом.
Такая же форма с файлом html и php работает без вопросов, может натолкну на мысль…
Код
<?php
if (isset($_POST['name'])) {$name = $_POST['name'];}
if (isset($_POST['email'])) {$email = $_POST['email'];}
if (isset($_POST['mess'])) {$mess = $_POST['mess'];}
if (empty($name))
{
echo "<b>Не указано имя!<p>";
echo "<a href=../kontakt.html>Вернуться и правильно заполнить форму.</a>";
}
else
if (empty($email))
{
echo "<b>Не указан e-mail!<p>";
echo "<a href=../kontakt.html>Вернуться и правильно заполнить форму.</a>";
}
else
if (empty($mess))
{
echo "<b>Сообщение не написано!<p>";
echo "<a href=../kontakt.html>Вернуться и правильно заполнить форму.</a>";
}
else
$to = "xxxxxxx@mail.ru"; /*Здесь укажите свой адрес!*/
$charset = "windows-windows-1251";
$subject = "Сообщение с сайта";
$message = "Имя пославшего: $name \nЭлектронный адрес: $email \nСообщение: $mess";
$send = mail ($to,$subject,$message);
if ($send == 'true')
{
echo "<center><b>Спасибо за отправку вашего сообщения
<a href=../kontakt.html>Нажмите</a>, чтобы вернуться на страницу";
}
else
{
echo "<p><b>Ошибка. Сообщение не отправлено!";
}
?>
Аноним
Аноним
Александр, если в текстовый файл, то текст приходит в другой кодировке.
Ihar
Ihar
Присоединяюсь к вопросу, только отправляю почту с денвера через gmail --> mail.ru. Контент лога в другой кодировке.
Александр Мальцев
Александр Мальцев
В файл .htaccess обязательно добавить строчку:
AddDefaultCharset UTF-8