Добавить в корзинуПозвонить
Найти в Дзене
Хроники Веба

Frontend Code-Form Builder (FCFB) - пример создания формы добавления записи (post)

Пример создания простой фронтенд формы публикации записи. Публиковать могут как авторизованные, так и анонимы. Фома позволяет только публиковать записи без возможности редактирования. В дальнейшем я буду добавлять еще различные примеры создания форм: публикации с фронтенда, в админке, страницы настроек, фильтры товаров, контактные формы, формы бронирования, регистрации и авторизации, многоступенчатые формы, с зависимыми списками, динамические ajax формы, формы в модальных окнах и т.д. Плагин предназначен только для создания форм, внешнего оформления и интерактива полей и не отвечает за сохранение и заполнение сохраненных данных, что с одной стороны является недостатком для людей не умеющих программировать, а с другой преимуществом для разработчиков. На основе данного примера мы разберем: 1. создание полей и вывод формы через шорткод 2. валидация полей на клиенте и на сервере 3. сохранение данных формы, т.е. это создание новой записи. 4. Инструкции по заполнению полей формы тут не буде
Оглавление

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

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

На основе данного примера мы разберем:

1. создание полей и вывод формы через шорткод

2. валидация полей на клиенте и на сервере

3. сохранение данных формы, т.е. это создание новой записи.

4. Инструкции по заполнению полей формы тут не будет, так как в примере нет редактирования записи.

По поводу валидции полей на клиенте: по сути если есть серверная, то на клиенте она просто не нужна, так как выглядит внешне это все одинаково, но для облегчения нагрузки на сервер, скорости отображения ошибок и вообще в качестве документации, я покажу как ее реализовать. Просто сама по себе она работать на форонтенде не будет, даже несмотря, но то, что у поля указаны 'required' => true. Автоматическая клиентская валидация работает только для полей в админке, когда не создается форма с нуля, а создаются только поля для уже существующих форм добавления типов записей, таксономий, пользователей, виджетов, настроек меню, комментариев.

Шорткод для вывода формы: [fcfb_form id="demo5" reset_template="1"]

Создание полей формы

add_filter('fcfb_form__demo5', 'demo5_form', 10, 2);
function demo5_form($args)
{
$args[] = [
'type' => 'container',
'label' => 'Добавить запись в блог',
'id' => 'addpost',
'fields' => [
[
'type' => 'text',
'id' => 'post_name',
'label' => 'Название записи',
'required' => true,
'min' => 4,
'max' => 100,
],
[
'type' => 'textarea',
'id' => 'post_content',
'label' => 'Описание записи',
'required' => true,
'ww' => '100%',
'min' => 20,
'max' => 10000,
],
[
'type' => 'multiselect',
'id' => 'categories',
'label' => 'Категория',
'source' => 'taxonomy',
'max' => 2,
'required' => true,
'query' => [
'taxonomy' => 'category',
'hide_empty' => false,
'exclude' => [1], //исключаем "без рубрики"
],
],
[
'type' => 'math_captcha',
'id' => 'code',
'label' => 'Ответ на вопрос',
],
[
'type' => 'checkbox',
'after' => 'Ознакомлен с политикой безопасности в отношении обработки персональных данных',
'id' => 'privacy_policy',
'required' => true,
'sw' => 3,
'ww' => '100%',
],
[
'type' => 'submit',
'id' => 'btn',
//деактивируем кнопку пока не будет отмечена галочка политики
'conditions' => [
'logic' => 'disabled',
'or' => [['rules' => [['id' => 'privacy_policy', 'values' => ['1'], 'compare' => '=']]]],
],
],
],
];
return $args;
}

Валидация полей на клиенте + скролл к первому полю с ошибкой

function my_custom_footer_script()
{
?>
<script>
jQuery(function($) {
//проверка полей форм до отправки ajax запроса
function noticeField(formData, event) {
const $form = $(event.currentTarget);
//проверка есть ли поля с ошибками
if(fcfb.submit.validFields($form)) {
//если ошибки есть, то скролл к первому полю с ошибкой
fcfb.submit.scrollNoticeField($form);
//блокируем ajax отправку данных на сервер
return false;
}
return formData;
}
fcfb.addFilter('fcfbAjaxSubmitBefore_demo5', function(formData, event) {
return noticeField(formData, event);
});
});
</script>
<?php
}
add_action('wp_footer', 'my_custom_footer_script');

Валидация на сервере и публикация поста

function fcfb_action_demo5_action()
{
if (empty(fcfb_post()['demo5'])) {
exit();
}
check_ajax_referer('demo5', 'fcfb-nonce');
$fields = fcfb_post()['demo5'];
//обновление каптчи
$output['math_captcha_refresh'] = fcfb_math_captcha_refresh('medium', 100, 30);
if ($n2 = fcfb_v_required($fields['post_name'], 'Название записи')) {
$output['errorFields']["[post_name]"] = $n2;
} else {
$n2 = fcfb_v_length($fields['post_name'], 4, 100, 'Название записи');
if ($n2) {
$output['errorFields']["[post_name]"] = $n2;
}
}
if ($n3 = fcfb_v_required($fields['post_content'], 'Описание записи')) {
$output['errorFields']["[post_content]"] = $n3;
} else {
$n4 = fcfb_v_length($fields['post_content'], 20, 10000, 'Описание записи');
if ($n4) {
$output['errorFields']["[post_content]"] = $n4;
}
}
if ($n5 = fcfb_v_required($fields['categories'][0], 'Категория')) {
$output['errorFields']["[categories][]"] = $n5;
} else {
$n6 = fcfb_v_array_count($fields['categories'], 1, 2, 'Категория');
if ($n6) {
$output['errorFields']["[categories][]"] = $n6;
}
}
if ($n7 = fcfb_v_required($fields['code']['user_answer'], 'Ответ на вопрос')) {
$output['errorFields']["[code][user_answer]"] = $n7;
} else {
$n8 = fcfb_validate_math_captcha($fields['code']);
if ($n8) {
$output['errorFields']["[code][user_answer]"] = $n8;
}
}
//если есть ошибки валидации, отправляем их и прекращаем выполнение
if (!empty($output['errorFields'])) {
//скролл к первому полю с ошибкой
$output['scrollField'] = [
'delay' => 100,
'top' => 200,
];
exit(json_encode($output));
}
//если ошибок нет, то добавляем пост
// 1. Очищаем и подготавливаем данные для безопасности
$post_title = sanitize_text_field($fields['post_name']);
$post_content = sanitize_textarea_field($fields['post_content']);
$post_categories = array_map('intval', array_filter((array) $fields['categories']));
// 2. Собираем массив данных для создания поста
$post_data = [
'post_title' => $post_title,
'post_content' => $post_content,
'post_category' => $post_categories, // Массив ID категорий
'post_status' => 'pending', // Статус "на рассмотрении".
'post_author' => 1, // ID автора, по умолчанию это админ
'post_type' => 'post', // Тип записи (стандартный пост)
];
// 3. Вставляем пост в базу данных
$new_post_id = wp_insert_post($post_data, true);
// 4. Проверяем, не произошла ли ошибка при добавлении
if (is_wp_error($new_post_id)) {
// Если произошла ошибка, отправляем уведомление об этом над формой
$output['noticesForm'] = [
[
'content' => $new_post_id->get_error_message(),
'type' => 'error',
],
];
exit(json_encode($output));
}
// Если пост успешно создан, отправляем позитивный ответ
//восстанавливаем форму в первоначальное состояние
$output['reset'] = 100;
//выводим уведомление в попапе
$output['popup'] = [
'id' => 'add_result',
'content' => 'Запись успешно отправлена на проверку!',
];
//удаление уведомлений над формой (если ранее была ошибка)
$output['noticesFormRemove'] = 100;
exit(json_encode($output));
}
add_action('wp_ajax_fcfb_action_demo5', 'fcfb_action_demo5_action');
add_action('wp_ajax_nopriv_fcfb_action_demo5', 'fcfb_action_demo5_action');