✅ Новости WEB и WordPress, темы, плагины. Здесь мы делимся советами и лучшими решениями для веб-сайтов.

Учебное пособие. Создание расширенного пользовательского типа поля Gravity Forms и обработка нескольких входных значений

13

В этом уроке я покажу вам, как создать расширенный настраиваемый тип поля Gravity Forms. Поле будет иметь несколько входных данных и потребует специальной обработки для хранения и отображения отправленных значений.

Что мы будем делать

В этом примере я беру пример владельца веб-сайта WordPress, который занимается доставкой обедов на рабочем месте. У владельца есть форма, в которой люди могут указать, какой обед они хотят и сколько на каждый день недели. Это можно решить с помощью табличного метода ввода числа для любого курса в любой день, когда они хотят доставить.

Учебное пособие. Создание расширенного пользовательского типа поля Gravity Forms и обработка нескольких входных значений

Курсы редактируются в настройках поля в редакторе форм и могут быть изменены в любое время. И для каждой отправки формы владелец веб-сайта получает полный обзор отправленных значений:

Учебное пособие. Создание расширенного пользовательского типа поля Gravity Forms и обработка нескольких входных значений

Очевидно, что это всего лишь пример, и вам, вероятно, нужно настроить его для вашего случая. Но в этом примере у нас есть возможность научиться обрабатывать несколько входных данных в одном поле. Это должно дать вам некоторые идеи о том, как обрабатывать ваш собственный настраиваемый тип поля.

Прежде чем начать кодировать

Прежде чем мы начнем, нам нужно место для добавления нашего кода. Вы можете добавить это в файл вашей темы functions.phpили плагина.

Метод, который я выбрал, является объектно-ориентированным, что означает создание класса, расширяющего класс Gravity Forms GF_Field. Я рекомендую поместить класс в отдельный файл в вашем проекте. Вы также должны убедиться, что плагин Gravity Forms существует, прежде чем включать свой класс, чтобы предотвратить сбой вашего сайта.

Если вам интересно, вы можете взглянуть на документацию Gravity Forms на GF_Field. Вы найдете больше функций и переменных, которые могут понадобиться для вашего типа поля.

Расширяя GF_Fieldкласс, мы можем просто переопределить функции, которые нам нужно изменить. Что касается функций, которые мы не переопределяем, Gravity Forms будет запускать функции по умолчанию, определенные внутри GF_Field. В приведенном ниже руководстве мы рассмотрим каждую функцию, которую нам нужно переопределить для нашего пользовательского поля, одну за другой. Без лишних слов, давайте начнем!

Создание пользовательского типа поля

Первым шагом является определение пользовательского класса PHP, который расширяет GF_Field. Дайте классу уникальное имя и убедитесь, что оно включено в ваш проект. После определения класса мы запускаем register()статическую функцию GF_Field, передавая экземпляр нашего класса в качестве параметра. Это инициализирует наш класс и регистрирует тип поля.

Единственная обязательная переменная, которая вам нужна внутри вашего класса, это $type. Переменная класса $typeдолжна быть уникальной и представлять собой псевдоним вашего типа поля. В моем примере я назвал его ‘ food_delivery‘.

if (class_exists('GF_Field')) { class FoodDelivery extends GF_Field { public $type = 'food_delivery';   // The rest of the code is added here... } GF_Fields::register(new FoodDelivery()); }

С помощью этого крошечного фрагмента кода наш настраиваемый тип поля должен быть добавлен в качестве доступного выбора в редакторе Gravity Forms. По умолчанию она отображается в конце поля «Стандартные поля». Поскольку мы еще не дали нашему полю правильное имя (это следующий шаг), кнопка помечена как значение $type.

Учебное пособие. Создание расширенного пользовательского типа поля Gravity Forms и обработка нескольких входных значений

Определение имени поля

Следующий шаг — простой; просто дать нашему полю лучшее имя. Для этого мы переопределяем функцию get_form_editor_field_title(). Все, что нам нужно сделать, это вернуть строку с именем поля.

public function get_form_editor_field_title() { return esc_attr__('Food Delivery', 'txtdomain'); }

С помощью этой функции в нашем классе кнопка для добавления поля обновляется с гораздо лучшей меткой.

Изменение категории поля

Этот шаг является необязательным. По умолчанию наш настраиваемый тип поля отображается в поле «Стандартные поля», но мы можем это изменить. Предположим, мы хотим, чтобы он отображался внутри поля «Дополнительные поля».

Чтобы изменить категорию, в которой должно отображаться поле, мы переопределяем функцию get_form_editor_button(). Нам нужно вернуть ассоциативный массив с двумя элементами. В качестве значения ключа ‘ group‘ вы указываете внутреннее имя категории, в которой должна отображаться кнопка. Здесь доступны следующие варианты: ‘ standard_fields‘, ‘ advanced_fields‘, ‘ post_fields‘ или ‘ pricing_fields‘. (Вы также можете создать свою собственную категорию, но здесь это не рассматривается). Второму элементу в массиве нужен ключ ‘ text‘, и для этого мы просто возвращаем имя поля, вызывая get_form_editor_field_title(). Это функция, которую мы только что создали выше.

Теперь кнопка для добавления нашего пользовательского типа поля перемещена в поле «Дополнительные поля».

Активация полевых настроек

Если вы пытались добавить тип поля в форму, то могли заметить, что настроек вообще нет. Вы даже не можете изменить ярлык. Это работает так, что на самом деле присутствуют все типы настроек, просто все они скрыты с помощью CSS с помощью Gravity Forms. Нам нужно индивидуально определить, какие настройки мы хотим включить, и Gravity Forms отобразит для нас выбранные настройки.

Нам нужно определить функцию get_form_editor_field_settings()и вернуть массив всех настроек, которые мы не хотим скрывать для нашего типа поля. Какие настройки вы хотите добавить, полностью зависит от вас и вашего проекта. Имейте в виду, что ваше поле должно поддерживать любые настройки, которые вы активируете, иначе бессмысленно показывать настройку для него.

Ниже я создал краткий обзор названий настроек. Это далеко не полный список, потому что есть много настроек, которые полезны только для очень специфических типов полей. Например, формат телефона, формат даты/времени и множество настроек, связанных с полями Post и Pricing.

Вкладка Общие

  • Метка поля:label_setting
  • Описание поля:description_setting
  • Выбор:choices_setting
  • Необходимый:rules_setting
  • Нет дубликатов:duplicate_setting
  • Включить столбцы:columns_setting
  • Включите опцию «выбрать все»:select_all_choices_setting
  • Включить «другое» выбор:other_choice_setting

Вкладка «Внешний вид»

  • Заполнитель:placeholder_setting
  • Видимость метки поля и размещение описания:label_placement_setting
  • Пользовательское сообщение проверки:error_message_setting
  • Пользовательский класс CSS:css_class_setting
  • Размер поля:size_setting

Продвинутая вкладка

  • Метка поля администратора:admin_label_setting
  • Значение по умолчанию:default_value_setting
  • Включить ввод пароля:password_field_setting
  • Принудительно SSL:force_ssl_field_setting
  • Видимость:visibility_setting
  • Разрешить динамическое заполнение поля:prepopulate_field_setting
  • Включить условную логику:conditional_logic_field_setting
  • Включить условную логику страницы:conditional_logic_page_setting

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

public function get_form_editor_field_settings() { return [ 'label_setting', 'choices_setting', 'description_setting', 'rules_setting', 'error_message_setting', 'css_class_setting', 'conditional_logic_field_setting' ]; }

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

Продолжайте и добавьте несколько элементов в список «Выбор», чтобы нам было с чем работать. Вот что я настроил в качестве примера:

Учебное пособие. Создание расширенного пользовательского типа поля Gravity Forms и обработка нескольких входных значений

Определение пользовательских вариантов по умолчанию

Если вы привыкли использовать, например, радиокнопки или флажки в Gravity Forms, вы, вероятно, заметили, что они поставляются с такими вариантами выбора, как «Первый выбор», «Второй выбор», «Третий выбор». Это поведение по умолчанию в Gravity Forms, если никакие варианты не были сохранены (ранее), и это срабатывает только для этих конкретных типов полей. Но для нашего пользовательского типа поля никакие варианты не будут заполнены. Это делает его немного громоздким, потому что вы не получите кнопку «+», чтобы добавить другой вариант. Вам нужно будет использовать кнопку «Массовое добавление / Предопределенные варианты», добавить туда несколько вариантов, и после этого вы получите доступ к кнопкам «+» для добавления вариантов. Но легко определить некоторые пользовательские варианты — все, что вам нужно, это определить переменную массива класса.public $choicesи Gravity Forms автоматически создаст предопределенные варианты в вашем поле, когда вы добавите его в свои формы.

Примечание. Это переменная класса, которую вы можете добавить в начало класса, прямо под public $type. Каждый выбор должен быть массивом с выбором в качестве значения ключа ‘ text‘.

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

Примечание. В Gravity Forms можно также добавлять клавиши ‘ value‘ к каждому варианту. Но у меня это не работает — значения автоматически станут такими же, как текст выбора.

Определение значения поля как массива

Следующий шаг довольно прост, но необходим. В качестве значений по умолчанию для полей в Gravity Forms используются строки. Нам нужно, чтобы значение было массивом, потому что мы работаем с несколькими входными данными. Для этого мы определяем функцию is_value_submission_array()и возвращаем true.

public function is_value_submission_array() { return true; }

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

Рендеринг вывода поля

Когда дело доходит до рендеринга вывода поля, нужно помнить о нескольких вещах.

Во-первых, вам нужно выбрать одну из двух функций; get_field_input()или get_field_content(). В первом методе Gravity Forms автоматически отображает элемент списка переноса, метку, описание и контейнер для сообщения об ошибке проверки в ваше поле, и вы контролируете только вывод внутреннего поля. Со вторым методом ничего этого не происходит, и вы больше контролируете вывод поля. Однако вам необходимо вручную отобразить метку, описание и сообщения об ошибках. Первый метод get_field_input()отлично подходит для большинства случаев.

Второе, о чем следует помнить, это то, что функция рендеринга для поля влияет на три разных местоположения. Три из них — это визуализация вывода поля во внешнем интерфейсе, предварительный просмотр поля в редакторе форм и, наконец, поле при редактировании записи. К счастью, Gravity Forms предлагает функции, позволяющие легко определить, в каком представлении мы находимся. Обычно вы должны визуализировать поле одинаково во всех трех случаях. Но поскольку рендеринг большой таблицы с большим количеством входных данных становится ненужным неуклюжим в редакторе форм, я решил отображать поле по-другому в редакторе форм.

И, наконец, нам нужно убедиться, что все входные данные получают надлежащий nameатрибут, чтобы Gravity Forms мог получить его значение при отправке формы. Все входные данные в Gravity Forms нуждаются в nameатрибутах, которые следуют этому правилу: name="input_{FIELD_ID}"(поля с множественным выбором используют дополнительный идентификатор, но нам не нужно беспокоиться об этом в нашем случае). У нас есть доступ к идентификатору поля, поскольку это переменная класса (из GF_Field). Но в нашем случае мы сказали Gravity Forms, что значение представляет собой массив, а не единственное значение (предыдущий шаг), поэтому мы добавляем скобки после атрибута имени; name="input_{FIELD_ID}[]". Таким образом, если поле имеет идентификатор 4 внутри формы, атрибут имени должен быть «input_4[]».

Я выбираю использование get_field_input(), которое поставляется с тремя параметрами. Первый параметр — это объект формы, который в нашем примере нам не нужен. Второй параметр – это текущее значение. Это может быть либо значение поля, $_POSTкогда форма была отправлена, но безуспешно. Мы можем сохранить предыдущие отправленные значения. Или, если функция работает при редактировании записи, значением будет сохраненное значение из отправки. Позже мы более подробно рассмотрим это значение. И третий параметр — объект входа, который нам тоже не понадобится для нашего примера.

Давайте начнем реализацию, get_field_input()которая ожидает окончательный рендеринг в виде строки. Сразу же я решил вернуть пустую строку, если мы находимся внутри редактора форм, потому что я не хочу отображать полную таблицу в этом представлении. Мы можем использовать этот метод $this->is_form_editor(), чтобы проверить, находимся ли мы внутри редактирования формы. Вы можете пропустить это или отобразить что-то еще, если хотите просмотреть поле в редакторе форм.

Следующим шагом является создание HTML-кода для таблицы, которая перебирает массив дней для создания столбцов и строк для каждого элемента курса. Но поскольку нам нужен доступ к массиву дней (столбцов таблицы) в нескольких местах, мы должны определить его как переменную класса, сделав его доступным из любых функций внутри него. Я определяю переменную класса $delivery_daysс массивом дней, для которых я хочу предложить доставку.

class FoodDelivery extends GF_Field { public $type = 'food_delivery';   private $delivery_days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'];   public function get_form_editor_field_title() { ... }

Это просто пример! Возможно, вы захотите получить массив для столбцов из другого места, которое не жестко запрограммировано.

Давайте вернемся get_field_input()и создадим нашу таблицу с входными данными. Сначала я перебираю переменную класса и генерирую заголовки таблицы. Затем я перебираю варианты, введенные в поле «Выборы». Это доступно из переменной класса (из GF_Field) $this->choices. Для каждого выбора я отображаю ввод с атрибутами имени собственного. У нас есть доступ к идентификатору поля из GF_Fieldпеременной класса $this->id.

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

Мы пока оставляем эту функцию, но вернемся к ней позже, чтобы обработать отправленное значение!

Правильное хранение значения

На данный момент Gravity Forms сохранит наше поле как одномерный массив, заполненный введенными значениями и пустыми строками, где ввод был пустым. Нет никакой информации о том, к какому дню или выбору принадлежит значение, кроме индекса. Нам нужно преобразовать этот одномерный массив в многомерный ассоциативный массив, где мы храним день и метку выбора. Затем мы можем легко получить доступ к сохраненному числовому значению, например, для $value['Ham sandwich']['Monday']. После этого преобразования массива нам также необходимо сериализовать массив, чтобы Gravity Forms мог правильно сохранить значение в базе данных.

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

Это сохранит названия дней и варианты выбора непосредственно внутри значения поля. Такой способ позволяет изменить выбор позже, не нарушая старые записи.

Теперь давайте обратимся к переопределению функции, которая обрабатывает сохранение отправленного значения; get_value_save_entry(). Он поставляется с пятью параметрами, но нам нужен только первый, который является отправленным значением. Внутри функции мы передаем значение в нашу пользовательскую функцию выше, сериализуем ее возврат и, наконец, возвращаем новое значение.

На этом этапе Gravity Forms успешно сохранит наши значения именно так, как мы этого хотим! Однако сохраненное значение теперь представляет собой сериализованный массив, который Gravity Forms с радостью отобразит прямо. Нам нужно реализовать функции, чтобы преобразовать его из уродливого сериализованного массива в какой-нибудь красивый вывод, где бы он нам ни понадобился.

Отображение отправленного значения

Нам нужно изменить вывод значения нашего поля в трех местах; список записей, просмотр одной записи и тегов слияния Gravity Forms. Теги слияния чаще всего используются в уведомлениях по электронной почте. Например {all_fields}, это тег слияния, который отображает полные значения отправленных форм в электронных письмах.

Поскольку мы рендерим один и тот же вывод в трех разных случаях, имеет смысл сделать для него отдельную функцию. Я определил пользовательскую функцию, которая принимает значение; несериализованный многомерный массив в качестве параметра. Затем функция создает некоторый HTML-код, который красиво отображает массив и возвращает строку. Я выбрал вложенный <ul>список, но вы можете изменить вывод по своему усмотрению.

Отлично, начнем с первого: список записей: get_value_entry_list(). Вы можете вывести здесь полный вывод, но он может стать довольно неуклюжим и длинным для представления списка, поэтому я решил просто вернуть фиксированную строку, которая объясняет, что пользователю нужно перейти к деталям записи, чтобы увидеть полный обзор.

public function get_value_entry_list($value, $entry, $field_id, $columns, $form) { return __('Enter details to see delivery details', 'txtdomain'); }

Это, конечно, полностью зависит от вас, например, вы можете выбрать отображение только первых x символов.

Вторая функция влияет на просмотр одной записи get_value_entry_detail():

Мы просто десериализуем массив с помощью функции WordPress [maybe_unserialize](https://developer.wordpress.org/reference/functions/maybe_unserialize/)()и возвращаем строковый вывод из нашей пользовательской функции.

Последняя функция влияет на теги слияния и следит за тем, чтобы значение нашего поля хорошо выглядело и в электронных письмах: get_value_merge_tag().

Обратите внимание, что нам не нужно будет десериализовать значение внутри этой функции.

С этими тремя функциями все представленные значения должны выглядеть довольно хорошо везде! Например, при просмотре отправленной записи:

Учебное пособие. Создание расширенного пользовательского типа поля Gravity Forms и обработка нескольких входных значений

Однако не хватает одной важной вещи! На данный момент наши входные данные не сохраняют ранее отправленные значения, и это очень плохо.

Сделайте так, чтобы наши входные данные сохраняли ранее отправленное значение

В основном есть два случая, когда нам нужно убедиться, что входные данные сохраняют ранее отправленные значения. Первый случай — когда отправка формы не удалась (например, пользователь забыл обязательное поле). Прямо сейчас все наши входы теряют все ранее введенные значения, и пользователь должен повторно вводить все значения снова. Во-вторых, когда владелец сайта редактирует запись, входные данные не заполняются отправленными значениями из отправки, что делает практически невозможным правильное редактирование значений.

Чтобы исправить это, вернемся к функции get_field_input(). Второй параметр этой функции — это значение. Но помните, что эта функция влияет как на внешний рендеринг, так и на редактирование записи. Это важно, потому что в этих двух случаях сохраненное значение отличается. Если мы находимся во внешнем интерфейсе и обрабатываем отправку формы, значение находится в формате одномерного массива, упомянутого ранее. А если мы редактируем запись, то значение в формате сериализованного многомерного массива. Поэтому нам нужно правильно перевести предоставленное значение, get_field_input()чтобы легко получить доступ к фактическим значениям.

В приведенном выше коде, прежде чем мы начнем создавать HTML для вывода поля, мы создаем переменную $table_value, содержащую правильно переведенное значение. Мы используем GF_Fieldфункцию is_entry_detail(), чтобы проверить, редактируем ли мы запись или нет. А затем для наших входных данных легко получить доступ к правильным значениям и установить их в качестве valueатрибутов входных данных:

С приведенным выше обновлением get_field_input()все наши пользовательские входы всегда должны быть заполнены предыдущим значением; независимо от того, редактирует ли он запись или повторяет отправку формы.

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

Заставьте наше поле пройти «требуемую» проверку

В Gravity Forms есть проверки, чтобы увидеть, является ли значение поля пустым или нет. Это часто необходимо, когда поле настроено как обязательное. Когда поле является обязательным, вы не можете отправить форму, если оно пустое, верно? Проблема для нас в том, что у нас есть несколько входов, и мы хотим, чтобы некоторые из них были пустыми. Это становится проблемой, если наше поле установлено как обязательное. Gravity Forms, к сожалению, неправильно интерпретирует «это пусто» и требует, чтобы все входные данные были заполнены. Поэтому нам нужно добавить правило, которое говорит, что если хотя бы один из наших многочисленных входных данных заполнен, общее значение поля не будет пустым.

Последняя функция, которую нам нужно переопределить в нашем классе, это is_value_submission_empty(). Мы получаем только идентификатор формы в качестве параметра этой функции, поэтому нам нужно извлечь значение поля с помощью функции Gravity Forms, чтобы получить его из $_POSTмассива: rgpost('input_<FIELD ID>'). Возврат должен быть одномерным массивом, который мы видели раньше. Все, что нам нужно сделать, это перебрать массив и вернуться false, если мы где-то найдем значение. В противном случае мы возвращаемся true, поскольку значение поля действительно полностью пусто.

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

Заключение и окончательный код

В этом руководстве подробно показано, как создать собственный расширенный тип поля для Gravity Forms. Даже если ваш проект отличается от моего примера, я надеюсь, что у вас есть несколько советов и а-ха на этом пути. Я считаю, что в некоторых случаях документации по Gravity Forms совершенно не хватает, и это результат множества проб и ошибок! В любом случае, надеюсь, это было полезно для вас!

Для справки, вот полный код целиком:

Источник записи: awhitepixel.com

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