Предоставление посетителям сайта простого и надежного средства обратной связи – это важнейшая часть любого веб-проекта. Наиболее простым и часто используемым каналом обратной связи — являются контактные формы. Посмотреть результат можно здесь.
В сегодняшней статье, мы создадим форму обратной связи на аяксе, с использованием современных техник веб-разработки. Для этого мы будем использовать PHP, CSS и jQuery в виде нескольких плагинов. Плагин formValidator будем использовать для проверки введенных значений, а с помощью плагина jQTransform, будем стилизовать текстовые поля и кнопки нашей формы. В дополнение, мы будем использовать класс PHPMailer для отправки на почту введенных данных.
Кроме того, наша форма будет прекрасно работать даже с выключенным JS.
*Для нормальной работы примера, вам понадобится PHP5
Шаг 1 – XHTML
Сначала нам понадобится XHTML-разметка для формы.
demo.php
<div id="main-container"> <!-- The main container element --> <div id="form-container"> <!-- The form container --> <h1>Fancy Contact Form</h1> <!-- Headings --> <h2>Drop us a line and we will get back to you</h2> <form id="contact-form" name="contact-form" method="post" action="submit.php"> <!-- The form, sent to submit.php --> <table width="100%" border="0" cellspacing="0" cellpadding="5"> <tr> <td width="18%"><label for="name">Name</label></td> <!-- Text label for the input field --> <td width="45%"><input type="text" class="validate[required,custom[onlyLetter]]" name="name" id="name" value="<?=$_SESSION['post']['name']?>" /></td> <!-- We are using session to prevent losing data between page redirects --> <td width="37%" id="errOffset"> </td> </tr> <tr> <td><label for="email">Email</label></td> <td><input type="text" class="validate[required,custom[email]]" name="email" id="email" value="<?=$_SESSION['post']['email']?>" /></td> <td> </td> </tr> <tr> <td><label for="subject">Subject</label></td> <!-- This select is being replaced entirely by the jqtransorm plugin --> <td><select name="subject" id="subject"> <option value="" selected="selected"> - Choose -</option> <option value="Question">Question</option> <option value="Business proposal">Business proposal</option> <option value="Advertisement">Advertising</option> <option value="Complaint">Complaint</option> </select> </td> <td> </td> </tr> <tr> <td valign="top"><label for="message">Message</label></td> <td><textarea name="message" id="message" class="validate[required]" cols="35" rows="5"><?=$_SESSION['post']['message']?></textarea></td> <td valign="top"> </td> </tr> <tr> <td><label for="captcha"><?=$_SESSION['n1']?> + <?=$_SESSION['n2']?> =</label></td> <!-- A simple captcha math problem --> <td><input type="text" class="validate[required,custom[onlyNumber]]" name="captcha" id="captcha" /></td> <td valign="top"> </td> </tr> <tr> <td valign="top"> </td> <!-- These input buttons are being replaced with button elements --> <td colspan="2"><input type="submit" name="button" id="button" value="Submit" /> <input type="reset" name="button2" id="button2" value="Reset" /> <?=$str?> <!-- $str contains the error string if the form is used with JS disabled --> <img id="loading" src="img/ajax-load.gif" width="16" height="16" alt="loading" /> <!-- the rotating gif animation, hidden by default --> </td></tr> </table> </form> <?=$success?> <!-- The $success variable contains the message that is shown if JS is disabled and the form is submitted successfully --> </div> </div> <!-- closing the containers -->
Как вы могли заметить в строке 8, обрабатывать нашу форму будет файл submit.php. Мы будем использовать этот файл в обоих случаях – как для обычной отправки формы (для посетителей с выключенным JS), так и для аяксовой отправки формы. Это позволит легко обновлять код, без необходимости объединять изменения между файлами.
Далее, мы можете видеть, что мы используем массив $_SESSION для заполнения текстовых полей значениями. Это делается для того, чтобы данные не потерялись во время перенаправления страницы, которое происходит во время отправки формы в submit.php.
Другой важный аспект – это классы, назначенный текстовым полям – classs=”validate[required,custom[onlyLetter]]”. Эти классы используются плагином валидации для определения правил проверки введенных значений для каждого текстового поля. В нашем примере, мы указываем, что поле обязательное, и разрешено вводить только буквы.
Существует множество доступных правил валидации, вы можете узнать о них на домашней странице плагина.
Теперь взгляните, как будет выглядеть наша форма, с применением плагина JQtransform.
Шаг 2 – jQuery
МЫ используем два плагина jQuery – jQtransform для стилизации элементов формы, и formValidator для проверки введенных значений на клиентской стороне.
Очень важно помнить, что кроме клиентской стороны, введенные данные всегда нужно проверять на серверной стороне.
Итак, для начала нам нужно подключить все необходимые библиотеки.
demo.php
<link rel="stylesheet" type="text/css" href="jqtransformplugin/jqtransform.css" /> <link rel="stylesheet" type="text/css" href="formValidator/validationEngine.jquery.css" /> <link rel="stylesheet" type="text/css" href="demo.css" /> <?=$css?> <!-- Special CSS rules, created by PHP --> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> <script type="text/javascript" src="jqtransformplugin/jquery.jqtransform.js"></script> <script type="text/javascript" src="formValidator/jquery.validationEngine.js"></script> <script type="text/javascript" src="script.js"></script>
Указанный выше код расположен в секции head, файла demo.php. Сначала мы подключаем CSS-файлы, используемые обоими плагинами, а затем уже библиотеку JQuery и плагины. Возможно, вас заинтересовала строка 5 – это специальный набор CSS-правил, который мы создадим с помощью PHP, для отображения подтверждающего сообщения, как вы увидите в дальнейшем.
Теперь, давайте посмотрим на наш файл script.js.
script.js
$(document).ready(function(){ /* after the page has finished loading */ $('#contact-form').jqTransform(); /* transform the form using the jqtransform plugin */ $("button").click(function(){ $(".formError").hide(); /* hide all the error tooltips */ }); var use_ajax=true; $.validationEngine.settings={}; /* initialize the settings object for the formValidation plugin */ $("#contact-form").validationEngine({ /* create the form validation */ inlineValidation: false, promptPosition: "centerRight", success : function(){use_ajax=true}, /* if everything is OK enable AJAX */ failure : function(){use_ajax=false} /* in case of validation failure disable AJAX */ }) $("#contact-form").submit(function(e){ if(!$('#subject').val().length) { $.validationEngine.buildPrompt(".jqTransformSelectWrapper","* This field is required","error") /* a custom validation tooltip, using the buildPrompt method */ return false; } if(use_ajax) { $('#loading').css('visibility','visible'); /* show the rotating gif */ $.post('submit.php',$(this).serialize()+'&ajax=1', /* using jQuery's post method to send data */ function(data){ if(parseInt(data)==-1) $.validationEngine.buildPrompt("#captcha","* Wrong verification number!","error"); /* if there is an error, build a custom error tooltip for the captcha */ else { $("#contact-form").hide('slow').after('<h1>Thank you!</h1>'); /* show the confirmation message */ } $('#loading').css('visibility','hidden'); /* hide the rotating gif */ }); } e.preventDefault(); /* stop the default form submit */ }) });
Весь блок скрипта выполняется внутри метода $(document).ready, который гарантирует нам, свое исполнение, только после окончания загрузки страницы.
Далее, мы используем метод jqTransform(), который определен в плагине jqtransform. Он переделывает и стилизует все элементы формы (тестовые поля, кнопки и др.)
Элемент select заменяется набором дивов и ссылок. Это выглядит здорово, однако влечет за собой некоторые проблемы с плагином валидации, в связи с чем, тултип для селекта нам придется сделать вручную.
После этого, в строке 7, вешаем обработчик событий на нажатие кнопки в нижней части формы, с одной строкой кода, которая прячет отображаемые тултипы с сообщениями об ошибках. Это для того, чтобы страница правильно обновлялась, и подсказки не оставались на странице, если пользователь ввел правильные данные.
Далее, мы инициализируем плагин formValidation, с помощью метода validationEngine() и в строке 24 описываем событие формы onsubmit. Пара моментов, на которые стоит обратить внимание здесь – отдельный тултип в строке 28, и дополнительный параметр ajax=1, в строке 39. Этот параметр использует файл submit.php, для того чтобы определить, передан ли запрос с помощью аякса или получен непосредственно через отправку формы.
Также, обратите внимание, что мы используем специальную переменную use_ajax, для предотвращения работы аякса, если форма не прошла проверку.
Шаг 3 – CSS
Все наши CSS-правила описаны в файле demo.css
demo.css
body,h1,h2,h3,p,quote,small,form,input,ul,li,ol,label{ /* reset some of the page elements */ margin:0px; padding:0px; } body{ color:#555555; font-size:13px; background: url(img/dark_wood_texture.jpg) #282828; font-family:Arial, Helvetica, sans-serif; } .clear{ clear:both; } #main-container{ width:400px; margin:30px auto; } #form-container{ background-color:#f5f5f5; padding:15px; /* rounded corners */ -moz-border-radius:12px; -khtml-border-radius: 12px; -webkit-border-radius: 12px; border-radius:12px; } td{ /* prevent multiline text */ white-space:nowrap; } a, a:visited { color:#00BBFF; text-decoration:none; outline:none; } a:hover{ text-decoration:underline; } h1{ color:#777777; font-size:22px; font-weight:normal; text-transform:uppercase; margin-bottom:5px; } h2{ font-weight:normal; font-size:10px; text-transform:uppercase; color:#aaaaaa; margin-bottom:15px; border-bottom:1px solid #eeeeee; margin-bottom:15px; padding-bottom:10px; } label{ text-transform:uppercase; font-size:10px; font-family:Tahoma,Arial,Sans-serif; } textarea{ color:#404040; font-family:Arial,Helvetica,sans-serif; font-size:12px; } td > button{ /* A special CSS selector that targets non-IE6 browsers */ text-indent:8px; } .error{ /* this class is used if JS is disabled */ background-color:#AB0000; color:white; font-size:10px; font-weight:bold; margin-top:10px; padding:10px; text-transform:uppercase; width:300px; } #loading{ /* the loading gif is hidden on page load */ position:relative; bottom:9px; visibility:hidden; } .tutorial-info{ color:white; text-align:center; padding:10px; margin-top:10px; }
Обратите внимание на строку 85. Это правило делает кнопки шире, но, к сожалению это плохо выглядит в IE6. Поэтому мы используем специальный CSS-селектор, который игнорируется IE6, но отлично понимают остальные браузеры.
Теперь, все что нам осталось – это PHP.
Шаг 4 – PHP
Сначала давайте рассмотрим код в начале файла demo.php
demo.php
session_name("fancyform"); session_start(); $_SESSION['n1'] = rand(1,20); /* generate the first number */ $_SESSION['n2'] = rand(1,20); /* then the second */ $_SESSION['expect'] = $_SESSION['n1']+$_SESSION['n2']; /* the expected result */ /* the code below is used if JS has been disabled by the user */ $str=''; if($_SESSION['errStr']) /* if submit.php returns an error string in the session array */ { $str='<div class="error">'.$_SESSION['errStr'].'</div>'; unset($_SESSION['errStr']); /* will be shown only once */ } $success=''; if($_SESSION['sent']) { $success='<h1>Thank you!</h1>'; /* the success message */ $css='<style type="text/css">#contact-form{display:none;}</style>'; /* a special CSS rule that hides our form */ unset($_SESSION['sent']); }
Как видите, мы используем массив $_SESSION для хранения двух случайных чисел и ожидаемого результата. Это будет использоваться в дальнейшем, файлом submit.php, для подтверждения того, что капча решена.
Другой интересный момент находится в строке 21, где мы описываем простой CSS-класс. Фактически здесь, мы скрываем форму, и отображаем сообщение об успешной отправке, если у пользователя отключен JS.
submit.php
require "phpmailer/class.phpmailer.php"; session_name("fancyform"); /* starting the session */ session_start(); foreach($_POST as $k=>$v) { /* if magic_quotes is enabled, strip the post array */ if(ini_get('magic_quotes_gpc')) $_POST[$k]=stripslashes($_POST[$k]); $_POST[$k]=htmlspecialchars(strip_tags($_POST[$k])); /* escape the special chars */ } $err = array(); /* some error checks */ if(!checkLen('name')) $err[]='The name field is too short or empty!'; if(!checkLen('email')) $err[]='The email field is too short or empty!'; else if(!checkEmail($_POST['email'])) $err[]='Your email is not valid!'; if(!checkLen('subject')) $err[]='You have not selected a subject!'; if(!checkLen('message')) $err[]='The message field is too short or empty!'; /* compare the received captcha code to the one in the session array */ if((int)$_POST['captcha'] != $_SESSION['expect']) $err[]='The captcha code is wrong!'; /* if there are errors */ if(count($err)) { /* if the form was submitted via AJAX */ if($_POST['ajax']) { echo '-1'; } /* else fill the SESSION array and redirect back to the form */ else if($_SERVER['HTTP_REFERER']) { $_SESSION['errStr'] = implode('<br />',$err); $_SESSION['post']=$_POST; header('Location: '.$_SERVER['HTTP_REFERER']); } exit; } /* the email body */ $msg= 'Name: '.$_POST['name'].'<br /> Email: '.$_POST['email'].'<br /> IP: '.$_SERVER['REMOTE_ADDR'].'<br /><br /> Message:<br /><br /> '.nl2br($_POST['message']).' '; $mail = new PHPMailer(); /* using PHPMailer */ $mail->IsMail(); $mail->AddReplyTo($_POST['email'], $_POST['name']); $mail->AddAddress($emailAddress); $mail->SetFrom($_POST['email'], $_POST['name']); $mail->Subject = "A new ".mb_strtolower($_POST['subject'])." from ".$_POST['name']." | contact form feedback"; $mail->MsgHTML($msg); $mail->Send(); unset($_SESSION['post']); /* unsetting */ /* the form was successfully sent */ if($_POST['ajax']) { echo '1'; } else { $_SESSION['sent']=1; if($_SERVER['HTTP_REFERER']) header('Location: '.$_SERVER['HTTP_REFERER']); exit; } /* some helpful functions */ function checkLen($str,$len=2) { return isset($_POST[$str]) && mb_strlen(strip_tags($_POST[$str]),"utf-8") > $len; } function checkEmail($str) { return preg_match("/^[\.A-z0-9_\-\+]+[@][A-z0-9_\-]+([.][A-z0-9_\-]+)+[A-z]{1,4}$/", $str); }
Обратите внимание как мы проверяем переменную $_POST[‘ajax’] на предмет установки и правильной работы. Как вы наверное помните, мы устанавливаем ее ранее, в файле script.js, для определения используется ли аякс для извлечения данных.
Две переменные массива $_SESSION errStr и post используются для совместного использования данных между формой и файлом submit.php, в случае выключенного JS. Здесь переменная post содержит отправленный нами массив $_POST и используется для заполнения полей формы, после того как пользователь перенаправляется обратно.
На этом работа над нашей формой обратной связи подошла к концу.
Пример рабочий, за исключением одного маленького недоразумения. Плагин formValidation, создан с целью проводить валидацию только английских символов, так что если вы попытаетесь написать имя по-русски, он выдаст ошибку о том, что нужно вводить только буквы. К счастью это решается путем замены регулярного выражения в файле jquery.validationEngine.js. Найдите строчки:
"onlyLetter":{ "regex":"/^[a-zA-Z\ \']+$/", }
и замените на следующую:
"onlyLetter":{ "regex":"/^[a-zA-Zа-яА-Я' ]+$/", }
После этого, скрипт перестанет игнорировать русские символы.
В связи с бесконечными вопросами, специально, отдельно сообщаю: настройка адреса email на который производится отправка писем, находится в файле submit.php, в самом начале файла, выглядит вот так:
/* config start */ $emailAddress = ''; /* config end */
Перевод статьи «A Fancy AJAX Contact Form«, автор Martin
смотреть всем срочно
Виктория как же вы так со мной поступили?
Классная форма! А есть аналог для joomla? И, если есть, как называется?
То что надо! Спасибо огромное! Для визитки со статическими страницами это идеальный вариант, да и вообще для всех сайтов без использования доп. модулей к смс
Спасибо! Добавил себе в блог: http://blogg.ck.ua/feedback
Очень нужна такая форма, только с аттачем (вложением картинки, фото), у самого знаний не хватает доработать. Если можете — подскажите, что и где нужно добавить, кроме HTML формы. Спасибо.
Вот тут есть еще пример
А где же указывается собственный почтовый ящик, на который всё приходит?
решил задачу. но поменяв названия полей (имя, ip-адрес) в теле письма на русские буквы, приходит не в русском, а в символах..
А скажите, можно добавить дополнительное поля или поля?
Думаю, интересно будет всем!
И все таки, почему крякозябры то в сообщениии? если оно русское.
А пожскажите пожалуйста, как в неё добавить поле «Прикрепить фаил», что бы вместе с сообщением отправлялся и фаил?? Очень нужно так сделать! Подскажите на почту: psash7 @ mail. ru
Меня тоже интересует как добавить в обработчик команды прикрепления файлов. Побывала разные варианты ничего не получается. Подскажите пожалуйста.
Как настроить скрипт, что-бы отсылал письма на почтовый ящик?
Пытался настроить выдает Invalid address: You must provide at least one recipient email address.
Как убрать капча для быстрых вопросов?
Вот еще альтернативный вариант:
http://majes.ru/
я себе их ставлю, не подводили.
я ламер какой то. ниче не понимаю. люди добрые как прикрутить это дело. где прописать адрес почты. подскажите
Привет! у меня сообщения об ошибке выводятся внизу может подскажете в чем проблема?
я разобралась эта форма некорректно работает при кодировке windous-1251
А где вставить или поменять е-маил адрес, на который должны приходить сообщения?
Сделал я по подобным описанием форму — 3 дня трахался, так и не заработала! Такое впечатление что эти «добрые» дяди фигню выкладывают для привлечения посетителей, а сами ржут над недоумевающей публикой!
форма очень классная и работает, а все те, кто ругает — криворукие чтоли? там же все написано и настолько просто и понятно, что проще уже просто некуда
Пожалуйста, тыкните меня носом в строчку где нужно заменить EMAIL на свой :D
Начало файла submit.php, там это настраивается.
Уже нашел, спасибо, но возникла другая проблема
Письмо не приходит на емэйл. Дело в том что сайт еще в стадии разработки на локальной машине.
Я использую Denwer 3 (php 5.3). Может проблема именно втом что с локальной машины пытаюсь отправить?
sendmail нужно установить. В Денвере нет его.
Внутри денвера была статья на эту тему
Я пользуюсь генератором форм обратной связи: перейти
С программированием дружу плохо так как.
Как можно подправить class.phpmailer.php под windows-1251?
Странная проблема.
Тема — это поле select. Валидация для него прописанна не в классе, как для текстовых полей, а в script.js именно для этого поля.
Если я добавляю еще один select в форму и прописываю валидацию через класс, то аяксовский алерт выскакивает не напротив поля, а в самом верху страницы. Для текстовых полей все ок, но для селектов — нефига.
Если пытаюсь скопипастить кусок кода в script.js
if(!$(‘#sunject’).val().length)
{
$.validationEngine.buildPrompt(«.jqTransformSelectWrapper»,»* Это поле обязательное»,»error»)
return false;
}
и сделать такой же для второго select-a, то у формы слетают стили.
как мне сделать так, чтобы алерт вылезал ровно напротив поля?..
Дурацкий вопрос наверное… но
Как сменить цвет формы :) а лучше вообще его убрать чтоб остались только поля?
Все css перерыл не могу понять:(
:)Правильно заданный вопрос — половина ответа — все дело в невнимательности.
Форма дублируется и в дубликате не изменил ссылку на css — соответственно правлю — и ничего не происходит :)
Алан, зачем капчу убирать? Вас просто завалят спамом потом!!!
Не работает капча!!!! В чем проблема??? Ссылка
Собираюсь использовать форму, но на modx. Может получится, отпишусь)
Ну и как? Получилось?
А есть ли подобная форма, но с отправкой файлов?
Проблема, помогите! Не могу поменять кодировку на windows-1251?
В файле class.phpmailer.php в 59 строчке поменя на это —
public $CharSet = ‘windows-1251’;*/
Какие строки нужно править? Как оно отправляет вообще? Где нужно вводить ту почту, от имени которой будет идти рассылка, где вводить её пароль и логин?
Форма классная. Все работает. Установить можно даже новичку, если он, конечно, внимательно следует инструкциям. НО. Форма корректно работает только в «родительском» коде — UTF-8. Если сайт или страничка на которой вставляется код обратной связи написан в windous-1251 — будут проблемы — сама страница с формой обратной связи в браузерах (к примеру, IE, Мазила, Опера) будет отображаться в абраказябрях. Можно решить эту проблему поменяв код не только в сценариях служебных файлов, но и перезаписав сами файлы (их два) в требуемом коде. Форма не только будет отображаться на русском, но заработает корректно — письма будут приходить без абразябр. Но опять НО. Полетят стили. Если это не пугает — вперед и с песнями.
Хотел бы использовать тему, но ламер страшный.
Собственно задача состоит в том, чтобы отменить валидацию и убрать поле «Тема» и капча
Помогите, пожалуйста)
Допиливать придется, но как основа самая лучшая
Супер!!! Я очень долго искал такую форму! Спасибо!
Красиво очень, вопрос можно ли использовать отсюда информацию, чтобы например преодразовать у меня форму заполнения заказа?
Например вот тут
Спасибо
Меняла кодировку. В итоге сейчас письма не отправляются, хотя с виду все работает. В чем проблема? Сейчас стоит utf-8
Всё конечно здорво. Но вот мне например надо. сделать что то подобное но только для Сообщений о битых Ссылках на сайте. К примеру мне даром не нужны имя и емайл отправителя. А вместо этого нужно поле автоматической вставки адреса страницы с которой было отправлено сообщение. Вот так вот. И хрен найдёшь нормального вариант реализации такой задумки.
Мысль такая , я очень благодарен автору этого прекрасного сайта, вероятно хозяйка талант в дизайне тоже ,но я не об этом, тема кодировки не закрыта ))
В class.phpmailer.php поменяй кодировка на utf-8 в строке public $CharSet = ‘ ‘; я поменял у меня все работает нормально)))
Спасибо, отличная форма. Прикрутил к сайту на joomla.
Для индикации AJAX операций можно также воспользоваться маленькой JavaScript библиотекой AjaxLoader.js (http://musicvano.github.io/ajaxloader/) для генерации спиннеров и динамического изменения их параметров.