В данной статье я на примере AJAX формы обратной связи расскажу как реализовать AJAX в CMS MODx Revolution. Для этого нам необходимо создать ресурс с пустым шаблоном, в настройках которого необходимо отключить визуальный редактор и убрать чекбокс «Доступен для поиска».
В содержимом ресурса мы вызываем сниппет, который нам отдаст результат. Это может быть pdoResources, getResources и т.д. В нашем случае, у нас будет следующий вызов FormIt:
[ [!FormIt? &hooks=`spam,math,email,FormItSaveForm` &emailTpl=`zayChunk` &emailSubject=`Вам сообщение с сайта artemblog.ru` &emailTo=`info@artemblog.ru` &formName=`Заявка` &mathMinRange=`1` &mathMaxRange=`10` &formName=`Обратная связь` &validate=`math:required` ] ][ [!+fi.error.math] ]
Так как на сайте у меня используется Bootstrap, я вывожу данную форму в модальном окне. Код модального окна:
<!-- Modal --> <div class="modal fade" id="consult" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> <div class="modal-dialog" role="document"> <div class="modal-content"> <form action="[ [~112] ]" method="POST" id="consultform"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title" id="myModalLabel">Получить консультацию</h4> </div> <div class="modal-body"> <div class="message"></div> <div class="form-group"> <label for="email">Ваше имя</label> <input type="text" class="form-control" id="name" name="name" placeholder="Имя" required> </div> <div class="form-group"> <label for="email">Ваш email</label> <input type="email" class="form-control" id="email" name="email" placeholder="Email" required> </div> <div class="form-group"> <label for="phone">Ваш телефон</label> <input type="text" class="form-control phone" id="phone" name="phone" placeholder="Телефон" required> </div> <div class="form-group"> <label for="text">Текст</label> <textarea name="text" class="form-control"></textarea> </div> <div class="form-group"> <label>Решите пример - [ [!+fi.op1] ] [ [!+fi.operator] ] [ [!+fi.op2] ]?</label> [ [!+fi.error.math] ] <input class="form-control" type="text" name="math" value="" /> <input type="hidden" name="op1" value="[ [!+fi.op1] ]" /> <input type="hidden" name="op2" value="[ [!+fi.op2] ]" /> <input type="hidden" name="operator" value="-" /> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Закрыть</button> <button type="submit" class="btn btn-primary">Отправить</button> </div> </form> </div> </div> </div>
И еще нам необходим скрипт обработки, у меня он написан на jQuery:
$(document).ready(function(){ $('#consultform').submit(function(e){ e.preventDefault(); var msg = $(this).serialize(); var url = $(this).attr('action'); $.ajax({ type: "POST", url: url, data: msg, success: function(data) { if (data){ $('#consult .message').html('<div class="alert alert-danger" role="alert">'+data+'</div>'); }else{ $('#consult .message').html('<div class="alert alert-success" role="alert">Сообщение отправлено!</div>'); } } }); return false; }); })
Данная конструкция должна работать, если вы все верно разместите в шаблоне. В принципе, MODx очень гибок, и можно делать с данной системой все, что душа пожелает.
В меню кнопкой «оставить заявку» открывается модальное окно Bootstrap, внутри которого форма ajax
Имею следующее:
1. модалку кнопкой вызываю
2. при заполнении формы (правильно/неправильно, все едино..) и отправке кнопкой «отправить» тупо закрывается модальное окно…
Нужно:
чтобы валидация формы происходила внутри открытого модального окна (если поля содержат ошибку – соответствующее сообщение выводилось, но модалка не закрывалась при этом, если все заполнено верно – отправка осуществлялась и выводилось сообщение об успехе отправки, опять же не закрывая модалки. Модалку можно было бы закрыть только вручную кнопкой «Х», либо по прошествии 2 минут – автоматически….
Что делаю не так ?! поможите, люди добрые… Где что менять для получения требуемого?
Вызов модального окна с формой
[[pdoMenu? &parents=`0` &level=`2` &outerClass=`navbar-nav me-auto mb-2 mb-lg-0` &tpl=`@INLINE
[[+menutitle]][[+wrapper]]` &rowClass=`nav-item` &parentClass=`dropdown` &tplParentRow=`@INLINE
[[+menutitle]]
[[+wrapper]]
` &tplInner=`@INLINE [[+wrapper]]` ]]
[[$tel]] оставить заявку
форма заявки
[[!AjaxForm? &form=`tpl.AjaxForm` &snippet=`FormIt` &hooks=`spam,FormItSaveForm,email,redirect`
&emailSubject=`Вам сообщение с сайта [[++site_name]]` &emailTo=`biper@yandex.ru` &emailFrom=`mail@yandex.ru`
&emailTpl=`tpl.email` &validate=`name:required,email:required,message:required`
&validationErrorMessage=`В форме содержатся ошибки!` &successMessage=`Ваше сообщение успешно отправлено` ]]
Содержимое чанка tpl.AjaxForm
Представьтесь, пожалуйста
[[+fi.error.name]]
Эл. почта для связи
[[+fi.error.email]]
Телефон для связи
[[+fi.error.tel]]
Опишите Вашу задачу
[[+fi.message]]
[[+fi.error.message]]
[[+fi.error.message]]
Очистить форму
Отправить сообщение
[[+fi.success:is=`1`:then=`
[[+fi.successMessage]]
`]] [[+fi.validation_error:is=`1`:then=`
[[+fi.validation_error_message]]
`]]
[[$warning]]
Содержимое сниппета AjaxForm
loadClass(‘ajaxform’, MODX_CORE_PATH . ‘components/ajaxform/model/ajaxform/’, false, true)) {
return false;
}
$AjaxForm = new AjaxForm($modx, $scriptProperties);
$snippet = $modx->getOption(‘snippet’, $scriptProperties, ‘FormIt’, true);
$tpl = $modx->getOption(‘form’, $scriptProperties, ‘tpl.AjaxForm.example’, true);
$formSelector = $modx->getOption(‘formSelector’, $scriptProperties, ‘ajax_form’, true);
$objectName = $modx->getOption(‘objectName’, $scriptProperties, ‘AjaxForm’, true);
$AjaxForm->loadJsCss($objectName);
/** @var pdoTools $pdo */
if (class_exists(‘pdoTools’) && $pdo = $modx->getService(‘pdoTools’)) {
$content = $pdo->getChunk($tpl, $scriptProperties);
} else {
$content = $modx->getChunk($tpl, $scriptProperties);
}
if (empty($content)) {
return $modx->lexicon(‘af_err_chunk_nf’, array(‘name’ => $tpl));
}
// Add selector to tag form
if (preg_match(‘#<form.*?class=(?:"|\')(.*?)(?:"|\')#i', $content, $matches)) {
$classes = explode(' ', $matches[1]);
if (!in_array($formSelector, $classes)) {
$classes[] = $formSelector;
$classes = preg_replace(
'#class=(?:"|\')' . $matches[1] . '(?:"|\')#i',
'class="' . implode(' ', $classes) . '"',
$matches[0]
);
$content = str_ireplace($matches[0], $classes, $content);
}
} else {
$content = str_ireplace('<form', '<form class="' . $formSelector . '"', $content);
}
// Add method = post
if (preg_match('#<form.*?method=(?:"|\')(.*?)(?:"|\')#i', $content)) {
$content = preg_replace('#<form(.*?)method=(?:"|\')(.*?)(?:"|\')#i', '<form\\1method="post"', $content);
} else {
$content = str_ireplace('<form', '<form method="post"', $content);
}
// Add action for form processing
$hash = md5(http_build_query($scriptProperties));
$action = '’;
if ((stripos($content, ») !== false)) {
if (preg_match(‘##i’, $content, $matches)) {
$content = str_ireplace($matches[0], », $content);
}
$content = str_ireplace(», «\n\t$action\n», $content);
}
// Save settings to user`s session
$_SESSION[‘AjaxForm’][$hash] = $scriptProperties;
// Call snippet for preparation of form
$action = !empty($_REQUEST[‘af_action’])
? $_REQUEST[‘af_action’]
: $hash;
$AjaxForm->process($action, $_REQUEST);
// Return chunk
return $content;
сниппет FormIt
initialize($modx->context->get(‘key’));
$fi->loadRequest();
$fields = $fi->request->prepare();
return $fi->request->handle($fields);