MODX AjaxForm — документация и примеры построения контактных форм

MODX AjaxForm - документация и примеры построения контактных форм MODX Revo
Содержание
  1. AjaxForm vs FormIt — что лучше использовать. Плюсы и минусы.
  2. Документация по AjaxForm
  3. Основные параметры
  4. Всплывающие сообщения
  5. Обработка своим сниппетом
  6. Валидация формы
  7. Событие af_complete
  8. Пример с оф. документации
  9. Решение проблем с отправкой писем (Отладка)
  10. Реальные примеры создания форм обратной связи
  11. Задача 1. Переписать вызовы контактной формы с Formit на AjaxForm.
  12. Задача 2. Создать форму заказа обратного звонка в модальном окне.
  13. AjaxForm на fenom
  14. Финальный штрихи
  15. Задача 3. Продвинутая форма с вложениями при помощи Formit + AjaxForm
  16. Плюшки
  17. Закрываем модальное окно после отправки формы
  18. Изменение стилей и положения всплывающего окна Ajaxform.
  19. Оптимизация скорости загрузки сайта. 
  20. redirect на другую страницу сайта, после успешной отправки формы?
  21. Настройка отправки целей в AjaxForm
  22. Как передать адрес и заголовок страницы
  23. Чекбокс — согласие с политикой обработки персональных данных
  24. Дополнительно

В прошлом уроке мы разобрали документация по пакету FormIt и построили контактную форму. Сегодня логическое продолжение.

В данной уроке мы рассмотрим бесплатный компонент AjaxForm — сниппет для отправки форм через ajax (отправка форм без перезагрузки, который по умолчанию рассчитан на работу с пакетом FormIt, но можно написать собственный обработчик.

Установить AjaxForm можно через репозиторий modstore.

AjaxForm vs FormIt — что лучше использовать. Плюсы и минусы.

Мне не нравится, что аякс форм, при инициализации регистрирует на фронтенде скрипты: jQuery.Form и jQuery.jGrowl. Плюс ко всему этому требует наличия подключения jQuery.

По этому, когда на странице 1 форма, я обычно использую чистый FormIt, т.к. он не добавляет своих библиотек. Когда на странице по 3-10 форм (это сейчас модно), я всегда использую AjaxForm, т.к. нет проблем с отправкой (дублированием писем) с разных форм + есть дополнительные плюшки.

  • Сохраняет в сессию $scriptProperties при инициализации сниппета.
  • Выводит указанную форму, прописывая класс ajax_form и скрытый input для получения $scriptProperties.
  • Вешает обработчик для отправки форм через ajax — без перезагрузки страницы.
  • При отправке запускает указанный вами сниппет (обработчик) и возвращает ответ от него.
  • Выводит сообщение об успехе отправки, или ошибки.

Документация по AjaxForm

Основные параметры

Имя По умолчанию Плейсхолдеры и примечания
&form tpl.AjaxForm.example Образец чанка с формой, который можно взять за основу.
&snippet FormIt Можете написать свой сниппет для обработки формы.
&frontend_css [[+assetsUrl]]css/default.css Стандартные стили оформления формы и полей с ошибками, чтобы отключить их вывод, укажите пустое значение.
&frontend_js [[+assetsUrl]]js/default.js Javascript для отправки формы через ajax
&actionUrl [[+assetsUrl]]action.php Адрес коннектора, на который отправляется форма

Всплывающие сообщения

По умолчанию AjaxForm выводит сообщения об успешной отправке формы или о наличии ошибок. Можете самостоятельно вызывать их для своих целей:

AjaxForm.Message.success('Зеленый popup');
AjaxForm.Message.error('Красный popup', 1);
AjaxForm.Message.info('Черный popup');

Указав второй параметр (, 1) — вы получаете «прилипающий» popup, который не закрывается автоматически (а только по нажатию на крестик) — бывает полезно для показа серьёзных ошибок.

примеры всплывающих сообщений с AjaxForm

За выплывающие уведомления, отвечает подключаемая по умолчанию  javascript библиотека jQuery.jGrowl.

Обработка своим сниппетом

Хотите вместо FormIt, использовать собственный сниппет, который будет делать что угодно (например создавать страницы на сайте)? Без проблем, единственное требование — он обязательно должен возвращать JSON массив с ключами:

  • status — 1 или 0, то есть успех или ошибка.
  • message — сообщение о работе сниппета, выводится если status = 0.
  • data — массив для полей с ошибками, в котором ключами является имя поля, а значением — сообщение об ошибке.

Для удобства работы в параметры сниппета передаётся переменная $AjaxForm с классом компонента, чтобы вы могли вызывать из него методы error и success при выдаче ответа.

Простейший пример своего сниппета:

<?php
if (empty($_POST['name'])) {
    return $AjaxForm->error('Ошибки в форме', array(
        'name' => 'Вы не заполнили имя'
    ));
}
else {
    return $AjaxForm->success('Форма прошла проверку');
}

Примечание: данный сниппет ничего не делает, просто возвращает результат проверки имени.

Вызываем так:

[[!AjaxForm?
    &snippet=`MySnippet`
    &form=`tpl.AjaxForm.example`
]]

Валидация формы

Сервер может вернуть ошибку отправки формы и массив полей, не прошедших проверку. Этим полям автоматически будет добавлен CSS класс error, который убирается при последующей отправке.

Так же вы можете запретить отправку формы, используя javascript переменную afValidated — если она объявлена и равна false, то форма не будет отправлена.

Важно! Все проверки на javascript можно обойти, так что лучше не использовать эту переменную стоит использовать для реальной проверки данных. Используйте только для удобства пользователей.

<script>
$(document).on('submit', '.ajax_form', function() {
    // Здесь любой код для проверки формы при отправке
    console.log(this);

    // Результатом работы будет выставление глобальной переменной
    afValidated = false; // Или true, если валидация пройдена
});
</script>

Событие af_complete

При получении ответа от сервера вызывается событие af_complete, которое вы можете использовать для обновления содержимого страницы или другой операции javascript.

Вам просто нужно указать функцию, в которую будет передано событие javascript и объект с ответом от сервера. Обратите внимание, что внутри этого объекта есть и отправляющая форма.

$(document).on('af_complete', function(event, response) {
    var form = response.form;
    // Если у формы определённый id
    if (form.attr('id') == 'my_form_3') {
        // Скрываем её!
        form.hide();
    }
    // Иначе печатаем в консоль весь ответ
    else {
        console.log(response)
    }
});

Пример с оф. документации

Отправка email сообщения при помощи FormIt с требованием некоторых полей:

[[!AjaxForm?
    &snippet=`FormIt`
    &form=`tpl.AjaxForm.example`
    &hooks=`email`
    &emailSubject=`Тестовое сообщение`
    &emailTo=`info@domain.com`
    &validate=`name:required,email:required,message:required`
    &validationErrorMessage=`В форме содержатся ошибки!`
    &successMessage=`Сообщение успешно отправлено`
]]

Решение проблем с отправкой писем (Отладка)

При возникновении любых проблем, в первую очередь проверяйте, отправляется ли форма без AjaxForm. Помните, что AjaxForm — сниппет-обёртка, он не отправляет письма и не проводит проверку формы. Это делает ваш сниппет или FormIt.

Так же не забывайте заглядывать в консоль браузера на предмет ошибок javascript. Если сервер выдаёт ошибку 500 при отправке, проверьте параметр register_globals у вашего PHP — он должен быть отключен.

Официальная документация по компоненту AjaxForm.

Реальные примеры создания форм обратной связи

Стоит 3 задачи, рассмотрим их.

Задача 1. Переписать вызовы контактной формы с Formit на AjaxForm.

Перепишем форму с прошлого урока. По большому счету ничего особо не меняется. Помещаем код формы в отдельный чанк, пусть будет contact_form (код на modparser берите с прошлого урока, здесь приведу на fenom):

<form class="ajax_form af_example contact-form custom-form-style-1" action="{$_modx->makeUrl($_modx->resource.id, '', '', 'full')}" method="post">
        {$fi.successMessage}
        {$fi.validation_error_message}
        <div class="row row-gutter-sm">
            <div class="form-group col mb-3">
                <input type="text" value="" class="form-control" name="name" id="name" required placeholder="Ваше имя">
                <span class="error_name">{$fi.error.name}</span>
            </div>
        </div>
        <div class="row row-gutter-sm">
            <div class="form-group col mb-3">
                <input type="email" value="" class="form-control" name="email" placeholder="Введите ваш E-mail">
                <span class="error_email">{$fi.error.email}</span>
            </div>
        </div>
        <div class="row">
            <div class="form-group col mb-3">
                <textarea rows="4" class="form-control" name="message" placeholder="Сообщение"></textarea>
                <span class="error_message">{$fi.error.message}</span>
            </div>
        </div>
        <div class="row appear-animation" data-appear-animation="fadeInUpShorterPlus" data-appear-animation-delay="1500">
            <div class="form-group col mb-0">
                <button type="submit" class="btn btn-primary btn-modern font-weight-bold custom-btn-border-radius custom-btn-arrow-effect-1 text-3 px-5 py-3">
                	ОТПРАВИТЬ
                	<svg class="ms-2" version="1.1" viewBox="0 0 15.698 8.706" width="17" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    					<polygon stroke="#FFF" stroke-width="0.1" fill="#FFF" points="11.354,0 10.646,0.706 13.786,3.853 0,3.853 0,4.853 13.786,4.853 10.646,8 11.354,8.706 15.698,4.353 "/>
    				</svg>
                </button>
            </div>
        </div>
    </form>

Здесь у нас особо ничего не поменялось, единственное к элементу form я добавил дополнительные классы ajax_form af_example.

И подсветка ошибок у нас была <span class="error">{$fi.error.namePolya}</span>, стала <span class="error_namePolya">{$fi.error.namePolya}</span>.

А вызов FormIt, переписан так:

{'!AjaxForm' | snippet : [
    'snippet' => 'FormIt',
    'hooks' => 'email',
    'validate' => 'name:required:maxLength=^21^,email:email:required,message:required:minLength=^30^',
    'form' => 'contact_form',
    'emailTpl' => 'tplForm',
    'emailTo' => $_modx->config.emailsender,
    'emailFrom' => 'noretly@site.ru',
    'emailSubject' => 'Сообщение со страницы контакты на сайте ' ~ $_modx->config.site_name,
    'successMessage' => '<div class="contact-form-success alert alert-success mt-4"><strong>Успешно!</strong> Ваше сообщение отправлено нам.</div>',
    'validationErrorMessage' => '<div class="contact-form-success alert alert-danger mt-4"><strong>Ошибка!</strong> Произошла ошибка при отправке вашего сообщения.</div>'
]}

Здесь у нас тоже ничего не поменялось, теперь просто запускается AjaxForm, следом инициализируется FormIt.

Теперь у нас выводятся ошибки без каких-либо перезагрузок страниц.

Вывод ошибок

fi.successMessage и fi.validation_error_message выводятся во всплывающем окне.

Задача 2. Создать форму заказа обратного звонка в модальном окне.

Форма должна выполнять следующее:

  • сохранять данные в админке MODX;
  • поле ввода телефона должно быть по маске;
  • после успешной отправки должно выводиться сообщение: «Спасибо за обращение в нашу компанию! Менеджер свяжется с вами в ближайшее время»;
  • модальное окно после отправки формы должно закрываться.

Решение.

Т.к. верстка построена на bootstrap:

Подключение bootstrap

версии 5.2.3:

5.2.3

Можно использовать его официальную документацию (брать код различных элементов от туда), разделы modal (https://getbootstrap.com/docs/5.2/components/modal/) и forms (https://getbootstrap.com/docs/5.2/forms/overview/).

Но т.к. разработчики Porto внесли свои небольшие изменения во внешний вид, возьмем их разметку модальных окон и форм у них. Находится в файле elements-modals.html, там есть Launch Form Modal, со следующим кодом:

Launch Form Modal

Сразу перепишем ее под наши нужды, разметка кнопки у нас получается такой:

<button class="btn btn-modern btn-primary" data-bs-toggle="modal" data-bs-target="#formModal">
    Заказать звонок						
</button>

Кстати эту кнопку можно поместить в чанк с самой формой, если хотите.

Ее можно поместить в любом месте сайта вместе с вызовом аякс форм. Получается разметку модального окна и формы выносим в отдельный чанк, пусть будет modal_form:

<div class="modal fade" id="formModal" tabindex="-1" role="dialog" aria-labelledby="formModalLabel" aria-hidden="true">
	<div class="modal-dialog">
		<div class="modal-content">
			<div class="modal-header">
				<h4 class="modal-title" id="formModalLabel">Заказ звонка</h4>
				<button type="button" class="btn-close" data-bs-dismiss="modal" aria-hidden="true">×</button>
			</div>
			<form id="demo-form" class="ajax_form af_example mb-4" action="[[~[[*id]]? &scheme=`full`]]" method="post">
				<div class="modal-body">
					<div class="form-group row align-items-center">
						<label class="col-sm-3 text-start text-sm-end mb-0">Имя</label>
						<div class="col-sm-9">
							<input type="text" name="name" class="form-control" placeholder="Введите свое имя" required/>
							<span class="error_name">[[+fi.error.name]]</span>
						</div>
					</div>
					<div class="form-group row align-items-center">
						<label class="col-sm-3 text-start text-sm-end mb-0">Телефон</label>
						<div class="col-sm-9">
							<input type="text" id="phone" name="phone" class="form-control" placeholder="Укажите телефон" required/>
							<span class="error_phone">[[+fi.error.phone]]</span>
						</div>
					</div>
					[[+fi.successMessage]]
					[[+fi.validation_error_message]]
				</div>
				<div class="modal-footer">
					<button type="button" class="btn btn-light" data-bs-dismiss="modal">Закрыть</button>
					<button type="submit" class="btn btn-primary">Позвоните мне</button>
				</div>
			</form>
		</div>
	</div>
</div>

Маску ввода сделаем при помощи jQuery библиотеки maskedinput, на этом останавливаться не буду смотрите урок: Маска ввода для полей HTML форм на jQuery. А еще лучше возьмите крохотный js для маски из урока: Маска ввода телефона в input на чистом JS.

Напомню, что все input, textarea должны иметь атрибут name — это обязательно!

Делаем вызов формы. Чтобы форма начала сохранятся в админке нам нужно добавить хук FormItSaveForm, указать название формы (formName), перечислить поля, которые нужно сохранить (formFields) и названия полей (fieldNames), в итоге получаем следующий вызов.

[[!AjaxForm?
    &snippet=`FormIt`
    &hooks=`email,FormItSaveForm`
    &validate=`name:required:maxLength=^21^,phone:required:maxLength=^17^`
    &form=`modal_form`
    &emailTpl=`tplForm`
    &fromName=`Заказ звонка`
	&formFields=`name,phone`
	&fieldNames=`name==Имя,phone==Телефон`
    &emailSubject=`Заказ звонка с сайта [[++site_name]]`
    &emailTo=`[[++emailsender]]`
    &emailFrom=`noretly@[[++base_url]]`
    &successMessage=`<p class="h4 text-white">Спасибо за обращение в нашу компанию! <br>Менеджер свяжется с вами в ближайшее время</p>`
]]

AjaxForm на fenom

Чанк с формой на fenom.

<div class="modal fade" id="formModal" tabindex="-1" role="dialog" aria-labelledby="formModalLabel" aria-hidden="true">
	<div class="modal-dialog">
		<div class="modal-content">
			<div class="modal-header">
				<h4 class="modal-title" id="formModalLabel">Заказ звонка</h4>
				<button type="button" class="btn-close" data-bs-dismiss="modal" aria-hidden="true">×</button>
			</div>
			<form id="demo-form" class="ajax_form af_example mb-4" action="{$_modx->makeUrl($_modx->resource.id, '', '', 'full')}" method="post">
			    <div class="modal-body">
					<div class="form-group row align-items-center">
						<label class="col-sm-3 text-start text-sm-end mb-0">Имя</label>
						<div class="col-sm-9">
							<input type="text" name="name" class="form-control" placeholder="Введите свое имя" required/>
							<span class="error_name">{$fi.error.name}</span>
						</div>
					</div>
					<div class="form-group row align-items-center">
						<label class="col-sm-3 text-start text-sm-end mb-0">Телефон</label>
						<div class="col-sm-9">
							<input type="text" name="phone" class="tel form-control" placeholder="Укажите телефон" required/>
							<span class="error_phone">{$fi.error.phone}</span>
						</div>
					</div>
    				{$fi.successMessage}
    				{$fi.validation_error_message}
    			</div>
    			<div class="modal-footer">
    				<button type="button" class="btn btn-light" data-bs-dismiss="modal">Закрыть</button>
    				<button type="submit" class="btn btn-primary">Позвоните мне</button>
    			</div>
			</form>
		</div>
	</div>
</div>

Вызов формы на fenom.

{'!AjaxForm' | snippet : [
    'snippet' => 'FormIt',
    'hooks' => 'email,FormItSaveForm',
    'validate' => 'name:required:maxLength=^21^,phone:required:maxLength=^17^',
    'form' => 'modal_form',
    'emailTpl' => 'tplForm',
    'fromName' => 'Заказ звонка',
	'formFields' => 'name,phone',
	'fieldNames' => 'name==Имя,phone==Телефон',
    'emailSubject' => 'Заказ звонка с сайта ' ~ $_modx->config.site_name,
    'emailTo' => $_modx->config.emailsender,
    'emailFrom' => 'noretly@site.ru',
    'successMessage' => '<p class="h4 text-white">Спасибо за обращение в нашу компанию! <br>Менеджер свяжется с вами в ближайшее время</p>',
]}

Финальный штрихи

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

<p><strong>Имя</strong>: {$name}</p> 
{if $phone?}<p><strong>Телефон</strong>: {$phone}</p>{/if}
{if $email?}<p><strong>Почта</strong>: <a href="mailto:{$email}">{$email}</a></p>{/if} 
{if $message?}<p><strong>Сообщение</strong>: {$message}</p>{/if}
тоже самое на fenom:
<p><strong>Имя</strong>: [[+name]]</p>
[[+phone:!empty=`<p><strong>Телефон</strong>: [[+phone]]</p>`]]
[[+email:!empty=`<p><strong>Почта</strong>: [[+email]]</p>`]]
[[+message:!empty=`<p><strong>Сообщение</strong>: [[+message]]</p>`]]

Не проверяю на пустоту только имя, т.к. оно используется во всех формах и везде оно обязательное для заполнения.

Ну и осталось добавить пару строк js, чтобы окно закрывалось, об этом информация ниже.

Тестируем, пробуем заполнить и отправить:

Тест формы

И данные падают в админку Пакеты — Formit

Данные формы в админке

Задача 3. Продвинутая форма с вложениями при помощи Formit + AjaxForm

Будем создавать вот такую форму.

Продвинутая форма с вложениями при помощи Formit + AjaxForm

По сути она достаточно простая. но ее особая особенность. это вложения.

И так. данная форма имеет, вот такой html код:

<form class="ajax_form" method="post" action="" enctype="multipart/form-data">
 <fieldset>
  <div class="row"> 
   <div class="col-sm-4">  
    <div class="fancy-form">
	<i class="fa fa-user"></i>
	<input type="text" name="name" required="" class="form-control" placeholder="Ваше имя*" value="">
    </div>
   </div>
   <div class="col-sm-4"> 
    <div class="fancy-form">
	<i class="fa fa-at"></i>
	<input type="text" name="email" required="" class="form-control" placeholder="Ваш email*" value="">
    </div>
   </div>
   <div class="col-sm-4"> 
    <div class="fancy-form">
	<i class="fa fa-phone"></i>
	<input type="text" class="form-control" id="pfone" name="pfone" required="" placeholder="Ваш телефон*" value="">
    </div>
   </div>
  </div>
  <div class="fancy-form bottom-21">
	<select class="form-control pointer" name="department">
		<option value="">--- Выберите тип работы ---</option>
		<option value="Разработка-сайта-под-ключ">Разработка сайта под ключ</option>
		<option value="Доработка-сайта">Доработка сайта</option>
		<option value="Адаптация-имеющегося-сайта">Адаптация имеющегося сайта</option>
		<option value="Разработка-верстка-дизайна-сайта">Разработка/верстка дизайна сайта</option>
		<option value="Продвижение-сайта">Продвижение сайта</option>
		<option value="Рекламные-компании">Рекламные компании</option>
		<option value="Разработка-дизайна-групп">Разработка дизайна групп</option>
		<option value="Продвижение-групп">Продвижение групп</option>
		<option value="Прочее">Прочее</option>
	</select>
  </div>
  <div class="fancy-form bottom-21">
	<textarea rows="5" name="message" required="" class="form-control word-count" data-maxlength="2000" data-info="textarea-words-info" placeholder="Примечания / пожелания"></textarea>
	<i class="fa fa-comments"><!-- icon --></i>
 	<span class="error error_name"></span>
  </div>
  <div class="input-group file-upload w100">
  <div class="input-group"><span class="input-group-addon"><i class="fa fa-paperclip"></i></span><input class="custom-file-upload custom-file-upload-hidden" placeholder="Ваше задание, методичка и т.д.*" type="file" id="file" name="attachment" data-btn-text="Выберите файл" tabindex="-1" style="position: absolute; left: -9999px;"><input type="text" class="form-control file-upload-input text-left"><span class="input-group-btn" tabindex="-1"><button type="button" class="file-upload-button btn btn-primary">Выберите файл</button></span></div>
  </div>
</fieldset>
<button type="submit" class="btn btn-3d btn-xmg btn-primary btn-w100">Отправить</button>
</form>

По сути обычная немного модифицированная bootstrap разметка.

Обязательный атрибут для использования вложений в MODX: enctype=»multipart/form-data»

Ну а теперь ближе к делу:

Создаем чанк, ну к к примеру form-uslugi и помещаем в него весть вышеприведенный код, далее модифицируем его под Formit + AjaxForm, получаем:

<form method="post" action="[[~[[*id]]]]" enctype="multipart/form-data">
    <fieldset>
        <div class="row"> 
            <div class="col-sm-4">  
                <div class="fancy-form">
                	<i class="fa fa-user"></i>
                	<input type="text" name="name" required="" class="form-control" placeholder="Ваше имя*" value="[[+fi.name]]">
                	<span class="error error_name">[[+fi.error.name]]</span>
                </div>
            </div>
            <div class="col-sm-4"> 
                <div class="fancy-form">
                	<i class="fa fa-at"></i>
                	<input type="text" name="email" required="" class="form-control" placeholder="Ваш email*" value="[[+fi.email]]">
                	<span class="error error_name">[[+fi.error.email]]</span>
                </div>
            </div>
            <div class="col-sm-4"> 
                <div class="fancy-form">
                	<i class="fa fa-phone"></i>
                	<input type="text" class="form-control" id="pfone" name="pfone" required="" placeholder="Ваш телефон*" value="[[+fi.pfone]]">
                	<span class="error error_name">[[+fi.error.pfone]]</span>
                </div>
            </div>
        </div>
        <div class="fancy-form bottom-21">
        	<select class="form-control pointer" name="department">
        		<option value="">--- Выберите тип работы ---</option>
        		<option value="Разработка-сайта-под-ключ">Разработка сайта под ключ</option>
        		<option value="Доработка-сайта">Доработка сайта</option>
        		<option value="Адаптация-имеющегося-сайта">Адаптация имеющегося сайта</option>
        		<option value="Разработка-верстка-дизайна-сайта">Разработка/верстка дизайна сайта</option>
        		<option value="Продвижение-сайта">Продвижение сайта</option>
        		<option value="Рекламные-компании">Рекламные компании</option>
        		<option value="Разработка-дизайна-групп">Разработка дизайна групп</option>
        		<option value="Продвижение-групп">Продвижение групп</option>
        		<option value="Прочеее">Прочеее</option>
        	</select>
        </div>
        <div class="fancy-form bottom-21">
        	<textarea rows="5" name="message" required="" class="form-control word-count" data-maxlength="2000" data-info="textarea-words-info" placeholder="Примечания / пожелания"></textarea>
        	<i class="fa fa-comments"><!-- icon --></i>
        	<span class="error error_name">[[+fi.error.message]]</span>
        </div>
        <div class="input-group file-upload w100">
        <input class="custom-file-upload custom-file-upload-hidden" type="file" id="file" name="attachment" data-btn-text="Выберите файл" tabindex="-1" style="position: absolute; left: -9999px;">
        </div>
    </fieldset>
<button type="submit" class="btn btn-3d btn-xmg btn-primary btn-w100">Отправить</button>
[[+fi.success:is=`1`:then=`
<div class="alert alert-success">[[+fi.successMessage]]</div>`]]
[[+fi.validation_error:is=`1`:then=`<div class="alert alert-error">[[+fi.validation_error_message]]</div>`]]
</form>

Далее создаем 2й чанк tpl-form-uslugi, со следующим содержимым

<p>Имя: [[+name]]</p>
<p>Email: [[+email]]</p>
<p>Телефон: [[+pfone]]</p>
<p>Тип работы: [[+department]]</p>
<p>Сообщение: [[+message]]</p>
<p>Файл: [[+attachment]]</p>

Можно вообще сделать для всех форм универсальный обработчик, при помощи модификаторов, вот пример универсального обработчика на fenom:

{if $name?}<p><strong>Имя:<strong>:{$name}</p>{/if}
{if $email?}<p><strong>E-mail:<strong>:{$email}</p>{/if}
{if $pfone?}<p><strong>Телефон:<strong>:{$pfone}</p>{/if}
{if $department?}<p><strong>Тип работы:<strong>:{$department}</p>{/if}
{if $message?}<p><strong>Сообщение:<strong>:{$message}</p>{/if}
{if $attachment?}<p><strong>Файл:<strong>:{$attachment}</p>{/if}

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

Ну и остается лишь только вызвать эту форму в нужном месте.

[[!AjaxForm?
&snippet=`FormIt`
&form=`form-uslugi`
&emailTpl=`tpl-form-uslugi`
&hooks=`spam,email`
&emailSubject=`Сообщение с сайта [[++site_url]]`
&emailTo=`mail@webadaptiv.ru`
&validate=`name:required,email:required`
&validationErrorMessage=`В форме содержатся ошибки!`
&successMessage=`Сообщение успешно отправлено!`
]]

Ну и проверяем работоспособность.

проверяем работоспособность форм

Плюшки

Закрываем модальное окно после отправки формы

Нам нужна кнопка закрытия, в моем случае

<button type="button" class="close" data-dismiss="modal" aria-label="Close">
   <span aria-hidden="true">×</span>
</button>

cм. bootstrap modal.

модальное окно

Так вот нам нужен класс элемента, который закрывает форму при клике, в моем случае это кнопка (buttom) с классом close.

Воспользуемся событием af_complete для клика по этой кнопке.

$(document).on('af_complete', function(event,res) {
	if(res.success) $('.close').click();
});

К стати его нужно прописывать в js файл или подключать в шаблон обвертывая в тег <script> </script>

оборачиваем событие в script

Все теперь после успешной отправки письма, модальное окно автоматически закроется.

Изменение стилей и положения всплывающего окна Ajaxform.

AjaxForm для стилизации окон использует стили jGrowl, которые лежат в assets/components/ajaxform/css/lib/jquery.jgrowl.min.css, можно поправить все прямо там, но если вы обновите компонент, то и стили ваши обновятся на дефолтные, следовательно их лучше предопределить в своем css.

К примеру положение окна по дефолту заданно вот таким стилем

.jGrowl.top-right{top:0;right:0}

те прижато к верху и правой стороне.

Чтобы сменить положение, к примеру по центру, достаточно предопредилить их в своем css, к примеру так:

.jGrowl.top-right{top:40% !important;width:30% !important;left:35% !important}

И точно таким же образом можно изменить весь внешний вид окошко с уведомлением, вот мой конечный код для одного из сайтов:

#jGrowl{font-size:18px;margin:0 12px}
.jGrowl.top-right{left:35%!important;top:35%!important}
#jGrowl .jGrowl-notification{position:relative;width:320px;padding:15px;text-align:center;background:none repeat 0 0 #fff!important;box-shadow:0 0 0 7px #8ab933!important;border:0 solid rgba(255,255,255,0.49)!important}
#jGrowl .jGrowl-notification .jGrowl-close{position:absolute;right:4px;top:4px;color:#8ab933!important}
#jGrowl .jGrowl-notification .jGrowl-message{color:#8ab933!important}

в итоге всплывает вот такое окошко по центру сайт.

новый вид уведомляшки в аякс форм

Оптимизация скорости загрузки сайта. 

  1. Делайте вызов Ajaxform кэшированным (без !).
  2. Объедините стандартные стили и скрипты со своими и укажите в вызове чтобы стандартные не подключались.

Берем CSS код из assets/components/ajaxform/css/lib/jquery.jgrowl.min.css,  assets/components/ajaxform/css/default.css и переносим его в общий файл стилей.

объединяем стили

default.css — из этого файла выкидываем верхнюю строку @import url(‘./lib/jquery.jgrowl.min.css’); — т.к. код мы подключили сразу.

Также берем содержимое файла assets/components/ajaxform/js/default.js и объединяем с основным js файлом.

Далее отключаем css и js в вызове ajaxform.

&frontend_css=«
&frontend_js=«

{'!AjaxForm' | snippet : [
    'snippet' => 'FormIt',
    'form' => 'obr-zvonok',
    'emailTpl' => 'tpl-form',
    'hooks' => 'email,FormItSaveForm',
    'emailFrom' => $_modx->config.emailsender,
    'fromName' => 'Заказ звонка',
	'formFields' => 'name,phone',
	'fieldNames' => 'name==Имя,phone==Телефон',
    'emailSubject' => 'Сообщение с сайта' ~ $_modx->config.site_name,
    'emailTo' => $_modx->config.emailsender,
    'successMessage' => '<p class="h4">Спасибо за обращение в нашу компанию! <br>Менеджер свяжется с вами в ближайшее время</p>',
    'frontend_css' => '',
    'frontend_js' => ''
]}

redirect на другую страницу сайта, после успешной отправки формы?

Добавляем id к форме, если его нет и затем в js файл прописать вот такие строки

$(document).on('af_complete', function(event, response) {
    var form = response.form;
    if (form.attr('id') == 'значение id формы') {
       window.location.href = "[[~id страницы]]"
    }
});

Можно просто обернуть в <script>выше приведенный код</script> и подключить в шаблон с формой ближе к закрытию body.

Настройка отправки целей в AjaxForm

Самый простой и удобный способ настроить цели на AjaxForm это добавить в сообщение успешной отправки script

&successMessage=`Сообщение успешно отправлено
                 <script>ga('send', 'event', 'plea', 'button_ok');
                 yaCounterXXXXXXXX.reachGoal('zayavka');</script>`

Как передать адрес и заголовок страницы

<a href="{$pageId | url}">{$pageId | resource : 'pagetitle'}</a>

Если полный адрес не выводится, попробуйте так

<a href="{$pageId | url : ['scheme' => 'full']}">{$pageId | resource : 'pagetitle'}</a>

Чекбокс — согласие с политикой обработки персональных данных

<div class="checkbox">
    <label>
      <input type="checkbox" required checked> Согласен на <a href="/polici" target="_blank">обработку персональных данных</a>
    </label>
</div>

Дополнительно

Сохранение форм в админке, добавление маски ввода для телефона, email, даты идентично formit.

Смотрите также:

Google reCAPTCHA(v2) для FormIt и AjaxForm

Как в MODX Revo избавиться от спама с FormIt, AjaxForm (без капч)

MODX CSRFHelper — защита форм FormIt и AjaxForm от CSRF атак.

В следующем уроке сделаем, познакомимся с дополнением PdoTools и начнем изучать его сниппеты.

Поделиться с друзьями
Алексей

Веб-дизайнер и SEO оптимизатор. Занимаюсь созданием сайтов с 2010 года и их продвижение с 2012 года!

Оцените автора
( 6 оценок, среднее 5 из 5 )
Web-Revenue.ru
Добавить комментарий

  1. Mmash

    Здравствуйте.
    Лишнюю кавычку уберите, пожалуйста:
    Имя: [[+name]]`]]
    Ещё в этой форме нужно местами поменять fenom и не_fenom, если ещё актуально.

    И вопрос без особой надежды на ответ, но вдруг мне повезет…
    Для сквозного модального окна action=»[[~[[*id]]? &scheme=`full`]]» работает не на всех страницах, action=»[[~[[*id]]]]» тоже не на всех.
    На страницах с адресами типа news/ выкидывает из формы без уведомлений. На страницах с адресами типа /contact.html всё отлично.
    Подскажите, пожалуйста, есть ли универсальный рецепт?

    Ответить
    1. Алексей автор

      Лишнюю кавычку убрал — спасибо за замечание.
      Ответ на ваш вопрос: [[~[[*id]]? &scheme=`full`]] должно работать везде, а по поводу того что выкидывает из формы, у вас скорее всего нет тега в head base href="". Если он есть посмотрите нормально протокол генерит или нет. Так же если base есть, возможно нужно создать плагин для якорных ссылок https://web-revenue.ru/modx-revo/yakornyie-ssyilki.

      Ответить
      1. Mmash

        Спасибо огромное!!!
        Проверила. Нашла примитивнейшую ошибку — в шаблонах проблемных страницах не было закрывающих ,
        Если можно, ещё одно замечание — по поводу name:required:maxLength=^21^
        Если пользователи Санёк и Настя, они вполне поместятся в 21 символ, а если Воскобойников Александр Вениаминович и Александрова Анастасия Александровна, им нужно каждому по 38 символов.

        И в примере написано:
        …тоже самое на fenom:
        Имя: [[+name]]
        [[+phone:!empty=`Телефон: [[+phone]]`]]…
        Насколько я понимаю, fenom выше с фигурными скобками, а это тоже самое уже не феном, поэтому куски кода надо поменять местами.
        Но, может быть, я затупила и не понимаю чего-то. Извините, если так.

        Очень вам признательна. Впервые взялась за MODX. С точки зрения СЕО, насколько я вижу, MODX на сегодняшний день один из лучших.
        По вашим урокам собираю сайт с небольшим функционалом. Понятно, логично, приятно разбираться. Очень здорово всё изложено! Спасибище!!!

        Ответить
        1. Алексей автор

          Сейчас в основном все ленивые и врятли кто будет ФИО целиком вводить, обычно просто имя пишут, ну а так никто вам не мешает увеличить количество вводимых символов.
          Весь код где квадратные скобки — это modparser, где фигурные — это fenom (в идеале их лучше не мешать, пишите на чем то одном).

          Ответить
  2. Аноним

    а не подскажите почему письма с сайта приходят без кодировки, т.е. вместо кириллицы кваказябры. хотя везде стоит utf-8 на сайте. исходящая почта того же домена что и сайт. спасибо

    Ответить
  3. Аноним

    кодировка utf-8 не работает в чем причина именно на ajax когда отправляю сообщение

    Ответить
  4. WilliamPak

    I am regular reader, how are you everybody? This post posted at this website is really good.

    Ответить
    1. Алексей автор

      Everything is good) I’m glad that you read me, I try to write comprehensive articles)

      Ответить
  5. Антон

    Алексей, сможете помочь (платно) починить форму на AjaxForm / FormIt на сайте? Не можем добиться ее работы никак… все по вашей инструкции написали…

    Ответить
    1. Алексей автор

      Здравствуйте. Написал на email

      Ответить
  6. Сергей

    Доброй ночи. Скажите для чего прописывать aria-describedby в формах?
    Заранее спасибо

    Ответить
    1. Алексей автор

      Здравствуйте. https://developer.mozilla.org/ru/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-describedby_attribute

      Ответить