Приветствую!
Данная публикация предназначена в первую очередь разработчикам дополнений к плагину WP-Recall и предполагает наличие у читателя знания основ php и javascript. Публикация актуальна для плагина версии 16.17.0.
Очень часто при разработке какого то функционала разработчикам приходится сталкиваться с вопросом приема и отправки данных с произвольных форм. Эта, в общем то, рутинная операция включает в себя множество этапов и нюансов в плане реализации. Но мало кто знает, что плагин WP-Recall позволяет решать эту задачу с помощью встроенного API для работы с формами. В этой заметке мы рассмотрим несколько примеров, которые позволят упростить и ускорить процесс разработки за счет использования доступных инструментов плагина WP-Recall.
Создание простой формы
В общем то, все начинается с этапа создания какой то формы. В ранее опубликованной статье "Подробно о произвольных полях WP-Recall" я подробно описывал принцип работы с произвольными полями плагина и также затронул там вопрос о создании с помощью них некой формы, которая способна принимать данные пользователя и отправлять их куда следует. Сейчас мы пойдем немного дальше.
Как вы уже наверное догадались, мы будем строить форму именно на основе функционала произвольных полей плагина. Создадим массив полей:
$fields = array( array( 'type' => 'text', 'slug' => 'field_one', 'title' => __('Текстовое поле'), 'placeholder' => __('Заполните это поле'), 'required' => 1, 'notice' => __('тут какое то примечание к полю') ), array( 'type' => 'select', 'slug' => 'field_two', 'title' => __('Выпадающий список'), 'values' => array( __('один'), __('два'), __('три') ), 'notice' => __('выберите одно из значений') ), array( 'type' => 'textarea', 'slug' => 'field_three', 'title' => __('Многострочное поле'), 'placeholder' => __('Напишите хоть что то...'), 'required' => 1, 'notice' => __('еще одно примечание к текстовому полю') ), array( 'type' => 'hidden', 'slug' => 'my_form_submit', 'value' => 1 ) );
В созданном массиве перечислены нужные нам произвольные поля с необходимыми настройками, всего четыре поля, три из которых видимые, для заполнения пользователем, а четвертое - скрытое, по нему мы позднее будем отлавливать отправленные данные с формы для обработки.
Итак, перечень полей готов, осталось создать саму форму:
$form = rcl_get_form(array( 'method' => 'post', 'action' => '/', 'submit' => __('Сохранить'), 'fields' => $fields ));
Мы передаем массив полей в функцию rcl_get_form(), которая и создает из этих полей форму. Кроме полей, мы также указываем метод отправки данных, текст на кнопке отправки и страницу назначения.
Осталось лишь написать обработчик данных этой формы. Отправленные данные мы будем обрабатывать в хуке 'wp', на нее и повесим нашу функцию-обработчик:
add_action('wp', 'my_form_save_data', 10); function my_form_save_data(){ if(!isset($_POST['my_form_submit'])) return false; $formData = $_POST; //тут обрабатываем данные с формы //возможно, сохраняем их //а дальше перенаправляем пользователя на нужную страницу wp_redirect($location); exit; }
Как можно заметить, внутри обработчика мы сначала проверяем значение того самого скрытого поля формы, по которому и понимаем, что пришли данные с формы, которые необходимо обработать.
Минимум усилий и вполне рабочая форма будет радовать вас и посетителей вашего сайта!
Отправка данных формы через AJAX
Но перезагрузка страницы при отправке данных с формы может не впечатлить современного притязательного пользователя и мы просто обязаны рассмотреть вариант отправки данных на сервер через AJAX-запрос.
Для этого, нам потребуется внести небольшие изменения в массив данных формы, который передается в функцию rcl_get_form(), повесим onclick на кнопку отправки:
$form = rcl_get_form(array( 'onclick' => 'rcl_send_form_data("my_form_save_data",this);return false;', 'submit' => __('Сохранить'), 'fields' => $fields ));
Мы повесили на onclick js-функцию rcl_send_form_data(), которая делает две вещи. Сначала она проверяет правильность заполнения формы, например, на заполнение обязательных полей, а затем, если все в порядке, отправляет данные в указанную функцию-обработчик через AJAX.
Конечно, мы должны зарегистрировать наш AJAX-обработчик на стороне php, делается это следующим образом:
rcl_ajax_action('my_form_save_data'); function my_form_save_data(){ rcl_verify_ajax_nonce(); $formData = $_POST; //тут обрабатываем данные с формы //возможно, сохраняем их //а дальше перенаправляем пользователя на нужную страницу wp_send_json(array( 'success' => __('Данные сохранены!'), //уведомление об успехе 'redirect' => $location, //редирект на указанный адрес 'error' => __('Тут текст ошибки'), //уведомление об ошибке 'reload' => true, //перезагрузка страницы 'dialog' => array( //вывод диалогового окна 'content' => __('Содержимое диалогового окна') ) )); }
Функция rcl_send_form_data() может правильно обработать только некоторый перечень ответов от обработчика, их перечень приведен в коде выше. Указанный перечень ответов будет обработан и приведет к какому-либо автоматическому событию.
Вешаем на onclick свою замену
В большинстве случаев, этот перечень решает поставленные задачи, но что делать если нам требуется, после получения ответа выполнять какое то действие на странице? В этом случае, нам потребуется отказаться от использования функции rcl_send_form_data() и написать свою замену с более сложной логикой и уже ее повесить на кнопку отправки данных нашей формы. Делается это несложно:
function my_sender_form_data(e){ //получаем данные формы var FormFactory = new RclForm(jQuery(e).parents('form')); //проверяем на правильность заполнения if(!FormFactory.validate()) return false; FormFactory.send('my_form_save_data', function(result){ //тут пишем нужную нам логику //на основании полученного ответа от обработчика //данные ответа лежат внутри result }); }
Далее осталось чуть поправить данные формы указываемые для функции rcl_get_form(), указываем свой js-обработчик:
$form = rcl_get_form(array( 'onclick' => 'my_sender_form_data(this);return false;', 'submit' => __('Сохранить'), 'fields' => $fields ));
Теперь мы можем отправлять из функции my_form_save_data() любые нужные нам данные и на основании этих данных производить какие то произвольные действия, логику которых мы описали внутри js-функции my_sender_form_data().
Пошаговое заполнение нескольких форм
Иногда бывает, что приходится разбивать получение данных пользователя на несколько этапов. Это полезно, если мы не можем предложить пользователю какую то одну форму, так как не знаем, какие данные он собирается заполнить и мы вынуждены динамически создавать форму на следующем шаге и выводить ему. Например, данные с первой формы должны поступить в обработчик, который на основании полученных данных должен создать новую форму и предложить ее для заполнения, в свою очередь, данные полученные с этой формы должны вызвать третью форму и так далее, пока не будет получен окончательный ответ.
В данный момент, это легко решается с помощью использования диалоговых окон. Логика следующая: данные с первой формы отправляются в обработчик, где создается и возвращается вторая форма в диалоговом окне, данные со второй формы передаются уже в другой обработчик, который и возвращается третью форму, которая будет посылать данные в свой собственный обработчик. Для каждой формы мы пишем свой обработчик.
Рассмотрим пример реализации описанного алгоритма:
//первая форма $form = rcl_get_form(array( 'onclick' => 'rcl_send_form_data("my_first_form_process", this);return false;', 'submit' => __('Передать'), 'fields' => $fields )); //обработчик первой формы rcl_ajax_action('my_first_form_process'); function my_first_form_process(){ rcl_verify_ajax_nonce(); //тут обрабатываем данные с первой формы //строим вторую форму и отправляем ее в диалоговом окне //вторая форма $form = rcl_get_form(array( 'onclick' => 'rcl_send_form_data("my_two_form_process", this);return false;', 'submit' => __('Передать'), 'fields' => $fields )); wp_send_json(array( 'dialog' => array( //вывод диалогового окна 'title' => __('Вторая форма'), 'content' => $form ) )); } //обработчик второй формы rcl_ajax_action('my_two_form_process'); function my_two_form_process(){ rcl_verify_ajax_nonce(); //тут обрабатываем данные со второй формы //строим третью форму и отправляем ее в диалоговом окне //третья форма $form = rcl_get_form(array( 'onclick' => 'rcl_send_form_data("my_three_form_process", this);return false;', 'submit' => __('Передать'), 'fields' => $fields )); wp_send_json(array( 'dialog' => array( //вывод диалогового окна 'title' => __('Третья форма'), 'content' => $form ) )); } //обработчик третьей формы rcl_ajax_action('my_three_form_process'); function my_three_form_process(){ rcl_verify_ajax_nonce(); //тут обрабатываем данные с третьей формы //и возвращаем уведомление об успехе wp_send_json(array( 'success' => __('Данные успешно обработаны!'), 'dialog' => array( //закрываем диалоговое окно 'close' => true ) )); }
Заметьте, вся логика описана только на стороне php! Здесь я снова использовал стандартную js-функцию rcl_send_form_data(), ее в этом случае вполне достаточно и ее использование позволяет полностью отказаться от написания js-логики, что как можно заметить значительно упрощает реализацию этого, достаточно сложного алгоритма.
Смотрим работу последнего примера в действии:
Весь код рабочего примера можно увидеть по ссылке: https://pastebin.com/
Использование описанного функционала очень часто позволяло мне значительно сокращать количество рутинных операций и ускорять время разработки многих дополнений. Предлагаю и вам начать его использовать. Надеюсь, вы найдете имеющиеся возможности полезными и удобными. Буду рад получить обратную связь, предложения или замечания в комментариях к публикации.
Всем удачи!
Круто! Спасибо Андрей.
Это еще и сокращает время на отладку js - часто сталкивался с тем что дебажил принимаемые данные - т.к. не совсем верно по dom дереву перемещался отлавливая свои data атрибуты.
Унификация - крутая штука. Потому как часто выполняешь на самом деле рутиные операции, а единой точки входа не было.
Я реколл ajax-ом активно пользуюсь, апи произвольных полей, апи постраничной навигации, апи кеша, rcl query, ssi modal, теперь вот формы - работы меньше для нас. Работать будем лучше и быстрей.
А еще писать меньше повторяющегося js и css. А это отразится на пользователях - в фронтенде их будет меньше - значит будет сайт быстрей загружать ресурсы.
WP-Recall лучший!
Спасибо, это реально крутая штука, сам всем этим добром активно пользуюсь, а люди то не в курсе, вот и решил поделиться)
Дошел я до этого дела на практике)) Спасибо Андрей - это просто чумовая вещь в работе. Всё отлично отработало. WP-Recall суперский фреймворк
А можно в
Добавить возможность указать какую то callback функцию которая будет вызвана при получении ответа и какие-то кастомные параметы data, которые будут переданы в эту функцию. Например что бы было так:
нет, но это и не требуется, в твоем случае, надо указать в массиве формы нужную js-функцию, которая будет вызываться при onclick и уже в ней обрабатывать возвращенный из php результат так как нужно