✅ Noticias, temas, complementos de WEB y WordPress. Aquí compartimos consejos y las mejores soluciones para sitios web.

Tutorial: Cree un tipo de campo de formularios de gravedad personalizados avanzados y cómo manejar múltiples valores de entrada

8

En este tutorial, le mostraré cómo crear un tipo de campo Gravity Forms personalizado avanzado. El campo tendrá múltiples entradas y necesitará un manejo especial para almacenar y mostrar los valores enviados.

que haremos

En este ejemplo, asumo un ejemplo del propietario de un sitio web de WordPress que se ocupa de las entregas de almuerzos en un lugar de trabajo. El propietario tiene un formulario para que las personas llenen qué tipo de almuerzo quieren y cuántos para cada día de la semana. Esto se puede resolver como un método similar a una tabla para ingresar un número para cualquier curso en cualquier día que deseen la entrega.

Tutorial: Cree un tipo de campo de formularios de gravedad personalizados avanzados y cómo manejar múltiples valores de entrada

Los cursos se pueden editar en la configuración del campo en el editor de formularios y se pueden cambiar en cualquier momento. Y para cada envío de formulario, el propietario del sitio web obtiene una descripción completa de los valores enviados:

Tutorial: Cree un tipo de campo de formularios de gravedad personalizados avanzados y cómo manejar múltiples valores de entrada

Obviamente, esto es solo un ejemplo y probablemente necesite ajustarlo a su caso. Pero con este caso de ejemplo, tenemos la oportunidad de aprender a manejar múltiples entradas en un solo campo. Debería darle algunas ideas sobre cómo manejar su propio tipo de campo personalizado.

Antes de empezar a codificar

Antes de comenzar, necesitamos un lugar para agregar nuestro código. Puede agregar esto en su tema functions.phpo en su archivo de complemento.

El método que he elegido está orientado a objetos, lo que significa crear una clase que amplíe la GF_Fieldclase de Gravity Forms. Recomiendo poner la clase en un archivo separado en su proyecto. También debe verificar que exista el complemento Gravity Forms antes de incluir su clase para evitar que su sitio se bloquee.

Si está interesado, puede consultar la documentación de Gravity Forms en GF_Field. Encontrará más funciones y variables que podría necesitar para su tipo de campo.

Al extender la GF_Fieldclase, podemos simplemente elegir anular las funciones que necesitamos cambiar. En cuanto a las funciones que no anulamos, Gravity Forms ejecutará el valor predeterminado definido dentro de GF_Field. En el tutorial a continuación, revisaremos cada función que necesitamos anular para nuestro campo personalizado una por una. Sin más preámbulos, ¡comencemos!

Crear un tipo de campo personalizado

El primer paso es definir una clase PHP personalizada que amplíe GF_Field. Asigne a la clase un nombre único y asegúrese de que esté incluido en su proyecto. Después de la definición de la clase, ejecutamos la register()función estática al GF_Fieldpasar una instancia de nuestra clase como parámetro. Esto inicializa nuestra clase y registra el tipo de campo.

La única variable requerida que necesita dentro de su clase es $type. La variable de clase $typedebe ser única y es un nombre de slug de su tipo de campo. En mi ejemplo lo he llamado ‘ 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()); }

Con este pequeño fragmento de código, nuestro tipo de campo personalizado debe agregarse como una opción disponible en el editor de Gravity Forms. De manera predeterminada, aparece al final del cuadro "Campos estándar". Debido a que aún no le hemos dado un nombre propio a nuestro campo (ese es el siguiente paso), el botón está etiquetado como el valor de $type.

Tutorial: Cree un tipo de campo de formularios de gravedad personalizados avanzados y cómo manejar múltiples valores de entrada

Definición del nombre del campo

El siguiente paso es fácil; simplemente dándole a nuestro campo un mejor nombre. Para hacer eso, anulamos la función get_form_editor_field_title(). Todo lo que tenemos que hacer es devolver una cadena con el nombre del campo.

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

Con esta función en nuestra clase, el botón para agregar el campo se actualiza con una etiqueta mucho mejor.

Cambiar la categoría del campo

Este paso es opcional. Por defecto, nuestro tipo de campo personalizado aparece en el cuadro "Campos estándar", pero podemos cambiar eso. Supongamos que queremos que aparezca dentro del cuadro "Campos avanzados".

Para cambiar la categoría en la que queremos que aparezca el campo, anulamos la función get_form_editor_button(). Necesitamos devolver una matriz asociativa con dos elementos. Como valor para la clave ‘ group‘, proporciona el nombre interno de la categoría en la que desea que aparezca el botón. Las opciones disponibles aquí son ‘ standard_fields‘, ‘ advanced_fields‘, ‘ post_fields‘ o ‘ pricing_fields‘. (También puede crear su propia categoría, pero eso no se trata aquí). El segundo elemento de la matriz necesita la clave ‘ text‘ y para eso simplemente devolvemos el nombre del campo llamando a get_form_editor_field_title(). Esta es la función que acabamos de crear arriba.

Ahora el botón para agregar nuestro tipo de campo personalizado se mueve al cuadro "Campos avanzados".

Activar la configuración del campo

Si ha intentado agregar el tipo de campo en un formulario, es posible que haya notado que no hay ninguna configuración. Ni siquiera puedes editar la etiqueta. La forma en que esto funciona es que todos los tipos de configuraciones realmente están ahí, simplemente todos están ocultos con CSS por Gravity Forms. Necesitamos definir individualmente qué configuraciones queremos habilitar, y Gravity Forms luego mostrará las configuraciones elegidas para nosotros.

Necesitamos definir la función get_form_editor_field_settings()y devolver una matriz de todas las configuraciones que no queremos ocultar para nuestro tipo de campo. La configuración que desea agregar depende completamente de usted y su proyecto. Tenga en cuenta que su campo debe admitir cualquier configuración que active; de ​​lo contrario, no tiene sentido mostrar una configuración para él.

He creado una descripción general rápida de los nombres de las configuraciones a continuación. Esto está lejos de ser una lista completa, porque hay muchas configuraciones que son útiles solo para tipos de campos muy específicos. Por ejemplo, formato de teléfono, formato de fecha/hora y un montón de configuraciones relacionadas con los campos de publicación y precios.

Pestaña General

  • Etiqueta de campo:label_setting
  • Campo Descripción:description_setting
  • Opciones:choices_setting
  • Requerido:rules_setting
  • Sin duplicados:duplicate_setting
  • Habilitar columnas:columns_setting
  • Habilite la opción "seleccionar todo":select_all_choices_setting
  • Habilitar la opción "otra":other_choice_setting

Pestaña de apariencia

  • Marcador de posición:placeholder_setting
  • Visibilidad de la etiqueta de campo y ubicación de la descripción:label_placement_setting
  • Mensaje de validación personalizado:error_message_setting
  • Clase CSS personalizada:css_class_setting
  • Tamaño del campo:size_setting

Lengüeta avanzada

  • Etiqueta de campo de administrador:admin_label_setting
  • Valor por defecto:default_value_setting
  • Habilitar entrada de contraseña:password_field_setting
  • Forzar SSL:force_ssl_field_setting
  • Visibilidad:visibility_setting
  • Permitir que el campo se complete dinámicamente:prepopulate_field_setting
  • Habilitar lógica condicional:conditional_logic_field_setting
  • Habilitar lógica condicional de página:conditional_logic_page_setting

En cuanto a nuestro ejemplo, los más importantes son la etiqueta del campo, la descripción, las opciones y si el campo es obligatorio o no. También permitimos la configuración de la clase CSS, el mensaje de validación personalizado y la lógica condicional.

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' ]; }

Actualice el editor de formularios y ahora debería ver todas las configuraciones y pestañas elegidas dentro de nuestro campo. Todas las configuraciones son manejadas y guardadas automáticamente por Gravity Forms.

Continúe y agregue algunos elementos en la lista de opciones para que tengamos algo con lo que trabajar. Esto es lo que he configurado como ejemplo:

Tutorial: Cree un tipo de campo de formularios de gravedad personalizados avanzados y cómo manejar múltiples valores de entrada

Definición de opciones predeterminadas personalizadas

Si está acostumbrado a usar, por ejemplo, botones de radio o casillas de verificación en Gravity Forms, probablemente haya notado que vienen con opciones como "Primera opción", "Segunda opción", "Tercera opción". Este es el comportamiento predeterminado de Gravity Forms si no se han guardado opciones (antes) y esto se activa solo en estos tipos de campos específicos. Pero para nuestro tipo de campo personalizado, no se completará ninguna opción. Esto lo hace un poco engorroso, porque no obtendrá el botón "+" para agregar otra opción. Tendría que usar el botón "Agregar en bloque/Opciones predefinidas", agregar algunas opciones allí y, después de eso, obtener acceso a los botones "+" para agregar opciones. Pero es fácil definir algunas opciones personalizadas: todo lo que necesita es definir una variable de matriz de clasepublic $choicesy Gravity Forms generará automáticamente opciones predefinidas en su campo cuando lo agregue a sus formularios.

Nota: Esta es una variable de clase, que puede agregar en la parte superior de la clase, justo debajo public $type. Cada opción debe ser una matriz, con la opción como valor para la clave ‘ text‘.

Tenga en cuenta que si ya ha agregado el campo al formulario, no se completarán las opciones de forma retroactiva. Esto solo entra en vigencia cuando agrega un nuevo campo al formulario.

Nota: en Gravity Forms parece posible agregar también las teclas ‘ value‘ a cada opción. Pero no he conseguido que esto funcione: los valores se convertirán automáticamente en los mismos que el texto de elección.

Definición del valor del campo como matriz

El siguiente paso es bastante simple, pero necesario. Como valores predeterminados para los campos en Gravity Forms son cadenas. Necesitamos que el valor sea una matriz porque trabajamos con múltiples entradas. Para ello definimos la función is_value_submission_array()y devolvemos true.

public function is_value_submission_array() { return true; }

Esto asegura que podamos trabajar correctamente con el valor ingresado de nuestras entradas múltiples.

Representación de la salida del campo

Cuando se trata de representar la salida del campo, hay un par de cosas a tener en cuenta.

En primer lugar, debe elegir entre dos funciones; get_field_input()o get_field_content(). En el primer método, Gravity Forms muestra automáticamente el elemento de la lista envolvente, la etiqueta, la descripción y el contenedor para el mensaje de error de validación en su campo y usted solo controla la salida del campo interno. Con el segundo método, nada de esto sucede y tiene más control sobre la salida del campo. Sin embargo, debe representar manualmente la etiqueta, la descripción y los mensajes de error. El primer método, get_field_input(), está perfectamente bien para la mayoría de los casos.

La segunda cosa a tener en cuenta es que la función de representación del campo afecta a tres ubicaciones diferentes. Los tres son la representación de la salida del campo en la interfaz, la vista previa del campo dentro del editor de formularios y, finalmente, también el campo al editar una entrada. Por suerte Gravity Forms ofrece funciones para determinar fácilmente en qué vista nos encontramos. Por lo general, renderizaría el campo de la misma manera en los tres casos. Pero debido a que la representación de una tabla grande con muchas entradas se vuelve innecesariamente torpe dentro del editor de formularios, he optado por representar el campo de manera diferente dentro del editor de formularios.

Y finalmente, debemos asegurarnos de que cualquier entrada obtenga un nameatributo adecuado para que Gravity Forms pueda recopilar su valor al enviar el formulario. Todas las entradas en Gravity Forms necesitan nameatributos que sigan esta regla: name="input_{FIELD_ID}"(los campos de selección múltiple usan una identificación adicional, pero no necesitamos preocuparnos por eso en nuestro caso). Tenemos acceso al ID de campo ya que es una variable de clase (de GF_Field). Pero en nuestro caso, le hemos dicho a Gravity Forms que el valor es una matriz y no un valor singular (paso anterior), por lo que agregamos corchetes después del atributo de nombre; name="input_{FIELD_ID}[]". Entonces, si el campo tiene la ID de 4 dentro de un formulario, el atributo de nombre debe ser " input_4[]".

Estoy optando por usar get_field_input()que viene con tres parámetros. El primer parámetro es el objeto de formulario, que en realidad no necesitamos para nuestro ejemplo. El segundo parámetro es el valor actual. Puede ser el valor del campo desde $_POSTel momento en que se intentó enviar el formulario, pero sin éxito. Podemos conservar los valores enviados anteriormente. O si la función se está ejecutando al editar una entrada, el valor será el valor almacenado del envío. Trataremos el valor más de cerca más adelante. Y el tercer parámetro es el objeto de entrada, que tampoco necesitaremos para nuestro ejemplo.

Comencemos a implementar get_field_input()cuál espera el renderizado final como una cadena. Directamente desde el principio, decido devolver una cadena vacía si estamos dentro del editor de formularios, porque no quiero mostrar la tabla completa en esta vista. Podemos usar el método $this->is_form_editor()para verificar si estamos o no dentro de la edición del formulario. Puede optar por omitir esto o representar algo más si desea una vista previa del campo dentro del editor de formularios.

El siguiente paso es construir el HTML para una tabla que recorre una serie de días para generar las columnas y las filas para cada elemento del curso. Pero debido a que necesitamos acceso a la matriz de días (columnas de la tabla) en varios lugares, debemos definirla como una variable de clase, haciéndola accesible desde cualquier función dentro de ella. Defino una variable de clase $delivery_dayscon una matriz de los días para los que quiero ofrecer la entrega.

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

¡Esto es solo un ejemplo! Es posible que desee obtener la matriz de las columnas de otro lugar que no esté codificado.

Volvamos get_field_input()y construyamos nuestra tabla con entradas. Primero recorro la variable de clase y genero los encabezados de la tabla. Luego repaso las opciones ingresadas en la configuración de campo para Elecciones. Esto es accesible desde la variable de clase (desde GF_Field) $this->choices. Para cada opción, presento una entrada con los atributos de nombre propios. Tenemos acceso al ID del campo desde GF_Fieldla variable de clase de $this->id.

¡Con este código en su lugar, deberíamos obtener una buena tabla representada para nuestro tipo de campo en la interfaz! Obviamente, el HTML depende totalmente de usted, este es solo un ejemplo básico.

Dejamos esta función por ahora, ¡pero volveremos a ella más tarde para manejar el valor enviado!

Almacenar el valor correctamente

A partir de ahora, Gravity Forms guardará nuestro campo como una matriz unidimensional poblada con los valores ingresados ​​y cadenas vacías donde la entrada estaba vacía. No hay información sobre a qué día o elección pertenece el valor, aparte del índice. Necesitamos transformar esta matriz unidimensional en una matriz asociativa multidimensional donde almacenamos el día y la etiqueta de elección. Entonces podemos acceder fácilmente al valor del número almacenado, por ejemplo $value['Ham sandwich']['Monday']. Después de esta transformación de matriz, también necesitamos serializar la matriz para que Gravity Forms pueda almacenar el valor correctamente en la base de datos.

Tendremos que transformar esta matriz de valores en varios lugares, así que definiré una función separada para esto. La función acepta la matriz unidimensional y la transforma en una matriz multidimensional con los valores almacenados para días y opciones:

Esto almacenará los nombres de los días y las opciones directamente dentro del valor del campo. Hacerlo de esta manera hace posible cambiar las opciones en un momento posterior sin romper las entradas anteriores.

Ahora pasemos a anular la función que maneja el almacenamiento del valor enviado; get_value_save_entry(). Viene con cinco parámetros, pero solo necesitamos el primero, que es el valor enviado. Dentro de la función, pasamos el valor a nuestra función personalizada anterior, serializamos su devolución y finalmente devolvemos el nuevo valor.

¡En este punto, Gravity Forms almacenará con éxito nuestros valores tal como los queremos! Sin embargo, el valor almacenado ahora es una matriz serializada que Gravity Forms felizmente reproducirá directamente. Necesitamos implementar funciones para transformarlo de una matriz serializada fea en una salida bonita donde sea que la necesitemos.

Mostrando el valor enviado

Hay tres lugares en los que necesitamos cambiar la salida del valor de nuestro campo; la lista de entradas, mirando una sola entrada y dentro de las etiquetas de combinación de Gravity Forms. Las etiquetas de combinación se utilizan con mayor frecuencia en las notificaciones por correo electrónico. Por ejemplo {all_fields}, es una etiqueta de combinación que muestra los valores completos del formulario enviado en los correos electrónicos.

Debido a que estamos representando la misma salida en tres casos diferentes, tiene sentido crear una función separada para ella. He definido una función personalizada que acepta el valor; la matriz multidimensional no serializada, como parámetro. Luego, la función genera algo de HTML que muestra la matriz de una manera bonita y devuelve la cadena. He optado por una <ul>lista anidada, pero puede cambiar la salida como desee.

Genial, empecemos por la primera: la lista de entradas: get_value_entry_list(). Puede optar por generar la salida completa aquí, pero puede volverse bastante torpe y largo para la vista de lista, por lo que opté por devolver una cadena fija que explica que el usuario debe ingresar a los detalles de la entrada para ver la descripción completa.

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

Por supuesto, esto depende totalmente de usted, puede optar por mostrar solo el primer número x de caracteres, por ejemplo.

La segunda función es la que afecta la vista de una sola entrada get_value_entry_detail():

Simplemente deserializamos la matriz con la función de WordPress [maybe_unserialize](https://developer.wordpress.org/reference/functions/maybe_unserialize/)()y devolvemos la cadena de salida de nuestra función personalizada.

La función final afecta las etiquetas de combinación y se asegura de que el valor de nuestro campo también se vea bien dentro de los correos electrónicos: get_value_merge_tag().

Tenga en cuenta que no necesitaremos deserializar el valor dentro de esta función.

¡Con estas tres funciones en su lugar, todos los valores enviados deberían verse bastante bien en todas partes! Por ejemplo, al ver una entrada enviada:

Tutorial: Cree un tipo de campo de formularios de gravedad personalizados avanzados y cómo manejar múltiples valores de entrada

Sin embargo, ¡falta una cosa importante! En este punto, nuestras entradas no conservan los valores enviados anteriormente y eso es bastante malo.

Hacer que nuestras entradas conserven el valor enviado anteriormente

Hay principalmente dos casos en los que debemos asegurarnos de que las entradas mantengan los valores enviados anteriormente. El primer caso es cuando falla el envío de un formulario (por ejemplo, el usuario olvidó un campo obligatorio). En este momento, todas nuestras entradas pierden todos los valores ingresados ​​previamente y el usuario tiene que volver a ingresar todos los valores nuevamente. En segundo lugar, cuando el propietario del sitio edita una entrada, las entradas no se completan con los valores enviados desde el envío, lo que hace que sea bastante imposible editar los valores correctamente.

Para solucionar esto volvemos a la función get_field_input(). El segundo parámetro de esta función es el valor. Pero recuerda que esta función afecta tanto al renderizado frontend como a la edición de entrada. Esto es importante porque el valor almacenado es diferente en estos dos casos. Si estamos en la interfaz y manejando el envío de formularios, el valor está en el formato de la matriz unidimensional mencionada anteriormente. Y si estamos editando una entrada, el valor tiene el formato de una matriz multidimensional serializada. Por lo tanto, debemos traducir correctamente el valor proporcionado get_field_input()para acceder fácilmente a los valores reales.

En el código anterior, antes de comenzar a crear el HTML para la salida del campo, creamos una variable $table_valueque contiene el valor traducido correctamente. Usamos GF_Fieldla función is_entry_detail()para verificar si estamos editando una entrada o no. Y luego, para nuestras entradas, es fácil acceder a los valores adecuados y establecerlos como valueatributos de las entradas:

Con lo anterior actualizado get_field_input(), todas nuestras entradas personalizadas siempre deben completarse con el valor anterior; no importa si está editando una entrada o reintentando el envío de un formulario.

En este punto, todo lo relacionado con la representación y el almacenamiento de nuestros valores está hecho y en pleno funcionamiento. Pero hay una cosa más que definitivamente debemos arreglar.

Hacer que nuestro campo pase la validación "requerida"

Los formularios de gravedad tienen comprobaciones para ver si el valor de un campo está vacío o no. Esto suele ser necesario cuando el campo se establece como obligatorio. Cuando se requiere un campo, no puede enviar el formulario si está vacío, ¿verdad? El problema para nosotros es que tenemos múltiples entradas y queremos permitir que algunas de ellas estén vacías. Esto se convierte en un problema si nuestro campo se establece en requerido. Desafortunadamente, Gravity Forms interpreta incorrectamente "está vacío" y requiere que se completen todas las entradas. Por lo tanto, debemos agregar una regla que diga que si se completa al menos una de nuestras muchas entradas, el valor total del campo no está vacío.

La función final que necesitamos anular en nuestra clase es is_value_submission_empty(). Solo obtenemos el ID del formulario como parámetro para esta función, por lo que debemos extraer el valor del campo utilizando la función Gravity Forms para obtenerlo de la $_POSTmatriz: rgpost('input_<FIELD ID>'). El retorno debe ser la matriz unidimensional que hemos visto antes. Todo lo que tenemos que hacer es recorrer la matriz y regresar falsesi encontramos un valor en alguna parte. De lo contrario, regresamos trueya que el valor del campo está completamente vacío.

Con la función anterior en su lugar, nuestro campo no fallará en el envío si está configurado como obligatorio y se completa al menos una entrada.

Conclusión y código final

Este tutorial le ha mostrado en detalle cómo crear su propio tipo de campo avanzado personalizado para Gravity Forms. Incluso si su proyecto es diferente a mi ejemplo, espero que tenga algunos consejos y a-ha en el camino. ¡Encuentro que la documentación de Gravity Forms es bastante deficiente en algunos casos, y este es el resultado de muchas pruebas y errores! De todos modos, ¡espero que esto haya sido de alguna utilidad para ti!

Como referencia, aquí está el código completo en su totalidad:

Fuente de grabación: awhitepixel.com

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More