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

В этой статье рассмотрим, как создать форму обратной связи для сайта, используя HTML, Bootstrap, JavaScript (jQuery) и PHP.

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

Что такое форма обратной связи?

Форма обратной связи (контактная форма, feedback form, contact form) - это HTML-форма для сайта, посредством которой администратор или менеджер сайта может получать данные от пользователей. Другими словами это один из способов, с помощью которого одни пользователи (посетители сайта) могут взаимодействовать с другими пользователями (менеджерами или администраторами сайта).

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

Готовую ajax форму обратной связи с капчей и возможностью прикрепления к ней файлов (текущая версия 1.1) можно скачать с Яндекс хранилища или GitHub.

Посмотреть проект на Github (1.1) Скачать архив с Яндекса (1.1)

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

Внешний вид формы обратной связи
Внешний вид формы обратной связи
Отображение ошибок во время проверки формы обратной связи
Отображение ошибок во время проверки формы обратной связи
Отображение информации об успешной отправки формы обратной связи
Отображение информации об успешной отправки формы обратной связи

Форму обратной связи версии 1.0 можно загрузить по следующей ссылке: Feedback Form v1.0

Скриншоты формы обратной связи 1.0:

Примечание: файлы имеют кодировку UTF-8 без BOM.

Для проверки работоспособности формы в Денвере необходимо в корне сайта создать файл .htaccess и добавить в него строчку: AddDefaultCharset UTF-8.

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

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

Форму обратной связи, работающей без перезагрузки страницы, структурно можно представить посредством следующей схемы:

Структурная схема формы обратной связи c AJAX

Как видно из схемы форма обратной связи состоит из 2 основных частей: клиентской и серверной.

Клиентская часть формы обратной связи состоит из следующих файлов:

  • index.html - веб-страница, содержащая html5 форму обратной связи);
  • main.js - JavaScript сценарий, который подключен к странице index.html);
  • bootstrap.min.css, bootstrap.min.js - CSS стили и JavaScript плагин Bootstrap;
  • jquery.jgrowl.min.css, jquery.jgrowl.min.js - CSS стили и jQuery-плагин для отображения всплывающих сообщений;
  • jquery-3.1.1.min.js - библиотека jQuery, необходимая для работы js-плагина Bootstrap, jGrowl и скрипта main.js;
  • glyphicons-halflings-regular.eot и др. - файлы, содержащие иконки.

Клиентская часть формы обратной связи

В качестве примера, возьмём HTML форму, состоящую из:

  • 3 полей (имя пользователя, адрес email и область для ввода сообщения);
  • блока, содержащего элементы input с type="file" (для прикрепления файлов к HTML форме);
  • капчи (защита формы от спама);
  • кнопки, отправляющей её на сервер.

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

Сценарий JavaScript (main.js) используется для отправки контактной формы на сервер посредством технологии AJAX (т.е. без перезагрузки страницы). Но кроме отправки, js-сценарий выполняет ещё следующие вспомогательные операции:

  • проверку полей формы на корректность их заполнения (валидацию). Данное действие выполняется с помощью HTML5 функции checkValidity.
  • отображение ошибок валидации (с помощью окрашивания соответствующих полей формы в красный цвет) и отображения всплывающих сообщений;
  • вывод в блоке (в котором пользователь осуществляет прикрепление файлов к форме) информации о количестве файлов, сообщения о соответствии выбранных файлов установленным критериям, а также для добавления новых элементов input с type="file";
  • обновление кода капчи (получение нового изображения с сервера);
  • получение ответа от сервера и его отображение на странице.

Подготовку данных формы для отправки осуществляется на базе HTML5 объекта FormData. Информация, собранная с помощью FormData отправляется на сервер посредством метода POST.

Серверная часть формы обратной связи состоит из следующих файлов:

  • captcha.php - скрипт для генерации капчи;
  • oswald.ttf - шрифт, с помощью которого код капчи пишется на изображении;
  • background.png - изображение, на которое будет наложен текст капчи;
  • process.php - скрипт, выполняющий отправку данных формы на email;
  • PHPMailerAutoload.php - автозагрузчик библиотеки PHPMailer.

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

PHP скрипт process.php выполняет следующие функции:

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

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

Установка формы обратной связи на сервер осуществляется путём копирования папки feedback в корневую директорию сайта.

После копирования контактная форма на сайте с доменным именем sitename будет доступна адресу: sitename/feedback/.

По умолчанию данная форма отправляет данные на адрес email, указанный пользователем в файле process.php.

Настройка email адреса получателя и других параметров письма осуществляются в process.php на следующих строчках:

$mail->From = 'email@mysite.ru'; // email адрес отправителя
$mail->FromName = 'Имя сайта'; // имя отправителя
$mail->Subject = 'Сообщение с формы обратной связи'; // тема письма
$mail->AddAddress('myemail@mail.ru'); // email адрес получателя

По умолчанию файлы, добавленные к форме, приходят на почту в виде вложений.

Кроме этого, php скрипт можно настроить так, чтобы он не прикреплял файлы к письму, а добавлял их в тело с помощью ссылок. Чтобы это осуществить, достаточно в файле process.php удалить 1 блок и добавить 2 позицию 2 следующий:

// место для установки 2 блока, который предназначен для отправки файлов в теле письма посредством ссылок
if (isset($files)) {
  $output .= "Файлы: " . "\n";
  foreach ($files as $value) {
    $href = substr($value,strpos($value, '/feedback/'));
    $output .= '<p><a href="'.$href.'">'.$href.'</a></p>' . "\n";
  }
}

Кроме отправки формы на email, её можно также настроить так, чтобы она отправляла данные в файл.

Осуществляется это посредством добавления в файл process.php в позицию 3 следующих строк:

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

Добавление полей в форму в версии 1.0

Краткая инструкция по добавлению новых полей в форму обратной связи:

  1. Добавить новый элемент в HTML-форму (файл index.html):
    <input type="text" id="id_поля" name="id_поля">
  2. Добавить строчку, которая будет вставлять данные из HTML элемента в объект formData (файл script.js):
    // добавить после строчки 
    // var formData = new FormData();
    // в formData значение 'id_поля'=значение_поля
    formData.append( 'id_поля', $("#id_поля").val() );
  3. Вставить в блок, в котором формируется тело письма, следующий код (файл process.php):
    // если в массиве POST имеется ключ id_поля
    if (isset($_POST[' id_поля'])) {
      // то добавить его код к телу 
      $output .= "Имя_поля: " . "\n" . $POST[' id_поля'] . "\n";
    }
    

Если наоборот, вы хотите удалить некоторое поле из формы, то необходимо найти в файлах index.html, script.js и process.php соответствующие куски кода и удалить.

Основы работы с версией 1.1

Инициализация кода js-скрипта (создание экземпляра объекта ProcessForm) для обработки формы обратной связи:

// feedbackForm - id HTML-формы
var formFeedback = new ProcessForm({idForm:'feedbackForm'});
formFeedback.init();

С помощью функции-конструктора ProcessForm можно обрабатывать любое количество форм. Осуществляется это следующим образом:

// feedbackForm - id первой HTML-формы
var formFeedback = new ProcessForm({idForm:'feedbackForm'});
formFeedback.init();
// contactForm - id второй HTML-формы 
var contactForm = new ProcessForm({idForm:'contactForm'});
contactForm.init();

Установка PHP файла для обработки формы (form) осуществляется с помощью атрибута action.

<form id="feedbackForm" action="/feedback/process-feedback-form.php" enctype="multipart/form-data" novalidate>

Настроить работу сценария JavaScript очень просто. Осуществляется это посредством указания дополнительных ключей.

/* Параметры указываются в виде:
  {
    ключ: значение;
    ключ: значение;
    ...
  }
  idForm - id формы обратной связи (по умолчанию feedbackForm)
  existenceUploadsFile - наличие у формы блока загрузки файлов (по умолчанию true)
  countFiles - количество файлов для загрузки (по умолчанию 5)
  maxSizeFile - максимальный размер файла в байтах (по умолчанию 524288 байт)
  validFileExtensions - допустимые расширения файлов (по умолчанию 'jpg','jpeg','bmp','gif','png')
  existenceCaptcha - наличие у формы капчи (по умолчанию true)
*/

Например, если вам не нужна капча, то необходимо данный блок удалить из HTML формы и установить при создании экземпляра объекта ProcessForm ключ existenceCaptcha со значением false.

var contactForm = new ProcessForm({
  idForm:'contactForm',
  existenceCaptcha: false
});
contactForm.init();

Ошибки валидации сценарий JavaScript отображает посредством всплывающих сообщений jGrowl. При формировании текста ошибки имя поля берётся из атрибута data-name, а текст ошибки из свойства элемента validationMessage.


Добавление новых полей к форме осуществляется очень просто.

Например, для того чтобы добавить номер телефона в форму обратной связи необходимо:

  1. Добавить элемент для ввода телефона в HTML форму:
    <!-- Телефон пользователя -->
    <div class="form-group has-feedback">
      <label for="phone" class="control-label">Введите телефон*:</label>
      <input type="text" name="phone" data-name="Введите телефон*" required="required" class="form-control" value="" minlength="14">
      <span class="glyphicon form-control-feedback"></span>
    </div>
  2. Вставить значение поля в тело письма (файл process.php):
    if (isset($_POST['phone'])) {
      $output .= 'Телефон пользователя: ' . $_POST['phone'];
    }
    

Формирование результата обработки формы на стороне сервера (process.php) осуществляется с помощью переменной $data.

Основной результат обработки формы устанавливается посредством ключа result, который может иметь следующие значения:

  • success - успешная обработка формы на сервере.
  • invalidCaptcha - неверная капча.
  • error - ошибка при проверке формы.

Создание сообщения, содержащей подробную информацию об ошибке осуществляется с помощью этой же переменной ($data), но имеющей в качестве ключа имя HTML элемента:

Например, формирование ошибки для поля email:

$data['email'] = "Указан не корректный адрес email!";

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

<!-- Форма обратной связи -->
<form id="feedbackForm" action="/feedback/process-feedback-form.php" enctype="multipart/form-data" novalidate>
  <div class="row">
    <div class="col-sm-6">
      <!-- Имя пользователя -->
      <div class="form-group has-feedback">
        <label for="name" class="control-label">Имя*:</label>
        <input type="text" name="name" data-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" name="email" data-name="Адрес email" class="form-control" required="required" value="" placeholder="" maxlength="30">
        <span class="glyphicon form-control-feedback"></span>
      </div>
    </div>
  </div>
  <!-- Сообщение пользователя -->
  <div class="form-group has-feedback">
    <label for="message" class="control-label">Введите сообщение*:</label>
    <textarea name="message" data-name="Сообщение" class="form-control" rows="3" placeholder="Введите сообщение (не менее 20 символов)" minlength="20" maxlength="500" required="required"></textarea>
  </div>
  
  <!-- Блок для прикрепления файлов к форме -->
  <div class="form-group">
    <p style="font-weight: 700;">Прикрепить к сообщению файлы (до <span class="countFiles"></span>):</p>
    <input type="file" name="images[]">
    <p style="margin-top: 3px; margin-bottom: 3px; color: #ff0000;"></p>
  </div>
  
  <hr style="margin-top: 3px; margin-bottom: 3px;">
  <!-- Капча -->              
  <div class="captcha">
    <img class="img-captcha" src="/feedback/captcha/captcha.php" data-src="/feedback/captcha/captcha.php">
    <div class="btn btn-default refresh-captcha"><i class="glyphicon glyphicon-refresh"></i> Обновить</div>
    <div class="form-group has-feedback">
      <label for="captcha" class="control-label">Пожалуйста, введите проверочный код:</label>
      <input name="captcha" data-name="Код на изображении" type="text" class="form-control" required="required" value="" minlength="6" maxlength="6" autocomplete="off">
      <span class="glyphicon form-control-feedback"></span>
    </div>
  </div>
  
  <button name="send-message" type="submit" class="btn btn-primary pull-right">Отправить сообщение</button>
</form>
//после загрузки веб-страницы
$(function () {

  var ProcessForm = function(parameters){
    
    // id формы обратной связи
    this.idForm = parameters['idForm'] || 'feedbackForm';
    // наличие у формы блока загрузки файлов
    this.existenceUploadsFile = parameters['existenceUploadsFile'] || true;
    // наличие у формы капчи
    this.existenceCaptcha = parameters['existenceCaptcha'] || true;    
    // количество элементов input для загрузки файлов
    this.countFiles = parameters['countFiles'] || 5;
    // максимальный размер файла для загрузки (по умолчанию 512 Кбайт)
    this.maxSizeFile = parameters['maxSizeFile'] || 524288;
    // допустимые разрешения файлов
    this.validFileExtensions = parameters['validFileExtensions'] || ['jpg','jpeg','bmp','gif','png'];
    // инициализация
    this.init = function(){
      // получаем форму
      var submitForm = document.getElementById(this.idForm);
      // отправка формы 
      $(submitForm).submit($.proxy(this.submitForm, this));
      if (this.existenceCaptcha) {      
        // обновление капчи
        $(submitForm).find('.refresh-captcha').click($.proxy(this.refreshCaptcha,this));
      }
      if (this.existenceUploadsFile) {
        $('#'+this.idForm+' .countFiles').text(this.countFiles);
        // добавление нового элемента input с type="file"
        $(document).on('change','#' + this.idForm + ' input[name="images[]"]',$.proxy(this.changeInputFile,this));
      }
    };
  }
  // метод, возвращающий результат проверки расширения файла допустимому
  ProcessForm.prototype.validateFileExtension = function(filename) {
    // получаем расширение файла
    var fileExtension = filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2);
    // если есть расширение, то проверяем соотвествует ли оно допустимому
    if (fileExtension) {
      for (var i=0; i <= this.validFileExtensions.length; i++) {
        if (this.validFileExtensions[i] == fileExtension) {
          return true;
        }
      }
    }
    return false;
  };
  // валилация формы
  ProcessForm.prototype.validateForm = function() {
    var _this = this;
    var validForm = true;
    var submitForm = document.getElementById(this.idForm);
    $(submitForm).find('input,textarea').each(function() {
      if (this.checkValidity()) {
        _this.changeStateInput(this,'success');
      } else {
        _this.changeStateInput(this,'error');
        $.jGrowl('Поле: "<strong>'+$(this).attr('data-name')+'</strong>"<br>'+this.validationMessage,{theme: 'jgrowl-error', life: 5000});
        validForm = false;
      }
    });
    return validForm;
  };
  // изменение состояния валидация элемента формы
  ProcessForm.prototype.changeStateInput = function(input,state) {
    var input = $(input);
    inputGroup = input.parents('.form-group');
    glyphiconInput = inputGroup.find('.form-control-feedback');
    if (state == 'error') {
      inputGroup.removeClass('has-success').addClass('has-error');
      if (input.prop("tagName").toLowerCase()!='textarea') {
        glyphiconInput.removeClass('glyphicon-ok').addClass('glyphicon-remove');
      }        
    } else if (state=='success') {
      inputGroup.removeClass('has-error').addClass('has-success');
      if (input.prop("tagName").toLowerCase()!='textarea') {        
        glyphiconInput.removeClass('glyphicon-remove').addClass('glyphicon-ok');
      }          
    } else {
      inputGroup.removeClass('has-success has-error');
      glyphiconInput.removeClass('glyphicon-ok glyphicon-remove');
    }
  };
  // обработка изображений для FormData
  ProcessForm.prototype.changeStateImages = function(state) {
    if (!this.existenceUploadsFile) {
      return;
    }
    var submitForm = document.getElementById(this.idForm); 
    var files = $(submitForm).find('[name="images[]"]');
    for (var i = 0; i < files.length; i++) {
      // получить список файлов элемента input с type="file"
      var fileList = files[i].files;
      // если элемент не содержит файлов, то перейти к следующему
      if (fileList.length > 0) {
        // получить первый файл из списка
        var file = fileList[0];
        // проверить тип файла и размер
        if (!((this.validateFileExtension(file.name)) && (file.size < this.maxSizeFile))) {
          $(files[i]).prop('disabled', state);
        }
      } else {
        $(files[i]).prop('disabled', state);
      }
    }
  };
  ProcessForm.prototype.collectData = function() {
    this.changeStateImages(true);
    this.dataForm = new FormData(document.getElementById(this.idForm));
    this.changeStateImages(false);
  };
  // отправка формы
  ProcessForm.prototype.submitForm = function (e) {
    var _this = this;
    e.preventDefault();
    if (this.validateForm()===false) {
      return;
    };
    this.collectData();
    $.ajax({
      type: "POST",
      url: $('#' + _this.idForm).attr('action'),
      data: _this.dataForm,
      contentType: false,
      processData: false,
      cache: false,
      success: function (data) {
        var data =  JSON.parse(data);
        //устанавливаем элементу, содержащему текст ошибки, пустую строку
        $('#' + _this.idForm + '.error').text('');
        // если сервер вернул ответ success, то значит двнные отправлены
        if (data.result == "success") {
          $.jGrowl('Форма успешно отправлена!',{theme: 'jgrowl-success', life: 5000});
          document.getElementById(_this.idForm).reset();
          $('#' + _this.idForm).find('input,textarea').each(function() {
            _this.changeStateInput(this,'clear');
          });
          if (_this.existenceUploadsFile) {
            $('#'+_this.idForm+' .countFiles').parents('.form-group').html(
              '<p style="font-weight: 700;">Прикрепить к сообщению файлы (максимум <span class="countFiles">'+
              _this.countFiles+'</span>):</p><input type="file" name="images[]">'+
              '<p style="margin-top: 3px; margin-bottom: 3px; color: #ff0000;"></p>');
          }
          if (_this.existenceCaptcha) {      
            _this.refreshCaptcha();
          }
        }
        else if (data.result == 'invalidCaptcha') {
          // если сервер вернул ответ invalidcaptcha...
          $.jGrowl('<strong>Внимание:</strong><br>Не верно был введён проверочный код!',{theme: 'jgrowl-error', life: 5000});
          captcha = $('#'+_this.idForm).find('[name="captcha"]').eq(0);
          _this.changeStateInput(captcha,'error');
          $(captcha).val('');
          var imgCaptcha = $('#'+_this.idForm).find('.img-captcha');
          imgCaptcha.attr('src', imgCaptcha.attr('data-src')+'?id=' + Math.random() + '');
        } else {
          // если сервер вернул ответ error...
          $.jGrowl('<strong>Ошибка!</strong><br>Форму не удалось отправить.',{theme: 'jgrowl-warning', life: 5000});
          // отображаем все ошибки
          for (var error in data) {
            if (error == 'result') {
              continue;
            }
            $.jGrowl(data[error],{theme: 'jgrowl-error', life: 5000});
            _this.changeStateInput($('#'+_this.idForm).find('[name="'+error+'"]').eq(0),'error');         
          }
        }
      },
      error: function (request) {
        $.jGrowl('Произошла ошибка ' + request.responseText + ' при отправке данных.',{theme: 'jgrowl-error', life: 5000});
      }
    });      
  };
  // обновление капчи
  ProcessForm.prototype.refreshCaptcha = function() {
    var imgCaptcha = $('#'+this.idForm).find('.img-captcha');
    imgCaptcha.attr('src', imgCaptcha.attr('data-src')+'?id=' + Math.random() + '');
  };
  // изменение элемента input с type="file"
  ProcessForm.prototype.changeInputFile = function(e){
    // условие для добавления нового элемента input с type="file"
    if ((e.currentTarget.files.length > 0) && ($(e.currentTarget).next('p').next('input[name="images[]"]').length==0) && ($('#' + this.idForm + ' input[name="images[]"]').length < this.countFiles)) {
      $(e.currentTarget).next('p').after('<input type="file" name="images[]"><p style="margin-top: 3px; margin-bottom: 3px; color: #ff0000;"></p>');
    }
    // если файл выбран, то выполняем следующие действия...
    if (e.currentTarget.files.length > 0) {
      // получим файл
      var file = e.currentTarget.files[0];
      // проверим размер и расширение файла
      if (file.size > this.maxSizeFile) {
        $(e.currentTarget).next('p').text('*Файл не будет отправлен, т.к. его размер больше '+ this.maxSizeFile/1024 + 'Кбайт');
      } else if (!this.validateFileExtension(file.name)) {
        $(e.currentTarget).next('p').text('*Файл не будет отправлен, т.к. его тип не соответствует разрешённому');
      } else {
        if ($(e.currentTarget).next('p')) {
          $(e.currentTarget).next('p').text('');
        }
      }
    } else {
      // если после изменения файл не выбран, то сообщаем об этом пользователю
      $(e.currentTarget).next('p').text('* Файл не будет отправлен, т.к. он не выбран');
    }
  };
    
  // Подключаем формы для обработки:
  var formFeedback = new ProcessForm({idForm:'feedbackForm'});
  formFeedback.init();
  
  var contactForm = new ProcessForm({idForm:'contactForm',existenceUploadsFile:false,existenceCaptcha: false});
  contactForm.init();

});
<?php
  session_start(); // открываем сессию
  $data['result']='error';   // переменная в которую будем сохранять результат работы
  $allowedExtension = array("jpg" => "image/jpg", "jpeg" => "image/jpeg", "gif" => "image/gif", "png" => "image/png");  // разрешённые типы файлов
  $pathToFile = $_SERVER['DOCUMENT_ROOT'].'/feedback/uploads/'; // директория для хранения файлов
  $maxSizeFile = 524288; // максимальный размер файла

  // функция для проверки длины строки
  function validStringLength($string,$min,$max) {
    $length = mb_strlen($string,'UTF-8');
    if (($length<$min) || ($length>$max)) {
      return false;
    }
    else {
      return true;
    }
  }

  if ($_SERVER['REQUEST_METHOD'] == 'POST') {   // если данные были отправлены методом POST, то...
    $data['result']='success';
    //получить имя, которое ввёл пользователь
    if (isset($_POST['name'])) {
      $name = $_POST['name'];
      if (!validStringLength($name,2,30)) {
        $data['name']='Поля имя содержит недопустимое количество символов.';   
        $data['result']='error';     
      }
    } else {
      $data['result']='error';
    } 
    //получить email, которое ввёл пользователь
    if (isset($_POST['email'])) {
      $email = $_POST['email'];
      if (!filter_var($email,FILTER_VALIDATE_EMAIL)) {
        $data['email']='Поле email введено неправильно';
        $data['result']='error';

      }
    } else {
      $data['result']='error';
    }   
    //получить сообщение, которое ввёл пользователь
    if (isset($_POST['message'])) {
      $message = $_POST['message'];
      if (!validStringLength($message,20,500)) {
        $data['message']='Поле сообщение содержит недопустимое количество символов.';     
        $data['result']='error';   
      }      
    } else {
      $data['result']='error';
    } 
    //получить капчу, которую ввёл пользователь
    if (isset($_POST['captcha'])) {
      $captcha = $_POST['captcha'];
    } else {
      $data['result']='error';
    } 
    // если не существует ни одной ошибки, то продолжаем... 
    if ($data['result']=='success') {
      
      // если пользователь ввёл правильный код капчи, то...
      if ($_SESSION["code"] == $captcha) {

        //обработаем файлы, загруженные пользователем посредством элементов с name="images[]"

        // если ассоциатианый массив $_FILES["images"] существует, то
        if(isset($_FILES["images"])) {
          // переберём все файлы (изображения)
          $files = array();
          foreach ($_FILES["images"]["error"] as $key => $error) {
            // если ошибок не возникло, т.е. файл был успешно загружен на сервер, то...
            if ($error == UPLOAD_ERR_OK) {
              // имя файла на устройстве пользователя
              $nameFile = $_FILES['images']['name'][$key];
              // расширение загруженного пользователем файла в нижнем регистре
              $extFile = mb_strtolower(pathinfo($nameFile, PATHINFO_EXTENSION));
              // размер файла
              $sizefile = $_FILES['images']['size'][$key];
              //myme-тип файла
              $filetype = $_FILES['images']['type'][$key]; 
              // проверить расширение файла, размер файла и mime-тип
              if (!array_key_exists($extFile, $allowedExtension)) {
                $data['files']='Ошибка при загрузке файлов (неверное расширение).';
                $data['result']='error';
                      $data['result7']='error';
              } elseif ($sizefile > $maxSizeFile) {
                $data['files']='Ошибка при загрузке файлов (размер превышает 512Кбайт).';
                $data['result']='error';
                $data['result8']='error';
              } elseif (!in_array($filetype, $allowedExtension)){
                $data['files']='Ошибка при загрузке файлов (неверный тип файла).';
                $data['result']='error';
                $data['result9']='error';
              } else {
                //ошибок не возникло, продолжаем...
                 
                // временное имя, с которым принятый файл был сохранён на сервере
                $tmpFile = $_FILES['images']['tmp_name'][$key];
                // уникальное имя файла
                $newFileName = uniqid('img_', true).'.'.$extFile;
                // полное имя файла
                $newFullFileName = $pathToFile.$newFileName;
                // перемещаем файл в директорию
                if (!move_uploaded_file($tmpFile, $newFullFileName)) {
                  // ошибка при перемещении файла
                  $data['files']='Ошибка при загрузке файлов.';                
                  $data['result']='error';
                  $data['result10']='error';
                } else {
                  $files[] = $newFullFileName;
                }
              }
            } else {
              //ошибка при загрузке файл на сервер
              $data['result']='error';
              $data['result11']='error';
            }
          }
        }
      } else {
        // пользователь ввёл неправильную капчу
        $data['result']='invalidCaptcha';
      }
    }
  } else {
    //ошибка не существует ассоциативный массив $_POST["send-message"]
    $data['result']='error';
    $data['result12']='error';
  }

  // дальнейшие действия (ошибок не обнаружено)
  if ($data['result']=='success') {
    //место для установки 3 блока, который предназначен для сохранения формы в файл
    $output = "---------------------------------" . "\n";
    $output .= date("d-m-Y H:i:s") . "\n";
    $output .= "Имя пользователя: " . $name . "\n";
    $output .= "Адрес email: " . $email . "\n";
    $output .= "Сообщение: " . $message . "\n";
    if (isset($files)) {
      $output .= "Файлы: " . "\n";
      foreach ($files as $value) {
         $output .= $value . "\n";
      }
    }
    if (file_put_contents(dirname(__FILE__).'/info/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 .= "Сообщение: " . "\n" . $message . "\n";

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

    
    // создаём экземпляр класса PHPMailer
    $mail = new PHPMailer;
  
    $mail->From      = 'email@mysite.ru';
    $mail->FromName  = 'Имя сайта';
    $mail->Subject   = 'Сообщение с формы обратной связи';
    $mail->Body      = $output;
    $mail->AddAddress( 'myemail@mail.ru' );

    // 1 - блок для прикрепления файлов к письму 
    if (isset($files)) {
      foreach ($files as $value) {
         $output .= $value . "\n";
         $mail->addAttachment($value);
      }
    }
    // конец 1 блока
 
    // отправляем письмо
    if ($mail->Send()) {
      $data['result']='success';
    } else {
      $data['result']='error';
    }
  }

  echo json_encode($data);

?>
<?php
//открывает сессию
session_start();
 
//присваивает PHP переменной captchastring строку символов
$captchastring = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz';
//получает первые 6 символов после их перемешивания с помощью функции str_shuffle
$captchastring = substr(str_shuffle($captchastring), 0, 6);
//инициализация переменной сессии с помощью сгенерированной подстроки captchastring,
//содержащей 6 символов
$_SESSION["code"] = $captchastring;
 
//Генерирует CAPTCHA
 
//создает новое изображение из файла background.png 
$image = imagecreatefrompng(dirname(__FILE__).'/background.png');
//устанавливает цвет (R-200, G-240, B-240) изображению, хранящемуся в $image
$colour = imagecolorallocate($image, 200, 240, 240);
//присваивает переменной font название шрифта
$font = dirname(__FILE__).'/oswald.ttf';
//устанавливает случайное число между -10 и 10 градусов для поворота текста 
$rotate = rand(-10, 10);
//рисует текст на изображении шрифтом TrueType (1 параметр - изображение ($image), 
//2 - размер шрифта (18), 3 - угол поворота текста ($rotate), 
//4, 5 - начальные координаты x и y для текста (18,30), 6 - индекс цвета ($colour),
//7 - путь к файлу шрифта ($font), 8 - текст ($captchastring) 
imagettftext($image, 18, $rotate, 28, 32, $colour, $font, $captchastring);
//будет передавать изображение в формате png
header('Content-type: image/png');
//выводит изображение
imagepng($image);
?>


   PHP 0    17487 +1

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

  1. maloir # 0
    Здравствуйте, загорелся вашей обратной связью, но видно я тут единственный кому она вообще не далась, я так понимаю тут люди собрались разбирающие в программировании, я к сожалению нет, и поэтому она у меня не работает. Перечитал все комменты, понравились ваши дополнения которые вы даете для усовершенствования формы, особенно понравилось закачка файлов перетягиванием файлов, но споткнулся даже не начав так сказать. Скачал, папку залил в корень, поставил форму, исправил настройки как описано в вашей статье, ни каких эффектов. И даже не могу спросить что я не так сделал так как просто много не понимаю, вернее всего. Устанавливал себе на сайт много раз формы обратной связи, но ни когда проблем не испытывал с установкой, интуитивно догонял (методом тыка :)) что куда, но ваша форма крепкий орешек, даже не знаю к чему подступится, не понятно зачем два файла process-contact-form.php и process-feedback-form.php к какому указывать путь из формы? У вас в статье написано файл process.php. надо редактировать но в скаченном архиве его вообще нет. В документе HTML почему — то две формы, то же не понятно… Не смотря на то что ваша статья написана доходчивым и простым языком, скачал, залил, исправил и пользуйся, на деле оказывается не так все просто. Так же не понятна эта строка: $mail->From = 'email@mysite.ru'; // email адрес отправителя — а как я узнаю емайл отправителя, если я не знаю отправителя или это форма только для за регистрированных пользователей? но опять же не понятно какой емайл вписывать. В общем хорошая статья, отличная форма, но установить не могу. Может найдется у вас время и вы подскажите что я не так сдедал. Залил в корень все что в архиве, исправил все строки что указано в статье кроме выше указаной.
    1. Александр Мальцев # 0
      Здравствуйте. В описании есть 2 ссылки. Первая ссылка (проект на GitHub) содержит пример с одной формой на странице (он базовый). Вторая ссылка (с Яндекс хранилища) там приведена возможность как можно работать с 2 формами (поэтому там и используется 2 серверных скрипта). Вам нужен базовый вариант, поэтому загружайте его с GitHub.
      $mail->From — должен содержать адрес электронной почты, от имени которого будет производиться отправка писем пользователям. Как вы его можете не знать. Например, на этом сайте все письма отправляются от имени no-reply@itchief.ru.
      1. maloir # 0
        Спасибо, ваш вариант заработал без проблем, все действительно просто! Но форма краказяблы присылала, нашел в коментариях ваш совет, но не смог применить его на форме которую вы мне сказали скачать. Скачал форму feedback-with-dropzone все исправил, присылает нормальные тексты. Все ок. Но в Вашей помощи нуждаюсь.
        1 форма распологается по центру, какой стиль отключить что бы она была не по центру? Она у меня на половину показывает.
        2 как снять ограничение на число знаков? А то мне нужна форма для объемных сообщений хотя бы до 500 символов
        3 пробывал добавить поля дополнительные, мне нужны текстовые поля для сбора информации, но не получилось, во всех документах правки вносил, такого плана: verify.php
        if (isset($_POST['text1'])) {
        $output .= «sub1: ». "\n". $POST['text1']. "\n";
        }
        if (isset($_POST['text2'])) {
        $output .= «sub2: ». "\n". $POST['text2']. "\n";
        }
        script.js
        formData.append( 'text1', $("#sub1").val() );
        formData.append( 'text2', $("#sub2").val() );
        в форму
        письма уходят но поля не приходят

        и последнее добавление других файлов
        в скрип в самое начало после $(function () { вставил код
        // максимальное количество файлов
        var countFiles = 5;
        // типы разрешённых файлов
        var typeFile = [
        'jpg',
        'jpeg',
        'gif',
        'png',
        'rar',
        '7z',
        'zip',
        'txt',
        'doc',
        'docx'
        ];

        в файл verify.php вставил
        // разрешённые типы файлов
        $allowedExtension = array(«jpg», «jpeg», «gif», «png», «rar», «7z», «zip»,«txt»,«doc»,«docx»);

        но форма пишит что неверный формат файла. Буду Вам очень благодарен за помощь.
    2. Иван # 0
      Здравствуйте. Разместила данный код на сайте, добавила телефон убрала email и capcha. В коде прописала что без капчи.var contactForm = new ProcessForm({
      idForm:'feedbackForm',
      existenceCaptcha: false
      });
      Форма не отправляется выдает Ошибка! Форму не удалось отправить. error. В чем может быть причина?
      1. Александр Мальцев # 0
        Этим действием вы настроили только клиент (работу файла main.js), но не серверный скрипт. Серверный скрипт пока ещё нельзя так просто настроить. В нём вам необходимо эти действия закомментировать или удалить.
        1. Иван # 0
          С этим разобрались. А как сделать чтоб файлы и с телефона могли приходить? Сейчас когда заполняешь форму, файл не приходит
          1. Александр Мальцев # 0
            Должно работать. Форма для отправки использует объект FormData, полный перечень поддерживаемых устройств можно посмотреть по ссылке caniuse.com/#search=formdata
      2. Юрий # 0
        Здравствуйте, Александр. Возникла снова проблема, предполагаю, что связана она с хостингом. Формы работают на поддомене тестовом, а как перенес на другой хостинг, стала появляться ошибка, «Незаполненно обязательное поле». При этом данные с полей записываются в текстовый файл в папку feedback, а на указанный адресс не доставляются. Перепроверил многократно и безрезультатно, заметил, что права на поддомене на папку 750, на файлы 640, а на хостинге, где не работает форма, на папку 755, файлы 644. И еще, в текстовый файл записывается время не точное, 6 часов разницы, не в этом ли проблема, подскажите пожалуйста.
        1. Юрий # 0
          Получилось, помог ваш совет $mail->Sender = 'domain@domain.com';
        2. Анатолий # 0
          Здравствуйте. Возникла проблемка. Мне нужно отправлять через форму векторные файлы cdr, eps, ai

          Я прописал эти расширения в файле main.js, однако при отправке всё равно возникает ошибка «Ошибка при загрузке файлов (неверный тип файла).»

          Версия формы 1.1
          1. Александр Мальцев # 0
            Кроме как это сделать при инициализации формы в javascript:
            var formFeedback = new ProcessForm({idForm:'feedbackForm',validFileExtensions:['jpg','jpeg','gif','png','cdr','eps','ai']});
            formFeedback.init();
            
            Добавить допустимые для загрузки файлы необходимо ещё указать в PHP (обработчик формы):
            // разрешённые типы файлов
            $allowedExtension = array("jpg" => "image/jpg", "jpeg" => "image/jpeg", "gif" => "image/gif", "png" => "image/png", "cdr" => "image/x-coreldraw", "eps" => "application/postscript", "ai" => "application/postscript");
            
          2. Elizabeth # 0
            Назрел еще один вопрос: в данной форме имеется лишь нативная браузерная проверка на валидность, она не очень привлекательна, я хотела бы несколько стилизовать сообщение об ошибках. Нашла в сети статью где предлагается внедрить Bootstrap Validator, но споткнулась на разделе «Валидация формы»: не смогла встроить все это дело в наш script.js. Можете еще помочь с этим вопросом, хочется чтоб всё прям безупречно было, не хотелось бы выводить некрасивое браузерное сообщение об ошибке, вместо этого просто подсветить незаполненные поля.
            1. Александр Мальцев # 0
              Стилизация элементов и так по умолчанию доступна в форме. Для этого достаточно лишь добавить к тегу form атрибут novalidate. Плагин Bootstrap Validator встраивать не вижу смысла, т.к. с валидацией формы отлично справляется и HTML5 валидатор.
              Попробуйте также новую версию формы обратной связи, список изменений приведён в статье.
            2. Elizabeth # 0
              Здравствуйте, благодарю за полезную статью! Вопрос такой: возможно ли сделать так, чтобы после отправки письма помимо сообщения об успешной отправке снизу отображалась очищенная форма обратной связи? В данный момент сама форма скрывается и демонстрируется лишь сообщение об успешной отправке.
              1. Александр Мальцев # +2
                Здравствуйте, спасибо. Для этого необходимо в файле script.js заменить блок
                if ($data.result == "success") {
                  // скрываем форму обратной связи
                  $('#messageForm').hide();
                  // удаляем у элемента, имеющего id=msgSubmit, класс hidden
                  $('#msgSubmit').removeClass('hidden');
                }
                
                на следующий:
                if ($data.result == "success") {
                  $('#messageForm').hide();
                  $('#msgSubmit').removeClass('hidden');
                  // код для очистки формы
                  document.getElementById('messageForm').reset();            
                  $('#messageForm input,#messageForm textarea').each(function () {
                    var formGroup = $(this).parents('.form-group');
                    var glyphicon = formGroup.find('.form-control-feedback');
                    formGroup.removeClass('has-success has-error');
                    glyphicon.removeClass('glyphicon-ok glyphicon-remove');
                  });
                  $('#countFiles').parents('.form-group').html('<p style="font-weight: 700;">Прикрепить к сообщению файлы (максимум <span id="countFiles"></span>):</p><input type="file" name="images[]"><p style="margin-top: 3px; margin-bottom: 3px; color: #ff0000;"></p>');
                  $('#img-captcha').attr('src', '/feedback/captcha.php?id=' + Math.random() + '');
                  setTimeout(function(){ 
                    $('#msgSubmit').addClass('hidden');
                    $('#messageForm').show();
                  }, 3000);
                }
                
                Очищенная форма появится через 3 секунды после показа сообщения.
                1. Юрий # 0
                  Работает отлично, но только после возвращения формы, вылазит «Незаполненно обязательное поле», при этом данные корректно были отправленны и на работу формы, это ни как не влияет.
                  1. Александр Мальцев # +1
                    Чтобы это поправить поищите в php лишнюю строчку, которая добавляет в массив $data это сообщение.
                    1. Юрий # 0
                      Спасибо, но не нашел, сравнил оригинальный verify.php со своим измененным и ничего похожего на ненужное не увидел)
                  2. Elizabeth # 0
                    Спасибо большое.
                2. Евгений # 0
                  Здравствуйте, помогите пожалуйста сделать номер телефона с проверкой и укажите какой код должен быть в php в js файлах, буду очень благодарен!
                  1. Александр Мальцев # 0
                    Для проверки телефона в форме можно использовать атрибут pattern:
                    <div class="form-group has-feedback">
                      <label for="phone" class="control-label">Введите телефон в формате 7(***)***-**-**:</label>
                      <input required="required" type="tel" pattern="7\([0-9]{3}\)[0-9]{3}-[0-9]{2}-[0-9]{2}" id="phone" name="phone" class="form-control" title="7(***)***-**-**">
                      <span class="glyphicon form-control-feedback"></span>
                    </div>
                    
                    На php проверку регулярных выражений можно выполнить с помощью preg_match.
                  2. Евгений # 0
                    Здравствуйте, Александр! Есть проблема с формой я копировал фидбэк к себе на сайт, заменил эмейл получателя, отправляю сообщение и получаю одобрительный ответ об отправке сообщения, но на почте нечего нет. Пользуюсь OpenServer-ом, пробовал уже несколько ящиков но ничего, буду благодарен за помощь)
                    1. Евгений # 0
                      Все помощь больше не нужна, проблема была с локальным сервером)
                    2. Дядя # 0
                      Здравствуйте, скажите, а сложно переделать форму, чтобы файл из сервера отправился на почту адресата из формы. А админу приходили контакты подписчика (имя, телефон, email)?
                      В форме оставить только три поля: имя, телефон, email.
                      1. Александр Мальцев # 0
                        Здравствуйте, было уже много подобных вопросов. Посмотрите комментарии, может в них, вы найдёте необходимые ответы…
                        Например, для отправки на почту адресата:
                        itchief.ru/lessons/php/feedback-form-for-website#comment-2526
                        itchief.ru/lessons/php/feedback-form-for-website#comment-2735
                      2. Михаил # 0
                        Опять таже ситуация с подменой Return-Path ящиком хостера Return-Path: 119132@linwebng05.hostingspace.pro
                        разве значени From
                        $mail->From = 'email@mysite.ru';
                        и не есть по умолчанию соответствие Return-Path?

                        Советуют добавить в скрипт 5 параметр:
                        mail($addr,$subj,$msg,$headers," -f domain@domain.com");
                        Это простите уж моё невежество КУДА??????!!! :??:"?%%?":"*(!
                        :-)
                        1. Михаил # 0
                          Новый ответ хостера:

                          В whitelist добавляется адрес отправителя.
                          На данный момент отправка до сих пор происходит с общего домена.
                          05 Feb 2017 14:37:07 (GMT +03:00)
                          SENDER: 119132@linwebng05.hostingspace.pro
                          RECIPIENT: email@domain.com
                          SUBJECT: Семинары
                          LAST STATE:
                          Message 240130832 aborted: Dropped by CASE

                          Настройте return-path в почтовом скрипте, к примеру, mail($addr,$subj,$msg,$headers," -f domain@domain.com");
                          в пятый параметр и добавьте Return-Path (domain@domain.com — реальный ящик на вашем домене).

                          Люди добрый подскажите где это уже исправить. Я задолбался. :-))))))))))))))))

                          1. Александр Мальцев # 0
                            Установите этот параметр так:
                            $mail->Sender = 'domain@domain.com';
                            
                            1. Михаил # 0
                              Александр, если есть время и возможность. Использую Вашу форму (без капчи и с полями имя, email, сообщение, и пункт загрузки (для тех, кто захочет реквизиты сбросить) как запись на семинары). Как можно добавить в форму выбор пункта с датой и временем для проведения семинара (а это до 20 дат в месяц)? И чтобы этот выбор записывался с остальными пунктами и в лог и на почту с эти выбором. За ответ заранее благодарен.
                              1. Александр Мальцев # 0
                                Для этого необходимо добавить в форму элемент для выбора даты. Как добавить компонент можно посмотреть здесь: itchief.ru/lessons/bootstrap-3/113-bootstrap-3-datetimepicker
                                <div class="form-group">
                                  <div class="input-group date" id="datetimepicker">
                                    <input type="text" id="date" name="date" class="form-control">
                                    <span class="input-group-addon">
                                      <span class="glyphicon-calendar glyphicon"></span>
                                    </span>
                                  </div>
                                </div>
                                После этого его необходимо добавить в объект formData для отправки на сервер:
                                formData.append('date', $('#datetimepicker').data('date'));
                                На сервере его получаем так:
                                $date = $_POST['date'];
                                После этого добавляйте эту переменную в лог, в тело письма…
                              2. Михаил # 0
                                Уряяяяя. Заработало… Александр огромная Благодарность. Все отсылает.
                          2. Михаил # 0
                            Александр добрый день. Поставил форму, все настроил и работает. Пишет в лог, но на почту письма не доходят. Я так понимаю как то надо настроить сервер и записи, так как письма пытаются уйти через почтовый сервер хостера и идет подмена реального адреса на SENDER: 119132@linwebng05.hostingspace.pro и его блокируют? Я не совсем понимаю что настроить и как. Какие изменения нужны в php.ini или TXT записях к домену или где править? Заранее Благодарю если можете подсказать.

                            Хостер только посоветовал:
                            Укажите в скрипте отправителя в Return-Path ящик на Вашем домене с корректно настроенной SPF записью и письма будут отправляться с наибольшей вероятностью. На данный момент письма блокируются нашим спам фильтром.
                            SENDER: 119132@linwebng05.hostingspace.pro
                            RECIPIENT: admin@
                            Судя по всему, проблема в скрипте, отвечающем за формирование тела письма.
                            Обращаем Ваше внимание, что письма с вашего сайта не должны отправляться с нашего общего домена.
                            [Отправитель конверта 119132@linwebng05.hostingspace.pro]
                            1. Александр Мальцев # 0
                              Здравствуйте, вам необходимо в скрипте вместо mysite.ru указать ваш домен:
                              $mail->From = 'email@mysite.ru';
                              $mail->FromName  = 'Имя сайта';
                              
                              А если необходимо добавить ещё TXT-запись, то спрашивайте у хостера какую именно.
                              1. Михаил # 0
                                Благодарю. В скрипте все настроено верно. Помогла TXT запись для домена. v=spf1 ip4:XX.XXX.XXX.X/XXX ~all ( XX.XXX.XXX.X/XXX соответственно диапазон адресов хостера)
                                Подскажите пожалуйста как быстро убрать из формы капчу? в каких файлах и что закомментировать или удалить. Благодарю заранее
                                1. Михаил # 0
                                  Просто хочу подправить форму что-бы было имя телефон e-mail и тест. без файлов и капчи. И если можно подскажите как украсить форму например выводом слева фотки по размеру формы. Еще раз благодарю.
                                  1. Александр Мальцев # 0
                                    Форму без капчи можете посмотреть тут: yadi.sk/d/0qBwiRQitRtfj
                                    Вывести слева фотку можно так:
                                    <div class="container">
                                      <div class="row">
                                        <div id="image" class="col-sm-6" style="background: url(1.jpg); background-size: cover;"></div>
                                        <div class="col-sm-6">
                                          <!-- Контейнер, содержащий форму обратной связи -->
                                          <!-- ... -->
                                        </div>
                                      </div>
                                    </div>
                                    
                                    Если необходимо такой же высоты, то можно воспользоваться сценарием JavaScript:
                                    <script>
                                    $(function(){
                                      $('#image').height($('#feedback').height());
                                    });
                                    </script>
                                    
                            2. wansal # 0
                              Александр, благодарю, вставил по Вашему совету нужную строку и разобрал некоторые вопросы с хостером, теперь файлы доставляются нормально, все работает как часы. Понимаю, что вопросы новичков порядком надоели, но все же еще раз Вас потревожу, если позволите)) Решил я добавить возможность заливать файлы путем drag-and-drop (чтобы ну прямо совсем идеально все выглядело). Выбрал для этого библиотеку dropzonejs.com, переделал немного ее дизайн под себя и интегрировал поле для загрузки в Вашу форму вместо стандартного input type=«file» (дабы не объяснять долго, выглядит это примерно так). В dropzone файлы заливаются без проблем, визуально все работает, однако файлы игнорируются Вашим обработчиком, что вполне логично. Не могли бы Вы подсказать, как правильнее «совместить» два скрипта? Горы кода писать, безусловно, не прошу, просто в целом хотелось бы понять, справлюсь ли я с этим. Быть может, достаточно перенести всё из dropzone.js в Ваш script.js и что-нибудь переименовать (это мои мозги с трудом могут потянуть), а может, придется привлекать специалиста. Все комментарии к подобным статьям на Вашем сайте пролистал и целый день провел в поисках ответа в сети, но безрезультатно…
                              1. Александр Мальцев # 0
                                Подключить dropzone.js оказалось не так просто. Т.к. изначально он прикрепляется к форме и нацелен на то, чтобы отправлять файлы серверному скрипту по указанному адресу.
                                Чтобы его от этого отучить необходимо выполнить следующее:
                                1. Отключить автоматическое обнаружение (Dropzone.autoDiscover = false), иначе Dropzone попытается 2 раза подсоединиться.
                                2. Создать dropzone и обязательно выставить параметр autoProcessQueue в положение false. Этим мы отключим отправку файлов самим Dropzone на сервер. Это действие будем выполнять самостоятельно. Параметру url необходимо установить произвольное значение (например, 'verify.php'), иначе Dropzone не будет работать. Данный параметр указывает ему местонахождение файла, который будет выполнять обработку файлов на сервере. Но, т.к. мы отключили отправку файлов самим Dropdown (autoProcessQueue: false), то его значение роли не играет. Ещё одно важный параметр — это paramName. Он должен содержать имя элемента input в форме.

                                В итоге получилась форма обратной связи, к которой можно добавлять файлы простым перетаскиванием. А также в ней будут отображаться миниатюры изображений, выбранных для отправки.
                                Форма обратной связи с Dropzone
                                Ссылки:
                                1. AJAX форма обратной связи с Dropzone (прикрепление файлов осуществляется перетаскиванием)
                                2. Пустая форма обратной связи с Dropzone
                                3. Архив формы feedback с dropzone: yadi.sk/d/Kl7gnBEn3DMEZ6
                                1. AlexDeLamaro # 0
                                  Тоже поставил себе эту форму с Dropzone. Великолепная штука, очень полезная. Единственный нюанс: целый день проковырялся, пытаясь настроить отображение прогресс-бара на загружаемых файлах. По идее, он должен работать, никаких конфликтов не обнаружил. По рекомендациям автора Dropzone даже добавлял класс «dropzone» к форме, но и это не помогло. Не понятно, загружается файл или уже загрузился. Прогресс-бар просто не отображается. Висит с display: none; и всё. Буду очень признателен, если подскажете, в чём может быть проблема.
                                  1. Александр Мальцев # 0
                                    Прогресс бар для картинок здесь не нужен, т.к. они отправляются не по отдельности, а вместе с другими данными формы. Поэтому он и выключен. В данном случае просто невозможно отследить отправилась какая-та картинка или нет. Т.е. повесить прогресс можно только на всю форму.
                                    Если необходим другой вариант, т.е. дать возможность отправки изображений отдельно от формы, то используйте классический вариант. А полученные ссылки просто включите в форму обратной связи при её отправке. Т.е. необходимо будет собрать их с соответствующих элементов. Но учтите, что в этом случае пользователь может загрузить файлы, но не отправить форму.
                                    1. AlexDeLamaro # 0
                                      Понял. Да, я включил в разрешённые загрузки и другие типы файлов, помимо изображений, планируется принимать файлы больших размеров. Буду биться, в общем. Большое спасибо за разъяснение, Александр.
                                  2. wansal # 0
                                    Все работает на высшем уровне, не могу нарадоваться. Была пара долгих заминок, но оба раза я сам был невнимателен и забывал подправить пути) Александр, огромная Вам человеческая благодарность!!! И спасибо за то, что даже непростые вопросы чайников Вы не оставляете без внимания, это дорогого стоит!
                                  3. Александр Мальцев # 0
                                    Нет, должно быть всё просто. Необходимо просто дополнительно к странице ещё подключить dropzone.js и добавить к форме класс dropzone.
                                    Также элемент, который должен принимать файлы иметь имя file и атрибут multiple:
                                    <input name="file" type="file" multiple>
                                    
                                    Как изменить код script.js для работы с multiple вы уже спрашивали выше:
                                    https://itchief.ru/lessons/php/feedback-form-for-website#comment-3913
                                    
                                    В будущих версиях формы — эта возможность, скорее всего, будет присутствовать по умолчанию.
                                    1. wansal # 0
                                      Честно говоря, не совсем понимаю, никак не выходит… В index.html вместо Вашей части кода:
                                      <div class="form-group">
                                      <p style="font-weight: 700;">Прикрепить к сообщению файлы (максимум <span id="countFiles"></span>):</p>
                                      <input type="file" name="images[]">
                                      <p style="margin-top: 3px; margin-bottom: 3px; color: #ff0000;"></p>
                                      </div>
                                      я вставил эту:
                                      <div id="myDropZone" class="field dropzone">
                                      <div class="dz-message needsclick">Нажмите для загрузки файлов</div>
                                      </div>
                                      Тега input для файлов на странице вообще нет (он как-то автоматически генерируется самим dropzone.js). Поскольку по умолчанию поле для загрузки dropzone идет как form, а в таком виде к Вашей форме обратной связи его не прикрепить (будет form внутри form), пришлось при помощи яваскрипта добавлять поле в виде div-контейнера. Если я приписываю к контейнеру с id «myDropZone» имя file, обработчик отправляет сообщение, по-прежнему игнорируя файлы. Если же добавляю имя images[], то при нажатии кнопки submit сообщение вообще не отправляется — по-видимому, Ваш скрипт пытается «устроить» проверку файлам, но у него это не получается, а в консоли браузера появляется вот такая ошибка. Я так понимаю, причина в том, что скрипты конфликтуют между собой. И надо каким-то образом заставить Ваш файл не делать проверку конкретно файлов (за него это сделает dropzone.js), и тем не менее отправлять их вместе с другим содержимым формы… Надеюсь, написал понятно, а то голова уже кругом идет))
                                  4. Дмитрий007 # 0
                                    Здравствуйте Александр.
                                    При закачке на хостинг, форма не хочет отправлять сообщения. Выскакивает «Произошли ошибки при отправке формы на сервер.»
                                    Как исправить, в чем может быть причина?
                                    1. Александр Мальцев # 0
                                      Проверьте тариф на хостинге, может быть в этом причина.
                                      Также можете посмотреть эти комментарии:
                                      itchief.ru/lessons/php/feedback-form-for-website#comment-3434
                                      itchief.ru/lessons/php/feedback-form-for-website#comment-3627

                                      А так сложно судить о вашей проблеме, информации совсем нет. Можно на хостинге включить лог ошибок, и посмотреть какая ошибка там возникает…
                                      1. Дмитрий007 # 0
                                        Скажу по другому. На хостинге готовая в папке форма ваша отрабатывает. Но если файл index переместить на один порядок ниже (на папку назад) она перестает работать пишет «Произошли ошибки при отправке формы на сервер.», так вот интересует вопрос, где-нибудь надо изменять пути в самих файлах (verify.php и script.js), то есть надо ли указывать абсолютный адрес внутри файлах?
                                        1. Александр Мальцев # 0
                                          Форма, ссылка на которую приведена в статье, использует абсолютные пути. Т.е. папку feedback необходимо оставить в корне сайта, а файл index.html можно перенести в любое место и переименовать. Всё должно работать, но необходимо проверить правила, которые у вас заданы в конфигурационном файле сервера (например, в Apache этот файл называется .htaccess). Т.е. его на время можно удалить и проверить работает ли форма. Если да, то необходимо провести изменения в этом файле. Если вы используете другие формы, на которые приведены ссылки в комментариях, то в некоторых из них могут присутствовать тег base или использоваться не абсолютные пути. Тут надо проверять…
                                    2. николай # 0
                                      форма замечательная, однако никак не могу добавить поле для ввода телефона. Все делал по инструкции в конце статьи, но в письме почему то телефона так и нет. Может есть уже готовая форма с телефоном? Выложите пожалуйста, очень нужна такая форма для сайта.
                                      1. Александр Мальцев # 0
                                        Можешь посмотреть эти реализации форм:
                                        yadi.sk/d/IiaNuxolujPKa
                                        yadi.sk/d/_UrVReQ2zzvgP
                                        1. николай # 0
                                          Александр, спасибо за ответ. но к сожалению ничего не вышло. Делал все и по инструкции и по аналогии с указанными формами, результат один либо вообще после ввода данных форма молчит либо выдает сообщение об ошибке при отправке на сервер.
                                          1. николай # 0
                                            Да и еще обе формы, указанные вами, оказались не рабочими.
                                            1. Александр Мальцев # 0
                                              Не знаю, если возникают какие-то ошибки, то надо их получить. Т.е. включайте лог на сервере, смотрите какой приходит ответ (response) с сервера. Если возникает ошибка, то он укажет на какой строчке. А так сложно судить, что у Вас не работает.
                                              Проверять форму необходимо согласно рекомендациям, т.е. разместив её (каталог feedback) в корне сайта. Также это делать необходимо в режиме инкогнито, чтобы не использовался кэшированные файлы. Проверил указанные вам формы, они работают. Так что пытайтесь разобраться, что у вас не так…
                                              1. николай # 0
                                                спасибо.
                                      2. wansal # 0
                                        Уважаемый Александр, будьте добры, помогите. Поставил максимальный размер каждого файла 24 МБ. Но также необходимо, чтобы 24 Мегабайта были максимально возможным объемом сразу всех вложений в совокупности (ящик не принимает письма весом больше 25 МБ, но вдруг человек захочет скинуть, к примеру, всего одну фотографию весом 19 МБ). Возможно ли это сделать? Сейчас при загрузке двух файлов по 20 МБ выскакивает ошибка отправки формы на сервер. И сразу второй вопрос, есть ли возможность загружать несколько файлов за раз, выделив их мышкой? Я прописал атрибут multiple в index.html, но на почту приходит только один файл из нескольких выбранных. Спасибо!

                                        P.S. Форма замечательная, сижу и разбираюсь в коде, всё с комментариями, всё логично и без хаоса. Мне как начинающему очень нравится)
                                        1. Александр Мальцев # 0
                                          Загрузка нескольких файлов с помощью одного элемента input:
                                          Кроме как добавить атрибут multiple, необходимо ещё заменить код цикла, с помощью которого осуществляется добавление элементов в объект FormData:
                                          // перебрать все элементы images с помощью цикла
                                          for (var i = 0; i < images.length; i++) {
                                            // получить список файлов элемента input с type="file"
                                            var fileList = images[i].files;
                                            // если элемент не содержит файлов, то перейти к следующей
                                            if (fileList.length > 0) {
                                              var count = fileList.length;
                                              for (var j = 0; j < count; j++) {
                                                if ((fileList[j].type.match('image.*')) && (fileList[j].size<524288)) {			
                                                  formData.append('images[]', fileList[j], fileList[j].name);
                                                }
                                              }
                                            }
                                          }
                                          
                                          Ограничить максимальный объём наиболее просто с помощью конфигурационного файла веб-сервера. Например, для Apache необходимо добавить в htaccess строку php_value upload_max_filesize 24M. Более подробно: itchief.ru/lessons/php/feedback-form-for-website#comment-3182
                                          Кроме этого необходимо настроить объём в скриптах script.js и verify.php. Кроме этого также можно написать дополнительную проверку в script.js, которая будет суммировать размер всех добавленных для отправки файлов. Если это значение будет больше 24МБ, то выдать пользователю соответствующее сообщение и не отправлять эти файлы на сервер.
                                          1. AlexDeLamaro # 0
                                            Александр, здравствуйте. А подскажите, пожалуйста, что необходимо указать вместо 'image.*' в данном примере, чтобы отправлялись все типы файлов. И можно ли сделать ограничение количества выбранных файлов при такой загрузке? То есть, чтобы можно было выбрать не более 5 файлов.

                                            Просмотрел уйму комментариев, спасибо за то, что откликаетесь и помогаете народу, невероятное количество правок сделано, из этой формы уже можно создавать отдельный мир :)
                                            1. Александр Мальцев # 0
                                              Здравствуйте. Да, осталось только собрать все эти комментарии и доработать форму до нового уровня. Т.е. сделать её универсальной и легко настраиваемой.
                                              1. AlexDeLamaro # 0
                                                С ограничением по типу разобрался: просто убрал из условия выборку по типу (fileList[j].type.match('image.*'). А вот как поставить ограничение на выбор не более 5 файлов — эту задачку я всё никак не могу решить. Буду премного благодарен за помощь.
                                                1. Александр Мальцев # +1
                                                  В HTML не такого атрибута, который мог бы ограничить количество файлов для элемента input (с type, равным file) и атрибутом multiple.
                                                  Вы можете только вывести только предупреждающее сообщение пользователю.
                                                  // если выбраны файлы, то..
                                                  if (e.target.files.length>0) {
                                                    // получить файлы
                                                    var files = e.target.files;
                                                    if (files.length>5) {
                                                      alert('Количество выбранных файлов для отправки превышает допустимое! Будут отправлены только первые 5.');
                                                    }
                                                    ...
                                                  
                                                  Для того чтобы их ограничить при отправке, можно добавить простое условие:
                                                  // перебрать все элементы images с помощью цикла
                                                  for (var i = 0; i < images.length; i++) {
                                                    // получить список файлов элемента input с type="file"
                                                    var fileList = images[i].files;
                                                    // если элемент не содержит файлов, то перейти к следующей
                                                    if (fileList.length > 0) {
                                                      var count = fileList.length;
                                                      if (count>5) {
                                                        count = 5;
                                                      }
                                                      for (var j = 0; j < count; j++) {
                                                        if ((fileList[j].type.match('image.*')) && (fileList[j].size<524288)) {			
                                                          formData.append('images[]', fileList[j], fileList[j].name);
                                                        }
                                                      }
                                                    }
                                                  }
                                                  
                                                  Или можно вообще запретить отправку формы, пока пользователь не выберет количество файлов не более 5.
                                                  1. AlexDeLamaro # 0
                                                    Огромное спасибо, Александр. Взял на вооружение.
                                                    Сегодня обнаружил одну странную штуку: файлы размером 7,5Мб+ не дают форме отправиться. Либо если сумма нескольких выбранных файлов составляет 7,5Мб+. Появляется сообщение «Произошла ошибка при отправке формы на сервер». В script.js и verify.php поставил maxSizeFile = 50000000, в .htaccess ещё больше:

                                                    php_value post_max_size 200M
                                                    php_value upload_max_filesize 100M

                                                    В консоли разработчика Chrome файл verify.php возвращает {result: «error»}. Как лучше отследить ошибку? В чём может быть проблема?
                                                    1. Александр Мальцев # 0
                                                      Сначала необходимо разобраться какая строчка $data['result']='error' возвращает то, что произошла ошибка при отправке формы.
                                                      Наиболее просто это сделать посредством размещения после каждой такой строчки другую (например, с номером строки):
                                                      $data['error']='75';
                                                      После этого посмотреть ответ с сервера и действовать дальше…
                                          2. Сергей # 0
                                            Александр, добрый день!
                                            Возникла вот такая ситуация: клиент с мобильного устройства отправлял сообщение, при этом скорость интернета была не высокой, и получилось, что ему кнопку отправить удалось нажать несколько раз. В результате пришло несколько писем. Возможно ли поставить некий timeout на нажатие кнопки?
                                            1. Александр Мальцев # 0
                                              Можно конечно задать и timeout, но, наверное, данное решение будет более правильным:
                                              beforeSend: function() {
                                                $('#messageForm button[type="submit"]')
                                                  .text('Идёт отправка сообщения...')
                                                  .prop('disabled',true);
                                              },
                                              complete: function() {
                                                $('#messageForm button[type="submit"]')
                                                  .text('Отправить сообщение')
                                                  .prop('disabled',false);
                                              },
                                              
                                              Данный код необходимо поместить в файл script.js, например, перед параметром success функции jQuery ajax. Он перед отправкой будет делать кнопку не активной, и выводить в ней текст «Идёт отправка сообщения...». После получения ответа переводить её обратно в активное состояние и изменять текст на «Отправить сообщение».
                                            2. Дмитрий # 0
                                              Добрый вечер, Александр! Спасибо за форму, всё отлично работает, но единственный момент в выводе капчи. Картинка выводится без https:// в адресе сайта, поэтому браузер ругается, что не все данные защищены.

                                              Искал, где изменить этот путь, но ведь капчу формирует скрипт, в общем не нашел, прошу помощи.

                                              1. Александр Мальцев # 0
                                                Наиболее простой вариант — это добавить в head элемент base:
                                                <base href="https://mysite.ru/">
                                                
                                                Поле этого все пути будут отсчитываться относительно этого адреса.

                                                Или как вариант можно просто указать протокол и имя домена:
                                                <img id="img-captcha" src=https://mysite.ru/feedback/captcha.php">
                                                
                                                1. Дмитрий # 0
                                                  Здравствуйте ещё раз. В общем разобрался я в чем дело. Всё работает отлично, если убрать код из htaccess, который убирает расширение файлов (в моём случае php). Но мне нужно убрать расширение файла, поэтому не знаю как быть?

                                                  В htaccess следующий код:
                                                  RewriteEngine on
                                                  #RewriteCond %{REQUEST_FILENAME} !-f
                                                  #RewriteCond %{REQUEST_FILENAME} !-d
                                                  #RewriteCond %{REQUEST_FILENAME}.php -f
                                                  #RewriteRule ^.*$ $0.php [L,QSA]
                                                  #RewriteCond %{THE_REQUEST} ([^\s]*)\.php(\?[^\s]*)?
                                                  #RewriteRule (.*) %1 [R=301,L]

                                                  Сейчас закомментирован, чтобы формы обратного звонка и обратной связи работали. Если раскомментировать, то вот что пишет браузер в консоли разработчика:



                                                  То есть получается, что файл mail.php загружается без расширения файла и без https (это форма обратного звонка).

                                                  Можно ли в файле htaccess принудительно прописать https://?

                                                  Например как-то так: RewriteCond %{HTTP_HOST}%{REQUEST_URI}%{REQUEST_FILENAME}
                                                  Или это нельзя так писать? В этих апачах вообще не разбираюсь, к сожалению :)))

                                                  Помогите пожалуйста.
                                                  1. Александр Мальцев # 0
                                                    Вам необходимо разобраться с правилами, которые у вас расположены в htaccess. Из каких-то соображений вы же их добавляли.

                                                    Например для того чтобы убрать расширение php, можно использовать следующее:
                                                    RewriteEngine On
                                                    RewriteCond %{REQUEST_FILENAME} !-d
                                                    RewriteCond %{REQUEST_FILENAME} !-f
                                                    RewriteRule (.*) $1.php [L]
                                                    
                                                    (1) — Включаем механизм преобразований
                                                    Определяем условия для применения правила:
                                                    (2) — Проверяем, соответствует ли запрос файлу на сервере. Если нет, то условие выполняется.
                                                    (3) — Проверяем, соответствует ли запрос каталогу на сервере. Если нет, то условие выполняется.
                                                    (4) — Если условия выполняются, то преобразовываем URL, т.е. добавляем к нему .php. После этого останавливаем процесс преобразования URL (флаг L).

                                                    Если же вам необходимо переадресовывать с HTTP на HTTPS то можно воспользоваться следующим правилом:
                                                    RewriteCond %{HTTP:HTTPS} !=on [NC]
                                                    RewriteRule ^(.*)$ https://mysite.ru/$1 [R=301,L]
                                                    
                                                  2. Дмитрий # 0
                                                    Спасибо, попробовал и оба варианта вместе и по отдельности, но не помогло. Всё равно и хром и мозилла ругается, что картинка капчи выводится без https

                                                    попробовал просто открыть картинку капчи в новой вкладке, она с https, а вот в форме выводится без.
                                                2. иван # 0
                                                  Александр, а можно ли сделать чтобы письмо пришло на почту как бы от почты оставленной в форме?
                                                  1. Александр Мальцев # 0
                                                    Можно попробывать это сделать так: $mail->From = $email;
                                                  2. Анна # 0
                                                    Добрый день!
                                                    Вопрос следующий, прикрепили файлы, оказалось, что один ошибочно, как отцепить ссылку, очистить.
                                                    С уважением, Анна.
                                                    1. Александр Мальцев # 0
                                                      Добрый. На текущий момент можно только ещё раз нажать кнопку «Выберите файл» и выбрать действие «Отменить». В следующих версиях учту этот момент и сделаю значок удалить.
                                                    2. Dmitriy # 0
                                                      Добрый день!
                                                      Прошу подсказать куда копать.
                                                      Письма приходят без вложенных файлов.
                                                      С уважением, Дмитрий.
                                                      1. Александр Мальцев # 0
                                                        Здравствуйте. Проверьте права на каталог в которой загружаются файлы на сервер и на их наличие.
                                                      2. Александр # 0
                                                        Если объем прикрепленных файлов велик, то после нажатия кнопки браузер застывает и это вводит пользователя в заблуждение: то ли браузер повис, то ли с соединением что не так. Хорошо бы вывести сообщение типа «Отправляю данные...» а затем его закрыть
                                                        1. Александр # 0
                                                          Воспользовался вашим же сайтом), itchief.ru/lessons/bootstrap-3/bootstrap-3-modal-window
                                                          Сделал так:

                                                          в script.js:

                                                          1)
                                                          if (formValid) {

                                                          $(document).ready(function() {
                                                          $("#myModalBox").modal('show');
                                                          });
                                                          2) После Ajax:

                                                          $("#myModalBox").modal('hide');

                                                          3) В шаблоне формы добавил html код модального окна

                                                          Вроде работает). Спасибо!
                                                        2. Юрий # 0
                                                          Добрый день! Заметил не давно косячёк в форме, видимо когда я добавлял/удалял поля и настраивал внешний вид, что-то зацепил) Проблема в следующем, при не правильно заполненном поле, появляется только общее сообщение сверху формы, о том, что произошла ошибка, заполните правильно поля, но не указано и не подсвечивается конкретно поле с ошибкой. Прилагаю скрин для наглядности. На нем также видно, что все поля, включая с ошибкой, в статусе ОК. Александр, помогите пожалуйста разобраться с данной ошибкой.
                                                          1. Александр Мальцев # +1
                                                            Такое может происходить, если у вас алгоритм проверки полей на клиенте не соответствует алгоритму проверки полей на сервере. Т.е. на клиенте всё хорошо, а когда данные приходят на сервер там обнаруживается ошибка. В этом случае ответ с сервера необходимо обработать и предоставить пользователю детальное описание ошибки.
                                                            На текущий момент могу предложить такое решение (код необходимо добавить в script.js и доработать в соответствии с полями формы):
                                                            Код...
                                                            else {
                                                              // если сервер вернул ответ error, то делаем следующее...
                                                              var errorText = 'Произошли ошибки при отправке формы на сервер.'
                                                              if ($data.name) {
                                                                errorText = errorText + '
                                                            ' + $data.name;
                                                                var nameInput = $("#name");
                                                                // находим предка, имеющего класс .form-group (для установления success/error)
                                                                formGroupName = nameInput.parents('.form-group');
                                                                // находим glyphicon (иконка успеха или ошибки)
                                                                glyphiconName = formGroupName.find('.form-control-feedback');
                                                                // добавляем к formGroup класс .has-error и удаляем .has-success
                                                                formGroupName.addClass('has-error').removeClass('has-success');
                                                                // добавляем к glyphicon класс glyphicon-remove и удаляем glyphicon-ok
                                                                glyphiconName.addClass('glyphicon-remove').removeClass('glyphicon-ok');
                                                              }
                                                              if ($data.phone) {
                                                                errorText = errorText + '
                                                            ' + $data.phone;
                                                                var phoneInput = $("#phone");
                                                                // находим предка, имеющего класс .form-group (для установления success/error)
                                                                formGroupPhone = phoneInput.parents('.form-group');
                                                                // находим glyphicon (иконка успеха или ошибки)
                                                                glyphiconPhone = formGroupPhone.find('.form-control-feedback');
                                                                // добавляем к formGroup класс .has-error и удаляем .has-success
                                                                formGroupPhone.addClass('has-error').removeClass('has-success');
                                                                // добавляем к glyphicon класс glyphicon-remove и удаляем glyphicon-ok
                                                                glyphiconPhone.addClass('glyphicon-remove').removeClass('glyphicon-ok');
                                                              }
                                                              if ($data.message) {
                                                                errorText = errorText + '
                                                            ' + $data.message;
                                                                var messageInput = $("#message");
                                                                // находим предка, имеющего класс .form-group (для установления success/error)
                                                                formGroupMessage = messageInput.parents('.form-group');
                                                                // находим glyphicon (иконка успеха или ошибки)
                                                                glyphiconMessage = formGroupMessage.find('.form-control-feedback');
                                                                // добавляем к formGroup класс .has-error и удаляем .has-success
                                                                formGroupMessage.addClass('has-error').removeClass('has-success');
                                                                // добавляем к glyphicon класс glyphicon-remove и удаляем glyphicon-ok
                                                                glyphiconMessage.addClass('glyphicon-remove').removeClass('glyphicon-ok');
                                                              }
                                                            

                                                            Скоро представлю новую версию формы обратной связи, которая станет более гибкой и легко настраиваемой. Если есть время, то можете подождать или воспользоваться вышеприведённым кодом…
                                                          2. Tracktor # 0
                                                            Здравствуйте, Александр.
                                                            Возникла новая проблема с кодировкой.
                                                            При отправке письма с ящика mail.ru вся кириллица приходит в нечитаемом виде.
                                                            Везде где только можно проставлена utf-8 (htaccess, все php-файлы, также сами документы тоже в нормальной кодировке).
                                                            Пока тестировал форму, отправлял с яндекса — проблем не было. Вот код:
                                                            $mail = new PHPMailer;
                                                            $mail->CharSet = 'UTF-8';
                                                            $mail->IsHTML(true);
                                                            $mail->From      = 'adres_yashika@mail.ru';
                                                            $mail->FromName  = 'Вам письмо';
                                                            $mail->Subject   = $t_obr;
                                                            $mail->Body      = $output;
                                                            $mail->AddAddress( 'adres_yashika@mail.ru' );
                                                            $mail->AddReplyTo("$email");
                                                            
                                                            Примечательно ещё то, что если заменить $t_obr и\или $output например на 'Тест' — то приходит нормально. Если же оставить в виде переменной — «кракозябры». Как выяснилось, кракозябры в виде кодировки windows-1251.
                                                            Пробовал iconv('windows-1251', 'utf-8', $t_obr); — не помогло, только кодировка ещё боле преображается.

                                                            Что ещё может быть не так?
                                                            1. Tracktor # 0
                                                              Похоже, разобрался.
                                                              mb_convert_encoding($t_obr, 'ISO-8859-1', 'UTF-8');
                                                              То же самое проделал и с $message.
                                                              Интересно, что такого особенного в ящиках mail.ru, что они так делают…

                                                              Александр, просьба всё равно ответить, вдруг реальная проблема в чём-то другом, а я огороды горожу, и есть выход проще…
                                                              1. Александр Мальцев # 0
                                                                Если изменил UTF-8 на utf-8 — но ничего не поменялось, то попробуй проверить кодировку страницы. Она тоже должна быть в UTF-8.
                                                                Не знаю, может еще, как вариант попробовать установить кодировку точно такую же, которая используется в ящиках mail.ru.
                                                                1. Александр Мальцев # 0
                                                                  Попруйте указать кодировку строчными буквами:
                                                                  $mail->CharSet = 'utf-8';
                                                                  
                                                                  Такое ощущение, что ваш сервер просто игнорирует эту строчку.
                                                              2. Константин # 0
                                                                Александр, добрый день!
                                                                Где можно прописать, чтобы кнопкой вызова формы была моя картинка (в стиле сайта), а также где можно задать координаты и размер формы на сайте, управлять затемнением фона? В частности, хочу сделать, чтобы форма выходила точно под кнопкой и не было общего затемнения фона (просто на фоне сайта определенном месте). Или такие задачи уже не входят в данный урок?
                                                                Большое спасибо.
                                                                1. Александр # 0
                                                                  Большое спасибо за отличную форму, и за все остальное на этом сайте.

                                                                  Касательно формы — единственное, что я не понял, это где можно поменять этот текст:



                                                                  Спасибо!
                                                                  1. Александр Мальцев # 0
                                                                    Если необходимо поменять требование к полю, то это в данном случае можно осуществить с помощью атрибутов minlength и maxlength. Если нужно изменить само сообщение, то никак. Оно выдаётся самим браузером.

                                                                    Если вы не хотите чтобы форму проверял браузер, то к ней необходимо добавить атрибут novalidate:
                                                                    <form id="messageForm" enctype="multipart/form-data" novalidate>
                                                                      ...
                                                                    </form>
                                                                    
                                                                    После этого проверку будет осуществлять только код, находящийся в файле script.js. Для создания собственных подобных всплывающих сообщений можно воспользоваться компонентами tooltip или jGrowl. С помощью них можно настроить вывод таких сообщений, которые будут Вам нужны.
                                                                    1. Александр # 0
                                                                      Большое спасибо. Даже информация о том, что этот текст выдает сам браузер полезна для манипулирования этим текстом
                                                                  2. Вася # 0
                                                                    Здравствуйте! Установил Ваш исходник на сайт, возникли проблемы с загрузкой файлов на сервер.Я чуть-чуть подкорректировал ваш код, для отправки письма решил использовать функцию mail(), все работает, если не загружать файл, если загружать, почему-то if вылетает сюда "$data['files']='Ошибка при загрузке файлов.';". Я начал копать и понял что файл вообще не заливается на сервер.

                                                                    Корректировки:

                                                                    $output = «Дата: ». date(«d-m-Y H:i»). "\n";
                                                                    $output .= «Имя пользователя: ». $name. "\n";
                                                                    $output .= «Адрес email: ». $email. "\n";
                                                                    $output .= «Сообщение: ». "\n". $message. "\n";
                                                                    $output .= «Файлы: ». "\n". $tmpFile. "\n". $newFullFileName.
                                                                    "\n";

                                                                    $to = «admin@домен»;
                                                                    $sub = «Сообщение с формы обратной связи»;

                                                                    if (mail($to, $sub, $output, «Content-type: text/plain; charset=utf-8»))
                                                                    {
                                                                    $data['result']='success';
                                                                    }
                                                                    else {
                                                                    $data['result']='error';
                                                                    }

                                                                    Письмо на почту:_

                                                                    Дата: 08-01-2017 13:11
                                                                    Имя пользователя: Вася
                                                                    Адрес email: dddd@ms.yu
                                                                    Сообщение:
                                                                    Текст сообщения!!!
                                                                    Файлы:
                                                                    /tmp/phpEyEaDX
                                                                    /var/www/html/assets/files/img_58721055910225.71886193.png

                                                                    По адресу /tmp/phpEyEaDX ни чего нет, поэтому и функция move_uploaded_file() вылетает в else. Начал копать дальше в js и понял, что не работает «console.log(file);», соответственно значит «if ((file.type.match('image.*')) && (file.size<524288))» уходит в else, так и не решил данную проблему, решил написать Вам. Пробовал менять переменную «upload_tmp_dir», директория меняется, а файл или удаляется сам, или просто не грузиться…

                                                                    В чем может быть причина?
                                                                    1. Вася # 0
                                                                      Вроде разобрался, оказывается на директорию прав на запись не хватало…
                                                                    2. Константин # 0
                                                                      Добрый день, Александр. С Новым годом.
                                                                      А на XAMPP эту форму можно проверить? Пока ошибку доступа выдает, хотя для всех файлов директории прописал расширенные права.
                                                                      1. Александр Мальцев # 0
                                                                        Спасибо, Константин. И вас также. Без настройки путей она должна работать из корня сайта (путь_до_сайта/feedback/*.*). Если вы переместили форму в какое-то другое место, то укажите в форме и скрипте дорогу к текущему расположению файлов.
                                                                        1. Константин # 0
                                                                          Да, именно так и сделал, папка feedback в корне сайта. Ну и кнопке на сайте ссылку прописал (на файл index.html в папке feedback). Больше ничего не трогал пока. А вот что система отвечает при нажатии на кнопку:

                                                                          Access forbidden!
                                                                          You don't have permission to access the requested object. It is either read-protected or not readable by the server.

                                                                          Всем исполняемым файлам в папке feedback поставил расширенные права (на чтение и изменение)
                                                                          Не могу понять, то ли мне надо с правами доступа разобраться, то ли в коде формы что-то поменять.
                                                                          1. Александр Мальцев # 0
                                                                            Попробуйте поставить на файлы и папки максимальные права. Или проверить разрешения в файле .htaccess.
                                                                      2. Юрий # 0
                                                                        Здравствуйте, Александр. Отличный у Вас ресурс.
                                                                        Есть вопрос, хотел для тренировки скопировать форму с сайте. И нашел Ваш сайт.

                                                                        Имеется контактная форма реализованная по данной статье ogothic.ru/uber/connect.html
                                                                        Под нее не получается написать скрипт verify.php

                                                                        Файлы со скриптами и html здесь
                                                                        yadi.sk/d/2qsR2hZW34nF5y

                                                                        Если подскажите в какую сторону копать, буду очень благодарен
                                                                        1. Александр Мальцев # 0
                                                                          Здравствуйте, Юрий. Спасибо. У вас в проекте нет файла php, который будет выполнять обработку форму. Если вы хотите, то можете использовать verify.php. Вам необходимо будет только немного отредактировать его под ваши поля (данные), а также настроить результат, который он должен передавать клиенту (браузеру).
                                                                        2. иван # 0
                                                                          и можно ли сделать чтобы после нажатия кнопки отправить выходила анимация загрузки если есть файл, картинка большим обьемом
                                                                          1. Александр Мальцев # 0
                                                                            Посмотри в этом комментарии, может, подойдёт:
                                                                            itchief.ru/lessons/bootstrap-3/creating-feedback-form-using-bootstrap-php-and-ajax#comment-1962
                                                                          2. иван # 0
                                                                            Здравствуйте Александр!

                                                                            А можно сделать в виде боковой кнопки по нему кликать и как popup выходит??
                                                                            1. Александр Мальцев # 0
                                                                              Здравствуйте. Посмотреть, как сделать, чтобы при нажатии по кнопке форма открывалась во всплывающем окне можно в этой статье.
                                                                            2. tatian # 0
                                                                              Добрый день!
                                                                              Александр, столько было разных изменений к форме, постоянно я что-то меняла — в итоге все испортила. Вы не могли бы сбросить ссылку, где будет интерфейс первоначальной, но с измененными скриптами. пожалуйста
                                                                              1. Александр Мальцев # 0
                                                                                Здравствуйте. В статье есть кнопка для скачивания сборки формы feedback для сайта. Или вам необходимо что-то другое?
                                                                                1. tatian # 0
                                                                                  Первоначально был минимальный набор полей. Потом были добавлены другие форматы файлов для скачивания, информация как добавлять новые поля. В конце концов я пыталась у себя все менять, добавлять и ничего не получилось. Да и загруженные файлы не приходят на электронку.
                                                                                  Мне необходимо, чтобы были кроме первоначальных полей еще поля с фамилией, адресом и можно было загружать многие форматы, в т.ч текстовые. Простите, я плохо разбираюсь, но мне такая форма нравится и очень нужна. Спасибо
                                                                                  1. Александр Мальцев # 0
                                                                                    Первоначальная форма, к которой добавлены поля с фамилией и адресом, а также возможность прикреплять текстовые файлы (txt, doc, docx) — yadi.sk/d/z5ffeiS834A4dA
                                                                                    1. tatian # 0
                                                                                      Александр, спасибо!
                                                                              2. Сергей # 0
                                                                                Добрый день, Алкександр!
                                                                                Хотел задать еще один вопрос, а где можно изменить ширину формы?
                                                                                Все отлично, просто она мне немного широковата.
                                                                                1. Александр Мальцев # 0
                                                                                  Ширина задаётся классом col-sm-6. 6 — это часть от 12 (100%). В данном случае он задаёт ширину, равную 50% от родительской ширины. Класс col-sm-offset-3 задаёт смещение, в данном случае 3 от 12, т.е. 25%. При необходимости можно настроить или задать всё по-другому.
                                                                                2. Сергей # 0
                                                                                  Здравствуйте, Александр!
                                                                                  Отличная форма! Только столкнулся со странной проблемой при ее реализации.
                                                                                  Например, простая форма: имя + телефон работает прекрасно, но как только я хочу использовать форму: имя + email + комментарий + файл, все работать перестает.
                                                                                  Причем, браузер ни какой ошибки не показывает, просто ничего не происходит

                                                                                  В консоле удалось увидеть следующую ошибку:

                                                                                  VM1305:1 Uncaught SyntaxError: Unexpected token < in JSON at position 0(…)
                                                                                  success @ script.js:127
                                                                                  i @ jquery-1.12.4.min.js:2
                                                                                  fireWith @ jquery-1.12.4.min.js:2
                                                                                  y @ jquery-1.12.4.min.js:4
                                                                                  c @ jquery-1.12.4.min.js:4

                                                                                  В файле script.js консоль указывает на ошибку в строке:
                                                                                  var $data = JSON.parse(data);

                                                                                  Помогите понять причину.

                                                                                  1. Александр Мальцев # 0
                                                                                    Это означает, что у вас не до конца отрабатывает скрипт verify.php. Наиболее просто понять, почему это происходит можно на вкладке Network в инструментах разработчика браузера. Скриншот, с основными элементами этой вкладки можно посмотреть в этом комментарии.
                                                                                    1. Сергей # 0
                                                                                      Да, причину удалось установить. Оказалось, что у хостера в настройках PHP не было включено расширение filter.
                                                                                  2. Мария # 0
                                                                                    Огромное спасибо за замечательную форму.
                                                                                    При внедрении на сайт возникла пара проблем.
                                                                                    1. Форма открывается в модальном окне. Как сбросить значения заполнения полей, если форма не была отправлена, а только было закрыто модальное окно?
                                                                                    2. В форме есть select, в зависимости от выбора значения которого показывается блок с определенными полями, некоторые из которых являются обязательными. Перед отправкой по умолчанию идет проверка на заполнение обязательных полей, и скрипт «проверяет» те поля, которые скрыты выбором option, и требует их заполнить. Как отключить проверку полей, которые не отображаются в подставляемом блоке?
                                                                                    1. Александр Мальцев # 0
                                                                                      Спасибо. Для очистки формы можно использовать следующий код:
                                                                                      // messageForm - id формы, расположенной в модальном окне
                                                                                      $('#messageForm').find('input,textarea').each(function(){
                                                                                        $(this).val('');
                                                                                      });
                                                                                      
                                                                                      Данный код необходимо заставить выполнятся при наступлении некоторого события, связанного с открытием модального окна.
                                                                                      Если вы используете модальное окно Bootstrap, то это можно сделать так:
                                                                                      // id-modal - id модального окна
                                                                                      $('#id-modal').on('show.bs.modal', function (e) {
                                                                                        $('#messageForm').find('input,textarea').each(function(){
                                                                                          $(this).val('');
                                                                                        });
                                                                                      })
                                                                                      
                                                                                      Не добавляйте к полям формы, которые заполнять не обязательно, атрибут required.
                                                                                      1. Мария # 0
                                                                                        Не добавляйте к полям формы, которые заполнять не обязательно, атрибут required.
                                                                                        У необязательных полей эти атрибуты отсутствуют. Вопрос в том, как исключить из проверки те, которые обязательные, но не показываются.
                                                                                        1. Александр Мальцев # 0
                                                                                          1. Добавить атрибут novalidate для формы.
                                                                                          2. В файле script.js указать в строчке необходимые элементы для перебора:
                                                                                          $('#messageForm input,#messageForm textarea').each(function () {
                                                                                          
                                                                                          Или исключить их, добавив после строчек
                                                                                          //если этот элемент капча, то не проверять его
                                                                                          if ($(this).attr('id') == 'text-captcha') { 
                                                                                            return true;
                                                                                          }
                                                                                          
                                                                                          подобный код
                                                                                          //идентификатор элемента для исключения из проверки
                                                                                          if ($(this).attr('id') == 'идентификатор_элемента') { 
                                                                                            return true;
                                                                                          }
                                                                                          
                                                                                    2. tatian # 0
                                                                                      Спасибо, к сожалению, я плохо разбираюсь.
                                                                                      Это не знаю как просмотреть «консоль разработчика -> NetWork -> verify.php»
                                                                                      1. Александр Мальцев # 0
                                                                                        Тут нет ничего сложного. Эта вкладка, расположена в браузере (в инструментах разработчика). Вызвать её можно с помощью сочетания клавиш Ctrl+Shift+I или через меню.
                                                                                        Вкладка NetWork в инструментах разработчика браузера
                                                                                      2. tatian # 0
                                                                                        Добрый день!
                                                                                        Александр, после заполнения всех полей не выдается сообщение «Внимание! Ваше сообщение отправлено», но на мою почту письма приходят. В чем может быть проблема? Спасибо
                                                                                        1. Александр Мальцев # 0
                                                                                          Здравствуйте. Попробуйте проверить следующие моменты:
                                                                                          1. Убедитесь, что с сервера приходит ответ success (консоль разработчика -> NetWork -> verify.php)
                                                                                          2. Проверьте, есть ли у вас на странице блок с идентификатором msgSubmit. Данный id на странице должен быть всего один и содержит соответствующий текст.
                                                                                          3. Проверьте, соответствует ли у вас кодировка, в которой сервер присылает ответ с кодировкой файла script.js.
                                                                                        2. Tracktor # 0
                                                                                          Здравствуйте.
                                                                                          Пытаюсь добавить к разрешённым расширениям файлов doc, docx, xls, xlsx и pdf. Внёс изменения script.js и в verify.php. Но при выборе файла всё равно пишет «Неверный тип»… Где может быть косяк?
                                                                                          1. Александр Мальцев # 0
                                                                                            Здравствуйте. В этом архиве можете посмотреть, как сделать файл script.js: yadi.sk/d/23HW2CRgtc5H5
                                                                                            1. Tracktor # 0
                                                                                              C файлами разобрался, но теперь появилась другая проблема — установил размер файлов больше 512 кб. Если отправлять небольшие файлы, всё проходит отлично (использую версию с прелоадером) — крутится, выводит сообщение об успешной отправке, доставляет. Но если отправить файл размером 2+ мб, то отправка происходит нормально, но прелоадер продолжает крутиться и крутиться, даже когда само письмо уже пришло на почту… Если убрать прелоадер, то всё то же самое, только страница не меняется и сообщение об успешной отправке не появляется. В чём может быть проблема?
                                                                                              1. Александр Мальцев # 0
                                                                                                Возможно, браузер не дожидается ответа от сервера. Попробуйте добавить в функцию ajax параметр timeout со значением 0 или какое-то большое значение в мс:
                                                                                                timeout: 0,
                                                                                                
                                                                                                А также при необходимости данное состояние запроса можно обработать:
                                                                                                error: function(jqXHR, textStatus, errorThrown) {
                                                                                                  if(textStatus==="timeout") {  
                                                                                                    alert("Время ожидания ответа от сервера истекло");
                                                                                                  }
                                                                                                }
                                                                                                
                                                                                                1. Tracktor # 0
                                                                                                  Может, я сделал что-то не так, но это усугубило ситуацию.
                                                                                                  Добавил
                                                                                                  timeout: 0,
                                                                                                  сюда:
                                                                                                  // технология AJAX 
                                                                                                        $.ajax({
                                                                                                          //метод передачи запроса - POST
                                                                                                          type: "POST",
                                                                                                          //URL-адрес запроса 
                                                                                                          url: "/feedback/verify.php",
                                                                                                          //передаваемые данные - formData
                                                                                                          data: formData,
                                                                                                          // не устанавливать тип контента, т.к. используется FormData
                                                                                                          contentType: false,
                                                                                                          // не обрабатывать данные formData
                                                                                                          processData: false,
                                                                                                          // отключить кэширование результатов в браузере
                                                                                                          cache: false,
                                                                                                          timeout: 0,
                                                                                                  После этого ничего нового не произошло, но отправка письма весьма замедлилась (я не дождался и перезагрузил страницу, и только минут через 15-20 отправленное письмо пришло на почту). И после этого перестала подтягиваться капча. При добавлении обработки (добавлял перед
                                                                                                  error: function (request) {
                                                                                                            $('#error').text('Произошла ошибка ' + request.responseText + ' при отправке данных.');
                                                                                                  ) тоже ничего не изменилось…

                                                                                                  Ещё грешу на настройки PHP для отправки почты (у меня отправляет sendmail, по-другому не умею, сам не очень силён в веб-программировании).
                                                                                                  1. Александр Мальцев # 0
                                                                                                    Попробуйте ставить не 0, а какое-то определённое время, которое может ждать пользователь, например, секунд 7.
                                                                                                    timeout: 7000,
                                                                                                    
                                                                                                    После этого времени убирать прелоадер и отображать пользователю некоторое сообщение.
                                                                                                    error: function(jqXHR, textStatus, errorThrown) {
                                                                                                      if(textStatus==="timeout") {  
                                                                                                        // убираем прелоадер
                                                                                                        // отображаем пользователю некоторое сообщение
                                                                                                      }
                                                                                                    }
                                                                                                    
                                                                                                    Ещё как вариант, попробуйте поработать со страницей из режима инкогнито. А то может, вы работаете с кэшированными (старыми) версиями скриптов.
                                                                                              2. Tracktor # 0
                                                                                                Спасибо. Да, там где проверка идёт, оставил как в старом, поэтому не работало.
                                                                                                Ещё раз громадный респект за форму.
                                                                                            2. Юлия # 0
                                                                                              Добрый день. Понимаю, что вас замучили уже вопросами, но может быть сможете помочь. Я новичок в PHP, пытаюсь разобраться уже несколько дней, но ничего не выходит.
                                                                                              Скачала форму по ссылке yadi.sk/d/23HW2CRgtc5H5, но:
                                                                                              * на все прикрепленные файлы высвечивается «Файл не будет отправлен, т.к. его тип не соответствует разрешённому» (http://joxi.ru/5mdYgknik4yR12), при этом картинки отправляются и на почту попадают;
                                                                                              * а вот архивы совершенно не отправляются (т.е. письмо уходит, но архивы не прикрепляются).
                                                                                              Заранее благодарю за ответ
                                                                                              1. Александр Мальцев # 0
                                                                                                Добрый день, Юлия. Проверьте, использует ли страница правильный файл script.js (т.е. тот который приведён в указанной вами форме)… По умолчанию каталог указанной формы, после извлечения из архива, необходимо переименовать в feedback и расположить в корне сайта.
                                                                                                1. Юлия # 0
                                                                                                  Александр, скрипт правильный, папка переименована
                                                                                                  1. Александр Мальцев # 0
                                                                                                    Проверил, работает. Не знаю, с чем у вас это может быть связано. Попробуйте, открыть страницу в режиме инкогнито… Может быть, у вас кэшируются стили и скрипты страницы.
                                                                                                    А также вставьте в файл script.js после
                                                                                                    formData.append('images[]', file, file.name);
                                                                                                    
                                                                                                    строчку
                                                                                                    console.log(file.name);
                                                                                                    
                                                                                                    и посмотрите вл вкладке Console браузера какие файлы у вас выводятся.
                                                                                                    Или используйте вкладку NetWork в браузере (в режиме разработчика).
                                                                                                    1. Юлия # 0
                                                                                                      Спасибо большое, в режиме инкогнито и после чистки кэша заработало)))) Благодарю за подсказку
                                                                                              2. Oleg # 0
                                                                                                Здравствуйте Александр, спасибо за форму, все работает отлично. Только объясните как убрать поле прикрепления файлов, я если убираю, то перестает работать отправка письма. Спасибо.
                                                                                                1. Александр Мальцев # 0
                                                                                                  Здраствуйте. Форма feedback без прикрепления к ней файлов: yadi.sk/d/q1_QiZj532HVYX
                                                                                                2. wolkkkaa # 0
                                                                                                  Я чуток тугой в этом.
                                                                                                  А где указывать свою почту.чтобы принимать письма.жду ответа!
                                                                                                  там мне нравки все!
                                                                                                  1. Александр Мальцев # 0
                                                                                                    Открыть файл verify.php и на строчке 183 вместо myemail@mail.ru вписать свою почту.
                                                                                                  2. Любомир # 0
                                                                                                    Здравствуйте, Александр!
                                                                                                    Очень красивая форма, все в ней устраивает, но я хочу убрать поля капча и сообщение.
                                                                                                    Оставить только имя и телефон. К сожалению, это не получается у меня, в итоге форма перестает работать, хотя удаляю куски кода из файлов указанных в статье.
                                                                                                    Понимаю, что вас уже достали здесь комментариями, но не могли бы вы сделать вариант только с именем и телефоном?
                                                                                                    Буду очень благодарен и оставлю вам донат :)
                                                                                                    1. Александр Мальцев # +1
                                                                                                      Здравствуйте.
                                                                                                      Ссылка для формы, состоящей только из имени и номера телефона: yadi.sk/d/_UrVReQ2zzvgP.
                                                                                                    2. Alexander # 0
                                                                                                      Как их посмотреть, если их нет, а точнее я их не вижу.
                                                                                                      Тариф поддерживает отправку писем, поскольку раньше использовал другие формы.
                                                                                                      _http://u-lab.ru/arch/ ссылка на форму справа вверху «напишите нам»
                                                                                                      Вот что отображается после нажатия на кнопку «Отправить сообщение»
                                                                                                      itchief.ru/assets/uploadify/b/5/2/b526bf09c1c377d021f28bacec28e225.png
                                                                                                      1. Александр Мальцев # 0
                                                                                                        У вас возникает ошибка на 46 строчки в файле verify.php. А именно проблема с вызовом несуществующей функции filter_var. Скорее всего, у вас версия PHP, в которой её нет.
                                                                                                        Можете просто убрать проверку поля email (или заменить её на что-то другое).
                                                                                                        Чтобы удалить проверку, замените нижеприведённый код:
                                                                                                        //получить email, которое ввёл пользователь
                                                                                                        if (isset($_POST['email'])) {
                                                                                                          $email = $_POST['email'];
                                                                                                          if (!filter_var($email,FILTER_VALIDATE_EMAIL)) {
                                                                                                            $data['email']='Поле email введено неправильно';
                                                                                                            $data['result']='error';
                                                                                                          }
                                                                                                        } else {
                                                                                                          $data['result']='error';
                                                                                                        }
                                                                                                        
                                                                                                        на:
                                                                                                        //получить email, которое ввёл пользователь
                                                                                                        if (isset($_POST['email'])) {
                                                                                                          $email = $_POST['email'];
                                                                                                        } else {
                                                                                                          $data['result']='error';
                                                                                                        }
                                                                                                        
                                                                                                        1. Alexander # 0
                                                                                                          Александр, спасибо большое!
                                                                                                          Всё работает как часы!
                                                                                                          Удачи!
                                                                                                      2. Alexander # 0
                                                                                                        Добрый день.
                                                                                                        Такая проблемка:
                                                                                                        Запилил форму в модальное окно, выглядит очень красиво, но в denver форма выполняется отлично, а вот на хостинге не хочет… не проверяется капча и не отправляется сообщение.
                                                                                                        1. Александр Мальцев # 0
                                                                                                          Здравствуйте.
                                                                                                          Посмотрите, какие возникают ошибки. А также проверьте, поддерживает ли тариф вообще отправку писем…
                                                                                                        2. Андрей # 0
                                                                                                          Нашел ответ по кодировке в ветке выше, помогло $mail->CharSet = 'utf-8';.
                                                                                                          Александр, ваша сайт Супер!!!
                                                                                                          1. Андрей # 0
                                                                                                            Спасибо так работает. Только кириллическое написание имени отправителя почему-то получается кракозябрами. Как и заголовок письма.
                                                                                                            1. Андрей # 0
                                                                                                              Заголовок (тема, сервера откуда отправлено и т.п.) письма точно такой-же, как и в нормальных письмах. Это и озадачило. Правда я судя по всему использую не самую последнюю вашу версию исходников, без phpmailer. Может быть из-за этого?
                                                                                                              И кстати давно хотел спросить, как сделать replay-to, что-бы отвечая на письмо, сразу подставлялся адрес, введенный отправителем?
                                                                                                              1. Александр Мальцев # 0
                                                                                                                В первых версиях формы обратной связи проверки на стороне сервере вообще не было. Так что пора обновить…
                                                                                                                В файл php необходимо добавить строчку:
                                                                                                                $mail->AddReplyTo('replyto@email.com', 'Reply to name');
                                                                                                                
                                                                                                                1. Андрей # 0
                                                                                                                  Правильно я понял, что добавить в файл verify.php? Возможно я не туда добавил, но при ответе теперь обратный адрес подставляется так «Reply to name <replyto@email.com>», а не адрес, введенный отправителем.
                                                                                                                  1. Александр Мальцев # 0
                                                                                                                    Вам необходимо подставить значения соотвествующих переменных:
                                                                                                                    $mail->AddReplyTo($email, 'Reply to ' . $name);
                                                                                                                    
                                                                                                              2. Андрей # 0
                                                                                                                Александр приветствую. Ваша форма обратной связи на моем сайте благополучно работает уже пол года, но вот сегодня почему-то пришло совершенно пустое письмо — ни адресата, ни текста, вообще ничего. Это меня озадачило, поскольку обычно выполняются всякие проверки перед отправкой. Как такое может происходить?
                                                                                                                1. Александр Мальцев # 0
                                                                                                                  Проверки в файле verify.php есть. Может быть, письмо было отправлено не из этой формы, а каким-то другим способом. Кстати тема письма совпадает с тем, какое вы установили ему в файле verify.php?
                                                                                                                2. Максим # 0
                                                                                                                  Доброго времени суток.
                                                                                                                  Просмотрел комменты, своей проблемы не нашел.
                                                                                                                  Добавил парочку новых строк в форму.
                                                                                                                  Письмо с формы приходит, но с новых строк видны только заголовки, самого вводимого содержимого строки в письме нету.
                                                                                                                  Буду рад совету. Спасибо.
                                                                                                                  1. Александр Мальцев # 0
                                                                                                                    Здравствуйте.
                                                                                                                    Посмотрите ответ на подобный вопрос:
                                                                                                                    itchief.ru/lessons/bootstrap-3/creating-feedback-form-using-bootstrap-php-and-ajax#comment-3334
                                                                                                                  2. lood # 0
                                                                                                                    Добрый день! У меня форма почему то не работает.
                                                                                                                    Адрес указал в строке 184: $mail->AddAddress( 'info@***.ru' );.
                                                                                                                    После отправки пишется «сообщение отправлено». Но по факту, письма не приходят.
                                                                                                                    Что мне еще нужно дописать?
                                                                                                                    1. Александр Мальцев # 0
                                                                                                                      Необходимо сначала проверить поддерживает ли хостинг вообще отправку писем или нет.
                                                                                                                      1. lood # 0
                                                                                                                        Александр, да, такав возможность у моего хостинга есть, она подключена.
                                                                                                                        Может быть мне в коде нужно какие то атрибуты подключить еще?
                                                                                                                        1. Александр Мальцев # 0
                                                                                                                          Может они попадают в спам. Необходимо проверить этот момент.
                                                                                                                          1. lood # 0
                                                                                                                            Александр! Ну, конечно же я это проверил!!! А то бы, даже спрашивать не стал! )
                                                                                                                            Какие еще варианты решения могут быть?
                                                                                                                            1. Александр Мальцев # 0
                                                                                                                              Проверьте для начала, уходит ли почта.
                                                                                                                              Этого можно сделать так:
                                                                                                                              1. Удалить весь код из файла, кроме отправки файла.
                                                                                                                              require_once dirname(__FILE__) . '/phpmailer/PHPMailerAutoload.php';
                                                                                                                              $mail = new PHPMailer;
                                                                                                                              $mail->From      = 'email@mysite.ru';
                                                                                                                              $mail->FromName  = 'Имя сайта';
                                                                                                                              $mail->Subject   = 'Сообщение с формы обратной связи';
                                                                                                                              $mail->Body      = 'Текст письма';
                                                                                                                              $mail->AddAddress( 'myemail@mail.ru' ); // куда отправить
                                                                                                                              $mail->Send();
                                                                                                                              
                                                                                                                              2. Запустить данный скрипт на выполнение.
                                                                                                                              3. Проверить в почтовом ящике письмо.
                                                                                                                              1. lood # 0
                                                                                                                                В файле verify.php удалил все, вставил текст, который Вы написали выше. Больше ничего не трогал. При нажатии «Отправить» ничего не происходить. Письма не приходят.
                                                                                                                                Что делать?
                                                                                                                                1. Александр Мальцев # 0
                                                                                                                                  Если ваш тариф хостинга позволяет отправку писем, то напишите о проблеме в техподдержку. Также можете включить лог ошибок в панели управления хостингом, открыть файл, в который они пишутся, и посмотреть какие ошибки у вас возникают.
                                                                                                                    2. Виктор # 0
                                                                                                                      И как ещё сделать выпадающий список? Что пользователь мог выбрать один из вариантов
                                                                                                                      1. Александр Мальцев # 0
                                                                                                                        В этом комментарии itchief.ru/lessons/php/feedback-form-for-website#comment-3161 есть ответ на ваш вопрос.
                                                                                                                        1. Виктор # 0
                                                                                                                          Спасибо большое за ответы, буду попробовать)
                                                                                                                      2. Виктор # 0
                                                                                                                        Всем доброго времени суток! У меня вопрос
                                                                                                                        Я снимаю вроде все ограничения по закачки файла (по умолчанию 512 КБ) делаю 1.5 МБ. После заполнения формы, пишет, что письмо отправлено, но в папке file этого файла нету (файл весит 1.4 Мб), а в текстовом документе отображается всё, кроме ссылки на файл. Это как нибудь можно исправить? Мне надо что бы люди могли закачивать файлы до 10 Мб

                                                                                                                        p.s. Закачиваю файл в размере 250 Кб, всё везде появляется
                                                                                                                        1. Александр Мальцев # 0
                                                                                                                          Кроме как изменить в скриптах, необходимо ещё настроить соответсвующие директивы.
                                                                                                                          Попробуйте воспользоваться этим ответом:
                                                                                                                          itchief.ru/lessons/php/how-to-install-recaptcha-on-website#comment-2896
                                                                                                                        2. Кирилл # 0
                                                                                                                          Здравствуйте.
                                                                                                                          Попытался заместо видения email сделать выбор категории, но приходит следующие — Выбрана категория: undefined.
                                                                                                                          Где я накосячил?
                                                                                                                          1. Александр Мальцев # 0
                                                                                                                            Не совсем понял про категорию. Если категорией является HTML элемент select, то сначала в javascript необходимо получить его значение (с помощью метода val()), поместить в объект FormData. А на сервере получить это значение ($_POST['имя_ключа']), на основании ключа, с которым было связано это значение в FormData. После этого что-то с ним сделать (например, вывести или сравнить с чем-нибудь и т.д.).
                                                                                                                            1. Kirill2511 # 0
                                                                                                                              В HTML вписал следующие —
                                                                                                                              <div class="form-group has-feedback">
                                                                                                                                                  <label for="selec" class="control-label">Выберите категорию:</label>
                                                                                                                                                  <select class="form-control" name="selec">
                                                                                                                                                  <option selected value="1">qwe</option>
                                                                                                                                                  <option value="2">qwer</option>
                                                                                                                                                  </select>
                                                                                                                              В js —
                                                                                                                                    var selec = $("#selec").val();
                                                                                                                                    formData.append('selec', $("#selec").val() );
                                                                                                                              
                                                                                                                              В php —
                                                                                                                                  if (isset($_POST['selec'])) {
                                                                                                                                    $selec = $_POST['selec'];
                                                                                                                                  } else {
                                                                                                                                    $data['result']='error';
                                                                                                                                  } 
                                                                                                                              
                                                                                                                              и
                                                                                                                                  #$output .= "Выбрана категория: " . $selec . "\n"; 
                                                                                                                              	$output .= "Выбрана категория: " . "\n" . $_POST['selec'] . "\n";
                                                                                                                              

                                                                                                                              Изначально побывал ". $selec. "\n" пока не прочитал низ темы, потом побывал через пост.
                                                                                                                              1. Александр Мальцев # 0
                                                                                                                                Добавьте для элемента select атрибут id, т.к. в javascript вы получаете его по id:
                                                                                                                                <select class="form-control" name="selec" id="selec">
                                                                                                                                
                                                                                                                                А так как вы сейчас делаете, в js необходимо элемент select получать так (т.е. по атрибуту name):
                                                                                                                                var selec = $('select[name="selec"]').val();
                                                                                                                                
                                                                                                                                1. Виктор # 0
                                                                                                                                  Уже какой раз пробую не выходит… Просто зависает форма и всё…

                                                                                                                                  Если не трудно напишите куда что вставлять
                                                                                                                                  1. Александр Мальцев # 0
                                                                                                                                    Посмотрите ошибки в консоли браузера.
                                                                                                                                    Кроме этого в статье есть Руководство по добавлению полей в форму, в которой описано что и куда добавлять. Попробуйте разобраться (не знаю как это руководство подробней описать, если только снять видео)…
                                                                                                                                  2. Kirill2511 # 0
                                                                                                                                    Спасибо, все заработало.
                                                                                                                            2. Anna # 0
                                                                                                                              спасибо от меня Вам и вашему сайту на соответствующей странице ;)
                                                                                                                              1. Александр Мальцев # 0
                                                                                                                                Приятно получать такие спасибки :)
                                                                                                                              2. Anna # 0
                                                                                                                                Александр, добрый день!
                                                                                                                                Еще раз спасибо за форму — пользуюсь. Очень всё понятно объяснено.
                                                                                                                                У меня вопрос. На сайте я сделала расширенную форму: добавила выбор из календаря, селекты, дополнительные поля и т.д. -это на странице Забронировать, а на главной оставила форму с тремя полями, телефон, email, сообщение — типа «перезвоните мне».
                                                                                                                                Чтобы письма менеджеру приходили с другой темой с этой формы, я продублировала папку feedback, изменила тему, убрала из письма ненужные поля и т.п. Теперь, когда отправляется письмо с одной формы на почту приходит сразу 2 письма — с разными темами. Почему так?
                                                                                                                                И ещё, как можно отправлять подтверждение о получении на указанный при заполнении формы email?

                                                                                                                                Спасибо!
                                                                                                                                1. Александр Мальцев # 0
                                                                                                                                  Здравствуйте.
                                                                                                                                  Проверьте, не подключаете ли вы к одной странице (*.html) 2 файла script.js, т.к. именно он отправляет и принимает данные с сервера. Либо проверьте путь к нему.
                                                                                                                                  Ещё одна ссылка содержится в файле script.js в адресе:
                                                                                                                                  url: "/feedback/verify.php",
                                                                                                                                  
                                                                                                                                  Проверьте эту строчку в разных файлах script.js, чтобы они указывали на файлы, расположенные в разных каталогах.

                                                                                                                                  Запросить подтверждения прочтения письма у пользователя можно так:
                                                                                                                                  $mail->ConfirmReadingTo = 'myemail@mail.ru';
                                                                                                                                  
                                                                                                                                  Но такие действия выполняются только в том случае, если пользователь это захочет. А также если почтовая программа настроена так, что разрешает отправку ответа.

                                                                                                                                  1. Anna # 0
                                                                                                                                    Александр, спасибо!
                                                                                                                                    Да, у меня дважды подключался script.js

                                                                                                                                    Я неправильно сформулировала вторую часть вопроса. Не подтверждение от пользователя, а копия пользователю на указанный при заполнении формы e-mail. Т.е. менеджеру приходит письмо и пользователю, который заполнял форму, отбивка на указанный e-mail: вы указали то-то и то-то, спасибо, мы получили, скоро ответим.
                                                                                                                                    1. Александр Мальцев # 0
                                                                                                                                      Копию письма (AddCC) или скрытую копию письма (AddBCC) можно отправить так:
                                                                                                                                      $mail->AddCC('mail1@domain.com');
                                                                                                                                      $mail->AddBCC('mail2@domain.com');
                                                                                                                                      
                                                                                                                                      Если необходимо с другим содержимым то так:
                                                                                                                                      itchief.ru/lessons/php/feedback-form-for-website#comment-2735
                                                                                                                                      1. Anna # 0
                                                                                                                                        Александр, я что-то торможу. Вы, похоже, немного изменили исходники формы с того момента, как я ее скачивала и настраивала под себя. Пытаюсь встроить отправку письма пользователю по указанному выше в комментарии примеру, но не получается — письмо на адрес пользователя не приходит.
                                                                                                                                        Вот мой работающий исходный код verify.php (без отправки письма-подтверждения)
                                                                                                                                        
                                                                                                                                        <?php
                                                                                                                                        //открывает сессию
                                                                                                                                        session_start();
                                                                                                                                        //получить имя, которое ввёл пользователь
                                                                                                                                        $name = $_POST["name"];
                                                                                                                                        //получить email, которое ввёл пользователь
                                                                                                                                        $email = $_POST["email"];
                                                                                                                                        $phone = $_POST["phone"];
                                                                                                                                        $message = $_POST["message"];
                                                                                                                                        //если пользователь правильно ввёл капчу
                                                                                                                                        if ($_SESSION["code1"] == $_POST["captcha"]) {
                                                                                                                                          //свой email (email, куда будут приходить сообщения)
                                                                                                                                          $emailTo = "myemail@gmail.com";
                                                                                                                                          //тема письма
                                                                                                                                          $subject = "ПЕРЕЗВОНИТЬ";
                                                                                                                                          //формируем тело письма
                                                                                                                                          //1. Полоска
                                                                                                                                          $body = "--------------------------------------\n";
                                                                                                                                          //2. Дата, когда сообщение пришло на сервер
                                                                                                                                          $body .= date("Y.m.d H:i")."\n";
                                                                                                                                          //3. Текст (заголовок)
                                                                                                                                          $body .= "Подробности заявки: \n\n";
                                                                                                                                          //4. Имя пользователя
                                                                                                                                          $body .= "Имя: ".$name."\n";
                                                                                                                                          $body .= "Телефон: ".$phone."\n";
                                                                                                                                          //5. Email пользователя
                                                                                                                                          $body .= "Email: ".$email."\n";
                                                                                                                                        
                                                                                                                                          //6. Сообщение пользователя
                                                                                                                                          $body .= "Сообщение: \n".$message."\n";
                                                                                                                                          //7. Отправляем на почту
                                                                                                                                          $success = mail($emailTo, $subject, $body, "From: no-reply@no-reply.ru \r\n");
                                                                                                                                          
                                                                                                                                          //7. Добавляем в конец файла message.txt 
                                                                                                                                          //$file = 'message.txt';
                                                                                                                                          //$success = file_put_contents($file, $body, FILE_APPEND | LOCK_EX);
                                                                                                                                          //8. Если действия были успешны, то отправляем "success"
                                                                                                                                          if ($success) {
                                                                                                                                            echo "success";
                                                                                                                                           
                                                                                                                                          }
                                                                                                                                          //иначе отправляем "invalid"
                                                                                                                                          else {
                                                                                                                                            echo "invalid";
                                                                                                                                          }
                                                                                                                                        }
                                                                                                                                        else {
                                                                                                                                          //если пользователь ввёл неправильную капчу, то отправляем "invalidcaptcha"
                                                                                                                                          echo 'invalidcaptcha';
                                                                                                                                        }
                                                                                                                                        
                                                                                                                                        
                                                                                                                                          ?>
                                                                                                                                        Вопрос: куда нужно вставлять указанный код
                                                                                                                                        $mail->ClearAllRecipients();
                                                                                                                                        $mail->clearAttachments();
                                                                                                                                        $mail->From      = 'email@mysite.ru';
                                                                                                                                        $mail->FromName  = 'Имя сайта';
                                                                                                                                        $mail->Subject   = 'Ваше сообщение отправлено';
                                                                                                                                        $mail->Body      = $name . ', ваше сообщение доставлено. На данное письмо отвечать не надо.';
                                                                                                                                        $mail->AddAddress( $email );
                                                                                                                                        $mail->Send();
                                                                                                                                        Спасибо!
                                                                                                                                        1. Александр Мальцев # 0
                                                                                                                                          Добавьте необходимые заголовки:
                                                                                                                                          $headers = 'From: no-reply@no-reply.ru' . "\r\n";
                                                                                                                                          $headers .= 'Cc: mail1@mail.ru' . "\r\n";
                                                                                                                                          $headers .= 'Bcc: mail2@mail.ru' . "\r\n";
                                                                                                                                          $success = mail($emailTo, $subject, $body, $headers);
                                                                                                                                          
                                                                                                                                          1. Anna # 0
                                                                                                                                            Спасибо!
                                                                                                                                            В общем никаких сложных (правильных и красивых) путей не стала искать. Может кому-то пригодится.
                                                                                                                                            Чтобы письмо-подтверждение о получении сообщения с сайта с произвольным содержимым уходило на почту пользователю, сделала следующее.
                                                                                                                                            добавила поля $subject1, $body1 и продублировала отправку еще одного письма
                                                                                                                                            //7. Отправляем на почту
                                                                                                                                              $success = mail($emailTo, $subject, $body, "From: no-reply@site.ru \r\n");
                                                                                                                                              $success = mail($email, $subject1, $body1, "From: no-reply@site.ru \r\n");
                                                                                                                                            где $email — почта, введенная пользователем в поле формы на сайте.
                                                                                                                                          2. Александр Мальцев # 0
                                                                                                                                            Да, многое улучшил :)
                                                                                                                                            Данный код вставить в ваш файл не получится, т.к. у вас для отправки почты используется php функция mail. А сейчас библиотека phpMailer. Если хотите использовать, то скачайте новую версию файла php и настройте его под себя.
                                                                                                                                            1. Anna # 0
                                                                                                                                              Саша, 20 сайтов по 2 формы на каждом… А если все-таки с функцией mail… Может подскажете…
                                                                                                                                  2. fancybear # 0
                                                                                                                                    Форма отличная! Использую на своем сайте, было бы неплохо если бы стояла капча recaptcha 2.0 удобная черт побери.
                                                                                                                                    1. Александр Мальцев # 0
                                                                                                                                      Спасибо. Как подключить recaptcha 2.0 можно почитать в статье Установка гугловской рекаптчи на сайт.
                                                                                                                                    2. Alex # 0
                                                                                                                                      Классаня форма, но как её добавить в joomla?
                                                                                                                                      1. Александр Мальцев # 0
                                                                                                                                        С joomla не знаком. Попробуйте сделать так. Скопировать директорию feedback со всеми файлами в корень сайта. После этого открой необходимую страницу в joomla и вставить в неё html-код формы из файла index.html. Только предварительно отключить использование визуального текстового редактора. Кроме этого ещё необходимо подключить Bootstrap и файл script.js к странице.
                                                                                                                                      2. Роман # 0
                                                                                                                                        Добрый день. Если в Firefox открывать форму по ссылке на странице, имеющей кодировку Windows-1251, то форма открывается в кодировке Windows-1251, а не в UTF-8. В итоге кракозябры…
                                                                                                                                        1. Александр Мальцев # 0
                                                                                                                                          Значит такой заголовок отдаёт Ваш сервер (Content-Type: text/html; charset=windows-1251).
                                                                                                                                          Можно открыть файл .htaccess и добавить в него следующую строчку, чтобы Ваш сервер всегда отдавал UTF-8 (или указать в настройках сервера):
                                                                                                                                          AddDefaultCharset UTF-8
                                                                                                                                          
                                                                                                                                          После этого необходимо и все другие страницы перевести в UTF-8.
                                                                                                                                          Хотя не знаю как Вы вообще используете windows-1251. Сейчас сайты открывают на многих устройствах, у которых операционная система не Windows.
                                                                                                                                          1. Роман # 0
                                                                                                                                            Вы, безусловно, правы. Буду переводить на UTF-8. Есть еще один момент. Если ввести в поле сообщение меньшее количество символов, чем требуется, то форма выдает ошибку «Произошли ошибки при отправке формы» вместо «Поле сообщение содержит недопустимое количество символов»
                                                                                                                                            1. Александр Мальцев # 0
                                                                                                                                              Обработка ошибок на PHP нужны только для тех пользователей, кто специально их обошёл в браузере. Т.е. можно ответить что данные просто так не уйдут. Т.к. первоначально обработка ошибок выполняется на стороне браузера.
                                                                                                                                              Если это необходимо, то Вы можете сделать это так:
                                                                                                                                              // если сервер вернул ответ error, то делаем следующее...
                                                                                                                                              var errorText = 'Произошли ошибки при отправке формы на сервер.'
                                                                                                                                              if ($data.name) {
                                                                                                                                                errorText = errorText + $data.name;
                                                                                                                                                var nameInput = $("#name");
                                                                                                                                                // находим предка, имеющего класс .form-group (для установления success/error)
                                                                                                                                                formGroupName = nameInput.parents('.form-group');
                                                                                                                                                // находим glyphicon (иконка успеха или ошибки)
                                                                                                                                                glyphiconName = formGroupName.find('.form-control-feedback');
                                                                                                                                                // добавляем к formGroup класс .has-error и удаляем .has-success
                                                                                                                                                formGroupName.addClass('has-error').removeClass('has-success');
                                                                                                                                                // добавляем к glyphicon класс glyphicon-remove и удаляем glyphicon-ok
                                                                                                                                                glyphiconName.addClass('glyphicon-remove').removeClass('glyphicon-ok');
                                                                                                                                              }
                                                                                                                                              if ($data.email) {
                                                                                                                                                errorText = errorText + $data.email;
                                                                                                                                                var emailInput = $("#email");
                                                                                                                                                // находим предка, имеющего класс .form-group (для установления success/error)
                                                                                                                                                formGroupEmail = emailInput.parents('.form-group');
                                                                                                                                                // находим glyphicon (иконка успеха или ошибки)
                                                                                                                                                glyphiconEmail = formGroupEmail.find('.form-control-feedback');
                                                                                                                                                // добавляем к formGroup класс .has-error и удаляем .has-success
                                                                                                                                                formGroupEmail.addClass('has-error').removeClass('has-success');
                                                                                                                                                // добавляем к glyphicon класс glyphicon-remove и удаляем glyphicon-ok
                                                                                                                                                glyphiconEmail.addClass('glyphicon-remove').removeClass('glyphicon-ok');
                                                                                                                                              }
                                                                                                                                              if ($data.message) {
                                                                                                                                                errorText = errorText + $data.message;
                                                                                                                                                var messageInput = $("#message");
                                                                                                                                                // находим предка, имеющего класс .form-group (для установления success/error)
                                                                                                                                                formGroupMessage = messageInput.parents('.form-group');
                                                                                                                                                // находим glyphicon (иконка успеха или ошибки)
                                                                                                                                                glyphiconMessage = formGroupMessage.find('.form-control-feedback');
                                                                                                                                                // добавляем к formGroup класс .has-error и удаляем .has-success
                                                                                                                                                formGroupMessage.addClass('has-error').removeClass('has-success');
                                                                                                                                                // добавляем к glyphicon класс glyphicon-remove и удаляем glyphicon-ok
                                                                                                                                                glyphiconMessage.addClass('glyphicon-remove').removeClass('glyphicon-ok');
                                                                                                                                              }        
                                                                                                                                              $('#error').html(errorText);
                                                                                                                                              // выводим новый код капчи
                                                                                                                                              $('#img-captcha').attr('src', '/feedback/captcha.php?id=' + Math.random() + '');
                                                                                                                                              // устанавливаем полю, с помощью которого осуществляем ввод капчи пустое значение
                                                                                                                                              $("#text-captcha").val('');
                                                                                                                                              if ($data.files) {
                                                                                                                                                $('#error').html($('#error').html()+$data.files);
                                                                                                                                              }
                                                                                                                                              
                                                                                                                                              Т.е. заменить следующий код в файле script.js на вышеприведённый:
                                                                                                                                              // Если сервер вернул ответ error, то делаем следующее...
                                                                                                                                              $('#error').text('Произошли ошибки при отправке формы на сервер.');
                                                                                                                                              if ($data.files) {
                                                                                                                                                $('#error').html($('#error').text()+$data.files);
                                                                                                                                              }
                                                                                                                                              
                                                                                                                                        2. Андрей # 0
                                                                                                                                          Здравствуйте!!! Очень хорошая форма и вы круто все объясняете, долго я это искал!!!
                                                                                                                                          Но у меня выдает такую ошибку:(прикрепил скрин)http://itchief.ru/assets/uploadify/0/6/7/067b41f041564dd38654d1adc3d22739.png
                                                                                                                                          P.S. Ошибка из строки
                                                                                                                                          $('#error').text('Произошла ошибка ' + request.responseText + ' при отправке данных.');
                                                                                                                                          1. Александр Мальцев # 0
                                                                                                                                            Здравствуйте. Проверьте путь в HTML документе до файла verify.php. Т.к. он жалуется на его отсутствие.
                                                                                                                                            1. Андрей # 0
                                                                                                                                              Вот мои пути в файле verify.php
                                                                                                                                              if (file_put_contents(dirname(__FILE__).'/message.txt', $output, FILE_APPEND | LOCK_EX)) {
                                                                                                                                                    $data['result']='success';
                                                                                                                                              require_once dirname(__FILE__) . '/phpmailer/PHPMailerAutoload.php';
                                                                                                                                              пути в script.js
                                                                                                                                              url: "https://doctor-federation.com/include/verify.php",
                                                                                                                                              вот в этом пути пробовал многое… ничего не подходит…
                                                                                                                                              1. Андрей # 0
                                                                                                                                                Еще тема такая, что у меня два адреса в одной директории данных, когда пишу путь на.рф, то пишет вышеуказанную ошибку, когда пишу путь на .com, то пишет просто «произошла ошибка при отправке данных», но по сути строка ошибки та же самая…
                                                                                                                                                1. Александр Мальцев # 0
                                                                                                                                                  Попробуйте не указывать протокол и доменное имя.
                                                                                                                                                  Начинайте указывать путь от корня сайта (/) или используйте относительный путь.
                                                                                                                                                2. Андрей # 0
                                                                                                                                                  Нужно подключить файл?? так?
                                                                                                                                                  include("include/verify.php");
                                                                                                                                                  Так ничего не меняется, а если путь изменять, то это же в файле script.js… или я что то не понимаю.
                                                                                                                                                  У меня в HTML документе php вставки, которые находятся в папке include, там и есть необходимая форма и туда я и вложил документы verify.php, script.js и папку phpmailer.
                                                                                                                                                  1. Александр Мальцев # 0
                                                                                                                                                    Путь к файлу verify.php из javascript указывается так:
                                                                                                                                                    //URL-адрес запроса 
                                                                                                                                                    url: "/feedback/verify.php",
                                                                                                                                                    
                                                                                                                                                    Тут всё зависит от того, где расположен файл относительно местоположения скрипта javascript. Можно использовать как относительные, так и абсолютные пути.
                                                                                                                                                    Например, если файл verify.php расположен в каталоге include, который находится в корне сайта. То можно указать так:
                                                                                                                                                    //URL-адрес запроса 
                                                                                                                                                    url: "/include/verify.php",
                                                                                                                                                    
                                                                                                                                              2. Слава # 0
                                                                                                                                                Александр, ещё момент, есть необходимость использовать несколько форм на странице, как избежать конфликт между ними? Спасибо.
                                                                                                                                                1. Александр Мальцев # 0
                                                                                                                                                  Самый простой способ — это всё продублировать… Т.е. и файлы и содержимое в них.
                                                                                                                                                  Например, сделать копию captcha.php — captcha2.php. После этого открыть его и в нём изменить code на code2:
                                                                                                                                                  $_SESSION["code2"] = $captchastring;
                                                                                                                                                  
                                                                                                                                                  После этого сделать копию verify.php — verify2.php.
                                                                                                                                                  Следующий этап продублировать содержимое файла script.js (следующие куски кода).
                                                                                                                                                  $('#countFiles2').text(countFiles);
                                                                                                                                                  // при изменения значения элемента "Выбрать файл"
                                                                                                                                                  $(document).on('change','input[name="images2[]"]',function(e){
                                                                                                                                                    // если выбран файл, то добавить ещё элемент "Выбрать файл"
                                                                                                                                                    if ((e.target.files.length>0)&&($(this).next('p').next('input[name="images2[]"]').length==0) && ($('input[name="images2[]"]').length<countFiles)) {
                                                                                                                                                      $(this).next('p').after('<input type="file" name="images2[]"><p style="margin-top: 3px; margin-bottom: 3px; color: #ff0000;"></p>');
                                                                                                                                                    }
                                                                                                                                                    ...
                                                                                                                                                  });
                                                                                                                                                  // при нажатии на кнопку "Обновить", выведем новый код капчи
                                                                                                                                                  $('#reload-captcha2').click(function () {
                                                                                                                                                    $('#img-captcha2').attr('src', '/feedback/captcha2.php?id=' + Math.random() + '');
                                                                                                                                                  });
                                                                                                                                                  // при отправке формы messageForm на сервер (id="messageForm")
                                                                                                                                                  $('#messageForm2').submit(function (event) {
                                                                                                                                                    ...
                                                                                                                                                  });
                                                                                                                                                  
                                                                                                                                                  И наконец, изменить файл index.html и некоторые поля в нём.
                                                                                                                                                  <form id="messageForm2" enctype="multipart/form-data">
                                                                                                                                                    ...
                                                                                                                                                    <input type="file" name="images2[]">
                                                                                                                                                    ...
                                                                                                                                                    <img id="img-captcha" src="/feedback/captcha2.php">
                                                                                                                                                    ...
                                                                                                                                                  </form>
                                                                                                                                                  
                                                                                                                                                2. Иван # 0
                                                                                                                                                  Большое спасибо за такую крутую форму! А можно добавить что-то типа прелоадера, когда отправляется сообщение? Потому что сейчас пользователю не очень понятно, что происходит после нажатие кнопки Отправить…
                                                                                                                                                  1. Александр Мальцев # 0
                                                                                                                                                    Данная задача уже была решена в этом комментарии.
                                                                                                                                                    Само решение следующее: необходимо скачать вращающуюся иконку, добавить её к форме и написать script.
                                                                                                                                                    JavaScript код предствленный в комментарии можно улучшить, добавив в него установку состояния disabled для кнопки «Отправить».
                                                                                                                                                    beforeSend: function () {
                                                                                                                                                      $('#loading').removeClass('hidden');
                                                                                                                                                      $('[type="submit"]').prop('disabled',true);
                                                                                                                                                    },
                                                                                                                                                    complete: function () {
                                                                                                                                                      $('#loading').addClass('hidden');
                                                                                                                                                      $('[type="submit"]').prop('disabled',false);
                                                                                                                                                    },
                                                                                                                                                    
                                                                                                                                                    Ссылка для загрузки: форма с вращающейся иконкой.
                                                                                                                                                  2. Кирилл # 0
                                                                                                                                                    Спасибо!

                                                                                                                                                    Подскажите ещё пожалуйста, можно ли как-то автоматически очищать папку files после отправки сообщения? Не хочется копить там файлы…
                                                                                                                                                    1. Александр Мальцев # 0
                                                                                                                                                      После отправки сообщения добавить код для удаления файлов:
                                                                                                                                                      // отправляем письмо
                                                                                                                                                      if ($mail->Send()) {
                                                                                                                                                        $data['result']='success';
                                                                                                                                                      } else {
                                                                                                                                                        $data['result']='error';
                                                                                                                                                      }
                                                                                                                                                      
                                                                                                                                                      // добавляем этот код:
                                                                                                                                                      if (isset($files)) {
                                                                                                                                                        foreach ($files as $value) {
                                                                                                                                                          unlink($value);
                                                                                                                                                        }
                                                                                                                                                      }
                                                                                                                                                      
                                                                                                                                                    2. Кирилл # 0
                                                                                                                                                      Огромное спасибо за форму!
                                                                                                                                                      Подскажите пожалуйста, я хочу добавить выбор, чтобы сообщение отправлялось на разные ящики исходя из ситуации пользователя (например выпадающий список, что-то типа: Отдел 1, Отдел 2, Отдел 3 — и чтобы при выборе нужного раздела письмо уходило в соответствии с адресом этого отдела)… как реализовать?
                                                                                                                                                      1. Кирилл # 0
                                                                                                                                                        В html файл с формой добавил такой код:

                                                                                                                                                        <div class="col-sm-6">
                                                                                                                                                        <!-- Выбор ящика -->
                                                                                                                                                        <div class="form-group has-feedback">
                                                                                                                                                        <label for="box" class="control-label">Выберите цель обращения:</label>
                                                                                                                                                        <select name="box" id="box" style="display: block; width: 100%; height: 25px;">
                                                                                                                                                        <option selected value="1">Пункт 1</option>
                                                                                                                                                        <option value="2">Пункт 2</option>
                                                                                                                                                        <option value="3">Пункт 3</option>
                                                                                                                                                        <option value="4">Пункт 4</option>
                                                                                                                                                        </select>
                                                                                                                                                        </div>
                                                                                                                                                        </div>
                                                                                                                                                        
                                                                                                                                                        В файл verify.php добавил это:

                                                                                                                                                        Вверху:
                                                                                                                                                            //получить мыло, которое выбрал пользователь
                                                                                                                                                            if (isset($_POST['box'])) {
                                                                                                                                                              $box = $_POST['box'];
                                                                                                                                                            } else {
                                                                                                                                                              $data['result']='error';
                                                                                                                                                            } 
                                                                                                                                                        
                                                                                                                                                        При отправке:
                                                                                                                                                        //формируем тело письма
                                                                                                                                                        $output = "Дата: " . date("d-m-Y H:i") . "\n";
                                                                                                                                                        $output .= "Имя пользователя: " . $name . "\n";
                                                                                                                                                        $output .= "Адрес email: " . $email . "\n";
                                                                                                                                                        $output .= "Сообщение: " . "\n" . $message . "\n";
                                                                                                                                                        $output .= "Выбран пункт: " . $box . "\n";
                                                                                                                                                        
                                                                                                                                                        Но при отправке выдаёт ошибку, то есть не получает $_POST['box'] — не пойму, почему… Что делаю не так?
                                                                                                                                                        1. Александр Мальцев # 0
                                                                                                                                                          Т.к. передача осуществляется с помощью AJAX, то кроме как добавить поле в форму ещё необходимо передать его значение в объект FormData (файл script.js).
                                                                                                                                                          Т.е. найти строчки такого содержимого:
                                                                                                                                                          formData.append('message', message);
                                                                                                                                                          
                                                                                                                                                          и вставить сразу же после них своё поле. Т.е. чтобы оно тоже добавилось в набор данных, которые отправятся на сервер.
                                                                                                                                                          formData.append('box', $("#box").val() );
                                                                                                                                                          
                                                                                                                                                          Первый параметр — это имя, по которому необходимо будет обращаться к данным на сервере. Второй параметр — это получения значения поля box.

                                                                                                                                                          А куда отправить определяется строчкой:
                                                                                                                                                          $mail->AddAddress( 'myemail@mail.ru' );
                                                                                                                                                          
                                                                                                                                                          Т.е. Вам необходимо туда доставить содержимое переменной $box, если она будет содержать email или если число (как это сделано у Вас, то организовать выбор email по case):
                                                                                                                                                          $mail->AddAddress( $box );
                                                                                                                                                          
                                                                                                                                                      2. Слава # 0
                                                                                                                                                        отлично, спасибо, Александр.
                                                                                                                                                        Кстати, а как отключить обязательное заполнение, в каком либо из полей?
                                                                                                                                                        И Александр, как вам можно благодарность перечислить?
                                                                                                                                                        1. Александр Мальцев # 0
                                                                                                                                                          Два действия:
                                                                                                                                                          1. На стороне клиента (в браузере). Необходимо найти строчку с соответствующим полем (например, name) и убрать атрибуты, предъявляющие требования к полю (в данном случае это required, minlength и maxlength). Т.е. после удаление останется следующее:
                                                                                                                                                          <div class="form-group has-feedback">
                                                                                                                                                            <label for="name" class="control-label">Введите ваше имя:</label>
                                                                                                                                                            <input type="text" id="name" name="name" class="form-control" value="" placeholder="Например, Иван Иванович" >
                                                                                                                                                            <span class="glyphicon form-control-feedback"></span>
                                                                                                                                                          </div>
                                                                                                                                                          
                                                                                                                                                          2. Убрать проверку в файле verify.php.
                                                                                                                                                          2.1. Т.е. удалить код (теперь проверки поля (в данном случае name) на сервере не будет):
                                                                                                                                                          //получить имя, которое ввёл пользователь
                                                                                                                                                          if (isset($_POST['name'])) {
                                                                                                                                                            $name = $_POST['name'];
                                                                                                                                                            if (!validStringLength($name,2,30)) {
                                                                                                                                                              $data['name']='Поля имя содержит недопустимое количество символов.';   
                                                                                                                                                              $data['result']='error';     
                                                                                                                                                            }
                                                                                                                                                          } else {
                                                                                                                                                            $data['result']='error';
                                                                                                                                                          } 
                                                                                                                                                          
                                                                                                                                                          2.2. А там где формируем тело письма добавить следующий код:
                                                                                                                                                          if (isset($_POST['name'])) {
                                                                                                                                                            $output .= "Имя: " . $_POST['name'] . "\n";
                                                                                                                                                          }
                                                                                                                                                          
                                                                                                                                                          Он будет проверять, передали ли мы поле name с формы. Если да, то добавит его содержимое к телу письма.

                                                                                                                                                          Для перевода благодарности можно воспользоваться страницей: itchief.ru/help-site
                                                                                                                                                          1. Слава # 0
                                                                                                                                                            Супер, спасибо, Александр!
                                                                                                                                                        2. Слава # 0
                                                                                                                                                          Очень крутая форма! Спасибо!

                                                                                                                                                          Александр, по добавлению и удалению полей, инфы, да, очень не хватает!
                                                                                                                                                          Нужны только имя, телефон и файлы, и вот что-то без ошибки не получается )
                                                                                                                                                          1. Александр Мальцев # 0
                                                                                                                                                            Мини инструкцию к концу статьи добавил.
                                                                                                                                                            Сборка с именем и телефоном: yadi.sk/d/IiaNuxolujPKa
                                                                                                                                                          2. Владислав # 0
                                                                                                                                                            Не получается запустить smtp (php долгий очень)
                                                                                                                                                            $mail = new PHPMailer;
                                                                                                                                                                $mail->SMTPAuth  = true;
                                                                                                                                                                $mail->Username  = '123@mail.ru';
                                                                                                                                                                $mail->Password  =  '123123';
                                                                                                                                                            	$mail->Host = 'ssl://smtp.mail.ru:465';
                                                                                                                                                            	$mail->Port = '465';
                                                                                                                                                            	$mail->Mailer = 'smtp';
                                                                                                                                                            	$mail->CharSet = 'utf-8';
                                                                                                                                                                $mail->From      = '1231@3123.ru';
                                                                                                                                                                $mail->FromName  = '123123.ru - Мятый элемент';
                                                                                                                                                                $mail->Subject   = 'Сообщение с формы обратной связи';
                                                                                                                                                                $mail->Body      = $output;
                                                                                                                                                                $mail->AddAddress( '123@mail.ru' );
                                                                                                                                                            prntscr.com/cd2xja
                                                                                                                                                            1. Александр Мальцев # 0
                                                                                                                                                              Не совсем понял ваши настройки (123@mail.ru). Чтобы настроить почту домена через стороний сервер необходимо подтвердить на mail.ru право на ваш домен, настроить на хостинги mx-записи, txt-записи. Либо вообще передать делигирование домена mail.ru.
                                                                                                                                                              1. Владислав # 0
                                                                                                                                                                Я использую обычную почту от mail.ru (сайт, логин и пароль заменил на 123).
                                                                                                                                                                Надо чтобы письма отходили через SMTP
                                                                                                                                                                1. Александр Мальцев # 0
                                                                                                                                                                  Из скриншота видно, что сервер отклонил соединение.
                                                                                                                                                                  Попробуйте добавить в начало:
                                                                                                                                                                  $mail->IsSMTP();// отсылать письмо используя SMTP 
                                                                                                                                                                  
                                                                                                                                                                  Кроме этого проверьте значение $mail->Host, действительно ли оно должно быть такое?
                                                                                                                                                                  Кроме этого попробуйте изменить $mail->From таким образом, чтобы оно совпадало с адресом отправления.
                                                                                                                                                                  Если вы хотите использовать SSL, то попробуйте добавить:
                                                                                                                                                                  $mail->SMTPSecure = 'ssl';
                                                                                                                                                                  
                                                                                                                                                            2. Владислав # 0
                                                                                                                                                              prntscr.com/cc8x36
                                                                                                                                                              Не отправляет, хостинг 1GB
                                                                                                                                                              1. Владислав # 0
                                                                                                                                                                Оказывается проверка была на количество символов у сообщения(

                                                                                                                                                                Теперь новая ошибка, кодировка:
                                                                                                                                                                prntscr.com/ccexxx
                                                                                                                                                                1. Александр Мальцев # 0
                                                                                                                                                                  Добавь в файл .htaccess строчку:
                                                                                                                                                                  AddCharset utf-8 .php .html .js
                                                                                                                                                                  
                                                                                                                                                                  1. Владислав # 0
                                                                                                                                                                    Нашел:
                                                                                                                                                                    $mail->CharSet = 'utf-8';
                                                                                                                                                              2. Игорь # 0
                                                                                                                                                                Отличная форма! У меня вопрос — а можно ли сделать чтобы формировался автоответ отправителю. Например — Ваше сообщение доставлено, просьба на данное письмо не отвечать и т.д.
                                                                                                                                                                1. Александр Мальцев # 0
                                                                                                                                                                  После отправки письма, можете также отправить сообщение отправителю.
                                                                                                                                                                  Для этого в файле verify.php после строчки:
                                                                                                                                                                  // отправляем письмо
                                                                                                                                                                  if ($mail->Send()) {
                                                                                                                                                                    $data['result']='success';
                                                                                                                                                                  
                                                                                                                                                                  вставьте следующие:
                                                                                                                                                                  $mail->ClearAllRecipients();
                                                                                                                                                                  $mail->clearAttachments();
                                                                                                                                                                  $mail->From      = 'email@mysite.ru';
                                                                                                                                                                  $mail->FromName  = 'Имя сайта';
                                                                                                                                                                  $mail->Subject   = 'Ваше сообщение отправлено';
                                                                                                                                                                  $mail->Body      = $name . ', ваше сообщение доставлено. На данное письмо отвечать не надо.';
                                                                                                                                                                  $mail->AddAddress( $email );
                                                                                                                                                                  $mail->Send();
                                                                                                                                                                  
                                                                                                                                                                  1. Игорь # 0
                                                                                                                                                                    Супер, Супер!!! В принципе, афигеный конструктор, я включу автоответ. Было очень мало инфы про включение дополнительных полей, разобрался — все очень легко, но просьба, хелп писать в коде и сноску где еще подправить.
                                                                                                                                                                    Выше был написан пост про крякозябры, я его не увидел и изменил в файле phpmailer\class.phpmailer.php 48 строку с public $CharSet = 'iso-8859-1'; на
                                                                                                                                                                    public $CharSet = 'UTF-8'; после этого все письма пошли в кириллице. Это неправильно? Просто у меня фрондэнд и бакэнд стоит nginx и .htaccess он не воспринимает.
                                                                                                                                                                    Не буду скрывать — буду менять с www.vrnzags.ru/feedback/mail.php
                                                                                                                                                                    на www.vrnzags.ru/feed/
                                                                                                                                                                    www.vrnzags.ru/feed/post.php
                                                                                                                                                                2. Александр # 0
                                                                                                                                                                  Спасибо, попробую.
                                                                                                                                                                  1. Александр # 0
                                                                                                                                                                    Александр, добрый день.
                                                                                                                                                                    Отличный урок. Замечательная реализация.
                                                                                                                                                                    Только у меня не получается встроить форму в уже готовую страницу. Точнее форма встраивается. Но капча не генерирует код. Фон капчи грузится. А кодов нет.
                                                                                                                                                                    Я все файлы из вашего примера разложил соответствующим папкам.

                                                                                                                                                                    /htdoc
                                                                                                                                                                    css
                                                                                                                                                                    files
                                                                                                                                                                    fonts
                                                                                                                                                                    img
                                                                                                                                                                    js (script.js)
                                                                                                                                                                    php (captcha.php,verify.php)
                                                                                                                                                                    phpmailer

                                                                                                                                                                    в форме изменил путь до капчи
                                                                                                                                                                    <img id="img-captcha" src="php/captcha.php"><\code>
                                                                                                                                                                    
                                                                                                                                                                    Затем в файле script.js изменил 
                                                                                                                                                                    
                                                                                                                                                                    <code>$('#reload-captcha').click(function () {
                                                                                                                                                                        $('#img-captcha').attr('src', '../php/captcha.php?id=' + Math.random() + '');
                                                                                                                                                                      });
                                                                                                                                                                    
                                                                                                                                                                    и еще

                                                                                                                                                                    //URL-адрес запроса 
                                                                                                                                                                            url: "../php/verify.php",
                                                                                                                                                                    
                                                                                                                                                                    и вот тут

                                                                                                                                                                    $('#img-captcha').attr('src', '../php/captcha.php?id=' + Math.random() + '');

                                                                                                                                                                    в capcha.php изменил

                                                                                                                                                                    //создает новое изображение из файла background.png 
                                                                                                                                                                    $image = imagecreatefrompng(dirname(__FILE__).'../../img/background.png');
                                                                                                                                                                    ...
                                                                                                                                                                    
                                                                                                                                                                    //присваивает переменной font название шрифта
                                                                                                                                                                    $font = dirname(__FILE__).'../../fonts/oswald.ttf';
                                                                                                                                                                    

                                                                                                                                                                    файл verify.php

                                                                                                                                                                    // включить файл PHPMailerAutoload.php
                                                                                                                                                                        require_once dirname(__FILE__) . '../../phpmailer/PHPMailerAutoload.php';
                                                                                                                                                                    


                                                                                                                                                                    Скажите, что не так и в каких местах мне нужно изменить пути до файлов и как правильно написать эти пути?

                                                                                                                                                                    Спасибо.
                                                                                                                                                                    1. Александр Мальцев # 0
                                                                                                                                                                      В скриптах php нельзя просто так использовать запись:
                                                                                                                                                                      '../../'
                                                                                                                                                                      
                                                                                                                                                                      Это просто добавит эту строку в путь.

                                                                                                                                                                      Здесь необходимо использовать функцию realpath:
                                                                                                                                                                      $font = realpath(dirname(__FILE__) . '/..').'/fonts/background.png'
                                                                                                                                                                      
                                                                                                                                                                      Или как второй вариант использовать абсолютный путь:
                                                                                                                                                                      $root = $_SERVER['DOCUMENT_ROOT'];
                                                                                                                                                                      $font = $root.'/fonts/background.png';
                                                                                                                                                                      
                                                                                                                                                                    2. Anton # 0
                                                                                                                                                                      как правильно удалить код «ведите сообщения»?
                                                                                                                                                                      1. Александр Мальцев # 0
                                                                                                                                                                        Необходимо удалить код из html, js и php.
                                                                                                                                                                        Наверно к статье необходимо добавить более подробную инструкцию по добавлению и удалению полей к форме.
                                                                                                                                                                        feedback form без поля message
                                                                                                                                                                      2. obddevice # 0
                                                                                                                                                                        Еще добавил в .htaccess правило «Options All -Indexes» и перенес message.txt в папку files, ведь получается что любой сможет найти этот и все загруженные файлы и посмотреть содержимое что совсем не безопасно.
                                                                                                                                                                        Если форма работает самостоятельно, не внутри какой то CMS со своей политикой безопасности, это очень важно.
                                                                                                                                                                        1. Obddevice # 0
                                                                                                                                                                          Добрый день, отличный пример, получилось сделать хорошую форму с нужными полями, сделал даже изменение темы письма с учетом данных полученных из формы и отправку копии письма пользователю. Такая вот система приема заявок уже получилась.

                                                                                                                                                                          Единственное что не смог сделать, настроить загрузку файлов отличных от изображений (в моем случае есть потребность получать zip/rar/7z архивы).

                                                                                                                                                                          Еще очень хотелось бы подключить recaptcha.

                                                                                                                                                                          Спасибо!
                                                                                                                                                                          1. Александр Мальцев # 0
                                                                                                                                                                            1. Anton # 0
                                                                                                                                                                              Приветствую!, а как если не секрет сделал отправку копии письма пользователю?
                                                                                                                                                                              1. obddevice # 0
                                                                                                                                                                                Александр, спасибо, заработало.
                                                                                                                                                                                Все архивы правда сохраняются на сервер как «img_579616d69175c6.18729815.rar» но это уже не проблема =) исправим.

                                                                                                                                                                                Anton, после:
                                                                                                                                                                                $mail->AddAddress('ваш@ящик');
                                                                                                                                                                                добавил:
                                                                                                                                                                                $mail->AddCC($email);
                                                                                                                                                                                Так же можно почитать про класс PHP Mailer и добавлять получателей через запятую или добавить скрытую копию, настроить поле Replay to и прочее… это довольно просто.

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

                                                                                                                                                                                $mail->Subject   = "Заявка от  " . $name;
                                                                                                                                                                                чтобы в почте был порядок.

                                                                                                                                                                                И еще куча вариантов.
                                                                                                                                                                                1. Александр Мальцев # 0
                                                                                                                                                                                  Такие имена генерируются специально, чтобы обеспечить их уникальность с помощью следующих строк:
                                                                                                                                                                                  // уникальное имя файла
                                                                                                                                                                                  $newFileName = uniqid('img_', true).'.'.$extFile;
                                                                                                                                                                                  // полное имя файла
                                                                                                                                                                                  $newFullFileName = $pathToFile.$newFileName;
                                                                                                                                                                                  
                                                                                                                                                                                  Если это не сделать, то надо каким-то другим способом обеспечивать уникальность имени. В противном случае существует вероятность того, что пользователи смогут загрузить файлы с одинаковыми именами.

                                                                                                                                                                                  Если необходимо оставить исходное имя (имя, которое имел файл на компьютере пользователя), то можно сделать так:
                                                                                                                                                                                  if (!move_uploaded_file($tmpFile, $nameFile)) {
                                                                                                                                                                                  
                                                                                                                                                                              2. Александр Мальцев # 0
                                                                                                                                                                                Немного изменил форму, в именно убрал проверку по mime типам. Т.к. многие браузеры mime тип файла с расширением 7z не определяют.
                                                                                                                                                                                Сборку доступна по следующему URL:
                                                                                                                                                                                yadi.sk/d/23HW2CRgtc5H5
                                                                                                                                                                                Теперь проверка осуществляется по расширению файлов.
                                                                                                                                                                                В файле script.js:
                                                                                                                                                                                var typeFile = [
                                                                                                                                                                                  'jpg',
                                                                                                                                                                                  'jpeg',
                                                                                                                                                                                  'gif',
                                                                                                                                                                                  'png',
                                                                                                                                                                                  'rar',
                                                                                                                                                                                  '7z',
                                                                                                                                                                                  'zip'
                                                                                                                                                                                ];
                                                                                                                                                                                
                                                                                                                                                                                В файле verify.php:
                                                                                                                                                                                // разрешённые типы файлов
                                                                                                                                                                                $allowedExtension = array("jpg", "jpeg", "gif", "png", "rar", "7z", "zip");
                                                                                                                                                                                
                                                                                                                                                                                С recaptcha сделаю, но немного попозже.
                                                                                                                                                                              3. Anton # 0
                                                                                                                                                                                Спасибо, пробую, еще проблема в том что письма приходят таком виде
                                                                                                                                                                                Дата: 20-07-2016 15:35
                                                                                                                                                                                Имя пользователя: Anton
                                                                                                                                                                                Адрес email: 111111111@gmail.com
                                                                                                                                                                                Сообщение:
                                                                                                                                                                                11111111111111111111111111111111111111111111111111111
                                                                                                                                                                                1. Александр Мальцев # 0
                                                                                                                                                                                  В файле verify.php после строчки:
                                                                                                                                                                                  $mail = new PHPMailer;
                                                                                                                                                                                  
                                                                                                                                                                                  добавь эту:
                                                                                                                                                                                  $mail->CharSet = 'UTF-8';
                                                                                                                                                                                  
                                                                                                                                                                                  1. Anton # 0
                                                                                                                                                                                    Спасибо, да помогло:)
                                                                                                                                                                                  2. Anton # 0
                                                                                                                                                                                    в .htaccess строчка
                                                                                                                                                                                    AddDefaultCharset UTF-8 есть
                                                                                                                                                                                    1. Александр Мальцев # 0
                                                                                                                                                                                      Эта строчка на кодировку письма ни как не влияет.
                                                                                                                                                                                  3. Anton # 0
                                                                                                                                                                                    Добрый день!, большое спасибо за отличную форму!, пытаюсь встроить ее на страницу она ломает глобальные стили. как можно понизить приоритет внутреннего (Внедренного стиля) css чтоб подключаемый стиль не ломал страницу?, сапасибо
                                                                                                                                                                                    1. Александр Мальцев # 0
                                                                                                                                                                                      Здравствуйте. Спасибо за отзыв.
                                                                                                                                                                                      Попробуйте css файл в форме заменить на этот.
                                                                                                                                                                                      yadi.sk/d/4uc58Il9tVVKS
                                                                                                                                                                                      Там оставлены только необходимые стили.

                                                                                                                                                                                      Кроме этого, попробуйте свой файл стилей подключить после bootstrap.min.css:
                                                                                                                                                                                      <link rel="stylesheet" href="/feedback/css/bootstrap.min.css">
                                                                                                                                                                                      <link rel="stylesheet" href="my.css">
                                                                                                                                                                                      
                                                                                                                                                                                      1. Anton # 0
                                                                                                                                                                                        не помогло(
                                                                                                                                                                                        1. Александр Мальцев # 0
                                                                                                                                                                                          Вот несжатые стили:
                                                                                                                                                                                          yadi.sk/d/l0BdrCKztVs3k

                                                                                                                                                                                          Попробуйте разобраться, что переопределяет Ваши стили.
                                                                                                                                                                                          Ну или как вариант, создайте свои стили для формы.
                                                                                                                                                                                          Можно использовать теже классы что и в этом примере, но с другим оформлением, которое будут вписываться в Ваш дизайн.
                                                                                                                                                                                          1. Anton # 0
                                                                                                                                                                                            можете помочь со встраиванием за вознаграждение, использую Конструктор сайта — Parallels Web Presence Builder, он не дает поступа к своим файлам
                                                                                                                                                                                            1. Александр Мальцев # 0
                                                                                                                                                                                              Большинство конструкторов не имеют прямого доступа к файлам, создание сайтов в них осуществляется только через готовые блоки. Если Вы не ограничены только этим конструктором, то можете скопировать эту форму в директорию на сайте (например, используя FTP). А в меню сайта указать ссылку на неё. А если доступа к файловой системе нет, то тут уже наверно ничем не поможешь…

                                                                                                                                                                                              Лучше потратить время и создать на чём нибудь другом. Иначе потом не сможете перенести свой проект и будете всё время привязаны к этому конструктору.
                                                                                                                                                                                              1. Anton # 0
                                                                                                                                                                                                доступа к файловой системе нет, я разместил форму на другом сайте (http://titul-usinsk.ru/feedback/) а на нужном встроил ее .html блоком прописав ссылки, сначала не заработала и вылетала ошибка пока в /feedback/script.js" не прописал путь до «titul-usinsk.ru/feedback/verify.php, сейчас отправка работает но… письмо уходит а форма возвращает „Произошла ошибка при отправке данных.“, нужно еще какие то пути прописать?, извените что так много у меня вопросов тут, еще раз спасибо что помогаете
                                                                                                                                                                                                1. Александр Мальцев # 0
                                                                                                                                                                                                  Единственно, что необходимо изменить это путь в файле script.js:
                                                                                                                                                                                                  url: "http://mysite.ru/feedback/verify.php"
                                                                                                                                                                                                  
                                                                                                                                                                                                  Скорее всего у Вас не разрешены кроссдоменные запросы.
                                                                                                                                                                                                  Чтобы это сделать, откройте файл .htaccess и добавьте в него следующую строчку:
                                                                                                                                                                                                  Header set Access-Control-Allow-Origin "*"
                                                                                                                                                                                                  
                                                                                                                                                                                                  1. Anton # 0
                                                                                                                                                                                                    добавил, заработало, урааа, спасибо вам за отличный блог и помощь, теперь я ваш постоялец ))))
                                                                                                                                                                                    2. 404 # 0
                                                                                                                                                                                      Здравствуйте. Большое спасибо за удобную форму.
                                                                                                                                                                                      Возникла необходимость выпилить из формы каптчу, как это правильно сделать?
                                                                                                                                                                                      1. Александр Мальцев # 0
                                                                                                                                                                                        Здравствуйте. Ссылка для скачивания контактной формы без капчи.
                                                                                                                                                                                        1. 404 # 0
                                                                                                                                                                                          Большое спасибо! То, что нужно.

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