В прошлой части мы сделали бекенд нашего модуля «Заказать звонок», который ожидает что в него когда нибудь придут всего два параметра: Телефон и Имя заказавшего звонок, после чего он их должен бережно добавить в базу данных добавив к записи ip заказавшего (в будущем можно будет сделать блэк-лист). Теперь пришло время сделать фронтенд нашего модуля, для этого нам понадобятся:
- jQuery v1.x
- Bootstrap v3.x
- Ion.js 1.x Ссылка на github
Первые две библиотеки не нуждаются в представлении, а про ion.js скажу пару слов. Это даже не библиотека а дополнение к jQuery и Bootstrap (Именно к ним обоим) стало быть что-бы использовать ion.js нужно с начала подключить jQuery потом Bootstrap и уже потом ion.js. А нужен ion.js только для того что-бы удобно собирать данные с форм, отправлять их посредством AJAX на нужный адрес и вставлять результат в заданный контейнер, и всё это делать одной командой типа :
1 |
data=.userinputs;ajax=/ajax/url;html=#Container; |
Что-бы это работало, в javasctript шаблона, нужно будет добавить такой код:
1 2 3 4 5 6 |
var ion = new Ion(); $(document).on('click', '[ion]', function () { ion.cmd($(this).attr('ion')); }); |
Так-же нам понадобятся парочка скрытых элементов на странице, это модальное окно и контейнер для системных сообщений. Про модальное окно понятно, оно и будет содержать нашу форму для заполнения, это будет стандартное модальное окно Twitter Bootstrap, его код:
1 2 3 4 5 6 7 |
<!-- Bootstrap Modal --> <div class="modal fade" id="ModalWin" tabindex="-1"> <div class="modal-dialog"> <div class="modal-content"> </div> </div> </div> |
A вот с контейнером системных сообщений поподробнее.
Зачем нужны системные сообщения? Когда мы делаем что-то не так, т.е. допускаем ошибки, нам было бы очень удобно если бы мы точно знали, какие ошибки мы допустили. По этому в любом хорошем интерфейсе обязательно будет предусмотрено поле для системных сообщений. В нашем случае это будет контейнер, куда будут подгружаться эти самые сообщения, контейнер этот будет отслеживаемый, т.е. на нём будет висеть обработчик, отслеживающий изменения внутри контейнера, и если они происходят (т.е. появились сообщения) их нужно как-то обработать (показать). Сделаем красиво и с анимацией:
На странице должен присутствовать html-код:
1 2 3 4 |
<!-- System messages --> <div id="SystemMessagesWrapper"> <div id="SystemMessages"></div> </div> |
Для него предусмотрен приблизительно такой стиль:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
/* SystemMessages */ #SystemMessagesWrapper { position: fixed; left: 0; right: 0; bottom: 10%; z-index: 10000; } #SystemMessages { max-width: 600px; margin: 0 auto; } #SystemMessages>div { display: none; border-radius: 5px; padding: 11px 18px; } #SystemMessages .error { background: red; border: 2px solid #000; border-color: #a51a1a; color: #fff; } #SystemMessages .message { background: green; border: 2px solid #000; border-color: #18be2d; color: #fff; } |
Обратите внимание на то что мы сделаем два типа сообщения: .error и .message просто мы будем по разному отображать сообщения с уведомлениями и с ошибками, красненькие и зелёненькие.
Для того что-бы наши сообщения красивенько появлялись и скрывались, и самое главное обрабатывались, в яваскрепте нашего шаблона должен быть вот такой код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/* Sysytem messages */ function showSystemMessages() { $('#SystemMessages>div') .not('.showed') .addClass('showed') .animate({marginBottom:1000,opasity:0},0) .show() .animate({marginBottom:5,opasity:1},700) .delay(3000) .fadeOut(300,function(){ this.remove(); }); } $('#SystemMessages').bind("DOMSubtreeModified",function(){ showSystemMessages(); }); |
Все внешние приготовления закончены, приступим к созданию непосредственна модуля обратной связи, дальше я не буду заниматься оформлением а покажу только то что необходимо, по этому всё будет предельно просто:
Итак, нам понадобится три элемента:
- Кнопка которая вызывает форму
- Страница с содержимым модального окна
- Страница обработчик
Кнопка
1 |
<button ion="ajax=/callme/modal;modal=#ModalWin;">Заказать звонок</button> |
В ion-команде дословно написано (порядок команд не имеет значения) обратится по адресу /callme/modal и вызвать модальное окно с идентификатором #ModalWin в котором отобразить содержимое ответа от сервера.
Страница для модального окна
Создадим страницу с содержимым модального окна, для этого в админке сделаем страничку с такими параметрами:
1 2 3 4 5 |
<div id="Callme"> <input name="name">Имя</input><br> <input name="phone">Телефон</input><br> <button ion="data=#Callme input;ajax=/callme/send;prepend=#SystemMessages;">Зазазать звонок</button> </div> |
Теперь при нажатии на кнопку «Заказать звонок» появляется наше модальное окно (неприглядное, стилизуйте сами):
Обратите внимание на Ion-команду кнопки «Заказать звонок» внутри модального окна:
data=#Callme input;ajax=/callme/send;prepend=#SystemMessages;
Дословно:
- data=#Callme input; — Собрать значения со всех полей ввода input внутри контейнера с идентификатором #Callme
- ajax=/callme/send; — Отправить собранные данные по адресу /callme/send
- prepend=#SystemMessages; — Добавлять в начало контейнера с идентификатором #SystemMessages ответ сервера
Страница обработчик
Теперь создадим страницу-обработчик:
Содержимое секции Markup
1 2 3 4 5 6 7 |
{% if alerts %} {% for alert in alerts %} <div class="error">{{ alert }}</div> {% endfor %} {% else %} <div class="message">Заявка принята!</div> {% endif %} |
Содержимое секции Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
function onStart(){ App::setLocale('ru'); // Выставляем локализацию сообщений для валидатора $repiatTime = 60; // Время повторной отправки в секундах $name = trim(e(post('name'))); $phone = trim(preg_replace("/\D/", "", trim(post('phone')))); # Валидация вводимых данных $validator = Validator::make( [ 'Имя' => $name, 'Мобильный_телефон' => $phone, ], [ 'Имя' => 'min:2|max:100', 'Мобильный_телефон' => 'required|min:11|max:11', ] ); if ($validator->fails()) { $this['alerts'] = $validator->messages()->all(); } else { if( Session::get('repeat')!="" && time() < Session::get('repeat') ) { $timeDiff = Session::get('repeat') - time(); $this['alerts'] = ['Повторную заявку можно отправить через '.$timeDiff.' сек.']; } else { DB::table('mcmraak_feedback_calls')->insert( [ 'name' => $name, 'phone' => $phone, 'ip' => $_SERVER['REMOTE_ADDR'] ] ); if($name==""){ $name="Не указано."; } Session::put('repeat', time() + $repiatTime); } } } |
Для тех кто знает PHP и Laravel на обычном уровне познаний всё будет понятно, остальные могут воспользоваться гуглом и самостоятельно разобрать что тут написано. Добавлю только то что стоит обратить внимание только на указание правильной таблицы в конструкторе запросов DB::table(‘mcmraak_feedback_calls’) посмотреть её название вы можете в Bulder
На этом пока всё, начальный результат достигнут. Заявки принимаются, добавляются в бузу данных, их нельзя отправлять чаще чем раз в минуту (время можно выставить в коде). При не правильном вводе, или при отправке раньше чем раз в минуту, всплывают сообщения.
Используя данную инструкцию, вы можете как угодно облагородить ваш модуль приёма заявок, в него можно добавить:
- Фиксирование времени заявки
- Капчу
- Сообщение пользователя
- Ссылка на страницу с которой была отправка
- Бан по ip
- И много много чего ещё, с абсолютной гибкостью которую предоставляет October CMS и Laravel на котором он работает.
Как это выглядит в результате:
P.S. Если кому-то это интересно, пишите ваши комментарии, это будет мотивировать меня написать продолжение данного цикла статей с Вашими пожеланиями