В этом уроке мы с вами научимся реализовывать формы обратной связи на основе 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.
Если вы проверите отправку формы, то вам на почту должно упасть примерно такое письмо:
У нас с вами получилось реализовать форму заказа обратного звонка. Осталась форма на странице контактов, которую я вам предлагаю реализовать самим.