Volver a Proyectos Listado de Artículos

Todo lo que necesitas saber sobre formularios ACF en la parte Frontend

Luis Ruiz

Escrito por Luis Ruiz Actualizado el

En este artículo vamos a intentar ir mostrando las partes más interesantes y Snippet de los formularios de ACF en la parte Visible de la web.

En algunas ocasiones, sobre todo en intranet, comunidades y web restringidas, necesitamos que el usuario logado envíe datos, documentos y que estos queden guardados en la plataforma para tener un mayor control y poder analizar y automatizar tareas.

Si no queremos complicarnos la vida haciéndolo de cero, o utilizar plugin extras, podemos usar ACF Pro si ya contamos con él.

Crear formulario

Creamos el formulario con la función acf_form(). Tenéis más información en el artículo de Mauricio Gelves sobre «Crear formularios en Frontend con ACF»

$args = [
	'new_post'    => [
        'post_type'   => 'orders',
	    'post_status' => 'private'
    ],
	'id'		    => 'form-orders',
	'post_id'       => 'new_post',
    'post_title'      => false,
    'post_content'    => false,
    'honeypot'        => true,
    'uploader'        => 'basic', // wp, basic
	'return'          => add_query_arg( 'updated', 'true', get_permalink() ),
    'submit_value'    => 'Enviar',
    'updated_message' => 'Datos enviados',
];

acf_form( $args );

Debemos de añadir al inicio de la página la función «acf_form_head» para que cargue todas las dependencias necesarias para crear el formulario. Sin esta función el formulario no funcionará correctamente.

Mostrar solo los campos que necesitamos en el formulario

Sí lo que buscamos es que solo se muestren unos determinados campos, tenemos que añadir al array de argumentos la key «fields» y pasarle el nombre de los campos.

$fields = array(
  '_bk_orders_usu',
  '_bk_orders_products'
);

$args = [
	// ....
	'fields' => $fields,
	// ...
];

Excluir campos para que no se muestren en el formulario.

En ocasiones vamos a necesitar que no se muestre algún campo concreto. Si el formulario es muy grande, y solo queremos excluir uno, es mejor esta opción que la que hemos visto anteriormente.

$groups = acf_get_field_groups(array('post_id' => $post_id));

// Sacamos todos los campos de ese grupo de campos.
$fields = acf_get_fields( $groups['key'] );

// Creamos un array con las Keys de los campos que necesitamos que no salga.
$excluded_fields = array(
    'field_633b308523ca2',
	'field_633b308523ca3'
);

$field_keys = array();
if ( $fields ) {
    foreach ( $fields as $field ) {
		// Añadimos al nuevo array los campos que no esten en el array de Keys excluidas.
        if ( ! in_array( $field['key'], $excluded_fields ) ) {
            $field_keys[] = $field['key'];
         }
    }
}

$args = [
	// ....
	'fields' => $field_keys,
	// ...
];

Como saber la Key de un campo ACF

Por defecto no se muestra la key de cada grupo y/o clave de campos. Para mostrarlos tenemos que ir a «Opciones de pantalla» que está situada arriba a la derecha, y hacer clic para desplegarlo.

Entonces veremos las diferentes opciones que tenemos, marcaremos la opción «clave» para el grupo de campos y claves de campo.

Mostrar Keys en Grupo de Campos en ACF
Mostrar Keys en Grupo de Campos.
Mostrar Keys en los campos dentro de los grupos en ACF
Mostrar Keys en los campos dentro de los grupos.

Filtrar un campo relacionado

Posiblemente nos surja en cualquier momento que tengamos un campo relacionado y queramos que solo se muestren los que tiene asignado el usuario para que seleccione los suyos.

Por ejemplo, imaginemos, tenemos un formulario en nuestra intranet para que los usuarios puedan reportar incidencias en una o varias de sus tiendas. Necesitaríamos que ,del listado completo de tiendas, solo mostrase las que tenga asignada el usuario para seleccionar la que necesite.

Para ello utilizaremos el filtro «acf/fields/relationship/query» para modificar los resultados mediante WP_Query

/**
* name_field_acf -> nombre del campo del formulario a modificar.
* name_field_shops -> campo donde tenemos guardadas las tiendas del usuario.
*/

add_filter('acf/fields/relationship/query/name=name_field_acf', 'bk_filter_by_user', 10, 3);
function bk_filter_by_user( $args, $field, $post_id ) {
	$user_id = get_current_user_id();
	$user_shops = get_field( 'name_field_shops', 'user_'. $user_id  );
	
	$args['posts_per_page'] = -1;
	$args['post__in'] = $user_shops;
	
  return $args;
}

En el array «$args» añadiremos los argumentos que necesitemos para modificar la consulta que vamos a realizar, al igual que hacemos cuando usamos WP_Query para filtrar resultados de POST y otros tipos de contenidos. Podéis encontrar más información sobre el filtro de ACF aquí

Asignar rangos de fechas en el calendario.

Cuando creamos formularios para reservas de vacaciones, solicitud de materiales, etc. vamos a necesitar definir una fecha de comienzo (minDate) para que el usuario no seleccione días anteriores al actual, o 7 días después, y también una fecha límite (maxDate) si fuera necesario.

Para ello usaremos la API javascript de acf, concretamente el filtro date_picker_args

(function($) {
	if (typeof(acf) != 'undefined') {
		acf.add_filter('date_picker_args', function( args, $field ){
			// donde, "+1m +7d" representa un mes y siete días a partir de hoy.
			args['minDate'] = '+4d';
			// args['maxDate'] = '60';
           return args;      
       });
	}
})(jQuery);

La mejor forma de integrar el código JavaScript en el desarrollo es mediante la acción «acf/input/admin_footer». Es dónde se inserta el código adicional en las páginas donde aparecen los campos ACF.

Esta acción es similar a admin_footer de WordPress, excepto que solo se activa en las páginas donde aparecen los campos ACF.

<?php

// Asignar día mínimo en el calendario
add_action('acf/input/admin_footer', 'bk_datepicker_custom');
function bk_datepicker_custom() {

    // solo lo asignaremos a la template de booking
    if ( is_page_template('page-templates/booking-holiday.php') ) {
        ?>
        <script type="text/javascript">
          
            // code  Javascript
					
        </script>
        <?php  
    }
}

?>

Y para que no afecte al resto de páginas, utilizaremos is_page_template. Así solo se insertará en las páginas que utilicen esa plantilla.

Siempre que necesitemos insertar CSS o JavaScript, usaremos la función is_page_template() si va a estar en una plantilla.

Así no añadiremos código innecesario a la página, y no afectará a la velocidad de carga de la página.

Solucionar la advertencia de «no se puede modificar la información del encabezado»

Si tenemos en nuestra plantilla la función acf_form_head, posiblemente se nos muestre el siguiente error al enviar los datos «Warning: Cannot modify header information – headers already sent by (output started at … ».

Lo normal es que utilicemos la función directamente en la plantilla de la siguiente manera:

*!
* template Name: Contact.
*/

acf_form_head();
get_header();

Si os muestra ese error, tenéis que eliminar la función «acf_form_head();» del archivo ,e insertar la siguiente acción en el archivo «function.php» por ejemplo:

add_action( 'init', 'bk_add_acf_form_head' );
function bk_add_acf_form_head(){
	// Para que solo lo ejecute en el template contact.php
    if ( is_page_template('page-templates/contact.php') ) {
        acf_form_head();
    }
}

Como veis, volvemos a utilizar la función «is_page_template» para no llame a los archivos CSS y JavaScript necesarios para que funcionen los formularios de ACF en la parte Frontend.

… Y esto no es todo

Con el paso del tiempo iremos añadiendo contenido útil para crear formularios con el plugin ACF (Advanced Custom Fields), y comprobaréis lo fácil y práctico que es utilizarlo sin necesidad de utilizar otros plugin.