В этом уроке мы с вами научимся реализовывать формы обратной связи на основе FormIt и AjaxForm. Начнем мы наш урок с формы обратного звонка, которая находится в модальном окне. Помните, в начале курса мы с вами создавали чанк modals? Теперь пришло время уменьшить его объем.
В качестве подготовки нам с вами необходимо создать два чанка: для письма и для формы. Так как я люблю, чтобы все было красиво, я адаптировал чанк письма miniShop2 под AjaxForm. Получился у меня чанк email_form.tpl:
{var $style = [
'logo' => 'display:block;margin: auto;',
'a' => 'color:#348eda;',
'p' => 'font-family: Arial;color: #666666;font-size: 12px;margin: 0 20px 10px;',
'h' => 'font-family:Arial;color: #111111;font-weight: 200;line-height: 1.2em;margin: 40px 20px;',
'h1' => 'font-size: 36px;',
'h2' => 'font-size: 28px;',
'h3' => 'font-size: 22px;',
'h3' => 'font-size: 18px;',
'th' => 'font-family: Arial;text-align: left;color: #111111;',
'td' => 'font-family: Arial;text-align: left;color: #111111;',
]}
{var $site_url = ('site_url' | option) | preg_replace : '#/$#' : ''}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>{$_modx->config.site_name}</title>
</head>
<body style="margin:0;padding:0;background:#f6f6f6;">
<div style="height:100%;padding-top:20px;background:#f6f6f6;">
<a href="{$site_url}">
<img style="{$style.logo}"
src="{$site_url}{$_modx->getPlaceholder('+conf_mail_logo')}"
alt="{$_modx->config.site_name}"
width="240"/>
</a>
<!-- body -->
<table class="body-wrap" style="padding:0 20px 20px 20px;width: 100%;background:#f6f6f6;margin-top:10px;">
<tr>
<td></td>
<td class="container" style="border:1px solid #f0f0f0;background:#ffffff;width:800px;margin:auto;">
<div class="content">
<table style="width:100%;">
<tr>
<td>
<h3 style="{$style.h}{$style.h3}">
Сообщение с сайта {$_modx->config.site_name}.
</h3>
<div style="{$style.p}">
{if $form_name?}
<h4 style="{$style.h}{$style.h4}">{$form_name}</h4>
{/if}
<p style="{$style.p}">
{if $name?}
<strong>Имя:</strong> {$name}<br/>
{/if}
{if $subject?}
<strong>Тема:</strong> {$subject}<br/>
{/if}
{if $email?}
<strong>E-mail:</strong> {$email}<br/>
{/if}
{if $phone?}
<strong>Телефон:</strong> {$phone}<br/>
{/if}
{if $text?}
<strong>Вопрос/сообщение:</strong> {$text}<br/>
{/if}
</p>
</div>
</td>
</tr>
</table>
</div>
<!-- /content -->
</td>
<td></td>
</tr>
</table>
<!-- /body -->
<!-- footer -->
<table style="clear:both !important;width: 100%;">
<tr>
<td></td>
<td class="container">
<!-- content -->
<div class="content">
<table style="width:100%;text-align: center;">
<tr>
<td align="center">
<p style="{$style.p}">
<a href="{$site_url}" style="{$style.a}">
{$_modx->config.site_name}
</a>
</p>
</td>
</tr>
</table>
</div>
<!-- /content -->
</td>
<td></td>
</tr>
</table>
<!-- /footer -->
</div>
</body>
</html>
И предлагаю сразу создать чанк для нашей формы обратной связи form_callback.tpl:
<form action="{$_modx->resource.id | url}" method="post" id="callbackform" class="ajax_form">
<input type="hidden" name="page" value="{$_modx->resource.pagetitle | htmlent}">
<input type="hidden" name="pageid" value="{$_modx->resource.id}">
<input type="hidden" name="form_name" value="Заказать звонок">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Заказать звонок</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="message"></div>
<div class="fields">
<div class="form-group hidden">
<label for="callbackform_user">Ваше имя</label>
<input type="text" id="callbackform_user" class="form-control" name="username" placeholder="Пользователь">
</div>
<div class="form-group">
<label for="callbackform_name">Ваше имя:</label>
<input type="text" class="form-control" id="callbackform_name" name="name" placeholder="Иванов Иван Иванович" required>
</div>
<div class="form-group">
<label for="callbackform_phone">Ваш телефон:</label>
<input type="text" class="form-control phone" id="callbackform_phone" name="phone" placeholder="+7 (999) 123-45-67" required>
</div>
<div class="form-group">
<label for="callbackform_text">Сообщение:</label>
<textarea class="form-control" name="text" id="callbackform_text" placeholder="Хочу обсудить детали по доставке. Звонить после 15:00" required></textarea>
</div>
</div>
</div>
<div class="modal-footer">
<div class="fields">
<button type="submit" class="btn btn-blue">Отправить</button>
</div>
</div>
</div>
</div>
</form>
Заметили несколько интересных нюансов? Во-первых, у нас есть антиспам поле username. Работает данный механизм очень просто: так как роботы заполняют все подряд, после отправки формы мы проверяем данное поле на пустоту, если поле заполнено, то определяем ее как спам. В силу того, что поле у нас скрытое, обычный пользователь его не увидит и соответственно не заполнит. Данный механизм работает не хуже каптчи, а так как последняя очень сильно выбивает меня из равновесия, я стараюсь использовать этот метод.
Во-вторых, у нас есть div с классом message, куда мы будем размещать сообщения об успешной отправке или ошибке. Так же есть обертка с классом fields, данные блоки мы с вами будем скрывать после успешной отправки формы.
Итак, нам осталось вызвать наш сниппет AjaxForm в чанке modals:
<div class="modal" tabindex="-1" role="dialog" id="callback">
{$_modx->runSnippet("!AjaxForm", [
'snippet' => 'FormIt',
'form' => '@FILE chunks/form_callback.tpl',
'hooks' => 'spam,email,FormItSaveForm',
'emailTpl' => '@FILE chunks/email_form.tpl',
'emailSubject' => 'Заказ звонка',
'emailTo' => $_modx->getPlaceholder('+conf_to_email'),
'emailFrom' => $_modx->config.emailsender,
'formName' => 'Заказ звонка',
'validate' => 'page:required,name:required,phone:required,username:blank',
])}
</div>
Обратите внимание, что мы тут также используем настройки ClientConfig, которые необходимо создать.
И, конечно, дописать обработчик события af_complete, для управления нашей формой. Его я разместил в чанке scripts.
{ignore}
<script>
$(document).ready(function(){
$(document).on('af_complete', function(event, response) {
var form = response.form;
//console.log(response);
if(response.success){
var id = '#'+form.attr('id')+' .message';
var fields = '#'+form.attr('id')+' .fields';
$(id).html('<div class="alert alert-success" role="alert">[[++submittext]]</div>');
$(fields).hide();
// Заказать звонок
if(form.attr('id') == 'callbackform'){
//yaCounterXXXXXXXX.reachGoal('callbackform');
}
}else{
$(id).html('<div class="alert alert-error" role="alert">[[++submittexterror]]</div>');
}
});
$(document).on('mse2_load', function(e, data) {
$('.eqh').matchHeight();
});
});
</script>
{/ignore}
Заметили теги ignore? Они нам здесь нужны для игнорирования данного блока шаблонизатором Fenom, так как в блоке со скриптами есть фигурные скобки. И, конечно, так как у нас отключен шаблонизатор Fenom, то мы используем стандартный шаблонизатор MODx для вывода текста из настроек ClientConfig.
Если вы проверите отправку формы, то вам на почту должно упасть примерно такое письмо:

У нас с вами получилось реализовать форму заказа обратного звонка. Осталась форма на странице контактов, которую я вам предлагаю реализовать самим.
{'!AjaxForm'|snippet:[ 'snippet'=>'FormIt', 'form'=>'@FILE chunks/feedback/feedback_form.tpl', 'emailTpl' => '@FILE chunks/feedback/feedback_letter.tpl', 'hooks'=>'chekSpamProtectionMessageKey,checkSpam,email,FormItSaveForm', 'formName'=>'Форма (контакты)' 'formFields' => 'name,email,phone,message', 'fieldNames' => 'name==Имя отправителя,email==Электронная почта,phone==Телефон,message==Сообщение', 'emailTo'=> 'email_to'|config, 'emailSubject'=>$_modx->getPlaceholder('email_subject'), 'emailReplyTo' => $_modx->getPlaceholder('email'), 'emailFrom'=>'email_from'|config, 'emailFromName' => 'site_name'|config, 'validate'=>'name:required,email:email:required,message:required,nospam:blank,usecontrol:blank', ]}Соответственно значение emailReplyTo берется из отправляемой формы, поля email. И оно удачно отправляется. Но вот значение emailSubject планировал брать из скрытого поля, значение которого меняется в зависимости от шаблона и выбранных настроек, чтобы не плодить формы.Так вот оно не отправляется. Письма приходят без темы. Вроде что одно, что другое имеют значения, а обрабатывается лишь одно. Или я где-то что-то упустил? Спасибо