Dynamic Forms

Manage Advanced ACF Forms from the WordPress administration. This module is an enhanced version of the native ACF Form feature. While all native settings can used, Dynamic Forms adds many new settings and introduce “Actions” for a complete control over the form behavior.

Dynamic Form

The unique form slug

Render & map fields of the following field groups

Add actions on form submission

Click the "Add action" button below to start creating your layout
0 Custom action

Set a unique action slug

0 Email action
0 Option action

(Optional) Target this action using hooks.

Choose which ACF fields should be saved to this option

Fill inputs with values

Choose which ACF fields should have their values loaded

0 Post action

(Optional) Target this action using hooks.

Click to initialize TinyMCE

Choose which ACF fields should be saved to this post

Fill inputs with values

Choose which ACF fields should have their values loaded

0 Redirect action

(Optional) Target this action using hooks.

The URL to redirect to. See "Cheatsheet" tab for all available template tags.

0 Term action

(Optional) Target this action using hooks.

Click to initialize TinyMCE

Choose which ACF fields should be saved to this term

Fill inputs with values

Choose which ACF fields should have their values loaded

0 User action

(Optional) Target this action using hooks.

Click to initialize TinyMCE

Choose which ACF fields should be saved to this user

Fill inputs with values

Choose which ACF fields should have their values loaded

1 Post action

(Optional) Target this action using hooks.

Click to initialize TinyMCE

Choose which ACF fields should be saved to this post

Fill inputs with values

Choose which ACF fields should have their values loaded

Apply field groups locations rules for front-end display

Whether or not to create a <form> element

Form class and id

class
id

Add class to all fields

wrapper class
input class

Whether or not to create a form submit button. Defaults to true

The text displayed on the submit button

HTML used to render the submit button.

HTML used to render the submit button loading spinner.

Whether to include a hidden input field to capture non human form submission. Defaults to true.

Whether or not to sanitize all $_POST data with the wp_kses_post() function. Defaults to true.

Whether to use the WP uploader or a basic input for image and file fields. Defaults to 'wp' Choices of 'wp' or 'basic'.

Determines element used to wrap a field. Defaults to 'div'

Determines where field labels are places in relation to fields. Defaults to 'top'.
Choices of 'top' (Above fields) or 'left' (Beside fields)

Determines where field instructions are places in relation to fields. Defaults to 'label'.
Choices of 'label' (Below labels) or 'field' (Below fields)

Override the native field groups HTML render

Extra HTML to add before the fields

Render your own customized HTML.

Field groups may be included using {field_group:group_key}
{field_group:Group title}

Fields may be included using {field:field_key}
{field:field_name}

Extra HTML to add after the fields

Hide the general error message: "Validation failed. 1 field requires attention"

Hide the successful notice when an error has been thrown

Do not prompt user on page refresh

Choose where to display field errors

Add class to error message

Hide form on successful submission

A message displayed above the form after being redirected. See "Cheatsheet" tab for all available template tags.

HTML used to render the updated message.
If used, you have to include the following code %s to print the actual "Success message" above.

Retrieve user input from the current form

{field:field_5e5c07b6dfae9}User input
{field:my_field}User input
{field:my_field:false}User input (unformatted)

Retrieve all user inputs from the current form

{fields}My text: User input

My textarea: User input

My date: 2020-03-01

Retrieve ACF field value from database

{get_field:my_field}DB value (current post)
{get_field:my_field:current}DB value (current post)
{get_field:my_field:128}DB value (post:128)
{get_field:my_field:128:false}DB value (post:128 - unformatted)

Retrieve option value from database

{get_option:my_option}DB value
{get_option:my_option_array:key}DB value

Retrieve $_REQUEST value

{request:name}$_REQUEST['name']
{request:name:key}$_REQUEST['name']['key']

Retrieve query var values. Can be used to get data from previous action

{query_var:name}value
{query_var:name:key}Array value

Retrieve current Dynamic Form data

{form}11
{form:ID}11
{form:title}Form
{form:name}form
{form:custom_key}Custom key value

Retrieve actions output

Last Post Action
{action:post:ID}128
{action:post:post_title}Title
{action:post:admin_url}https://www.acf-extended.com/wp-admin/post.php?post=128&action=edit
{action:post:permalink}https://www.acf-extended.com/my-post
{action:post:post_author}1
{action:post:post_author_data:user_login}login
{action:post:post_author_data:permalink}https://www.acf-extended.com/author/johndoe
See {current:post} for all available tags

Post Action Named my-post
{action:my-post:ID}128
{action:my-post:post_title}Title
{action:my-post:admin_url}https://www.acf-extended.com/wp-admin/post.php?post=128&action=edit
{action:my-post:permalink}https://www.acf-extended.com/my-post
{action:my-post:post_author}1
{action:my-post:post_author_data:user_login}login
{action:my-post:post_author_data:permalink}https://www.acf-extended.com/author/johndoe
See {current:post} for all available tags

Retrieve actions output

Last Term Action
{action:term:ID}23
{action:term:post_title}Term
{action:term:admin_url}https://www.acf-extended.com/wp-admin/term.php?tag_ID=23
{action:term:permalink}https://www.acf-extended.com/taxonomy/term
See {current:term} for all available tags

Term Action Named my-term
{action:my-term:ID}23
{action:my-term:post_title}Term
{action:my-term:admin_url}https://www.acf-extended.com/wp-admin/term.php?tag_ID=23
{action:my-term:permalink}https://www.acf-extended.com/taxonomy/term
See {current:term} for all available tags

Retrieve actions output

Last User Action
{action:user:ID}1
{action:user:user_login}login
{action:user:user_email}user@domain.com
{action:user:user_url}https://www.website.com
{action:user:permalink}https://www.acf-extended.com/author/johndoe
See {current:user} for all available tags

User Action Named my-user
{action:my-user:ID}1
{action:my-user:user_login}login
{action:my-user:user_email}user@domain.com
{action:my-user:user_url}https://www.website.com
{action:my-user:permalink}https://www.acf-extended.com/author/johndoe
See {current:user} for all available tags

Retrieve actions output

Last Email Action
{action:email:from}Contact
{action:email:to}email@domain.com
{action:email:reply_to}email@domain.com
{action:email:cc}email@domain.com
{action:email:bcc}email@domain.com
{action:email:subject}Subject
{action:email:content}Content

Email Action Named my-email
{action:my-email:from}Contact
{action:my-email:to}email@domain.com
{action:my-email:reply_to}email@domain.com
{action:my-email:cc}email@domain.com
{action:my-email:bcc}email@domain.com
{action:my-email:subject}Subject
{action:my-email:content}Content

Retrieve current post data (where the form is being printed)

{current:post}128
{current:post:ID}128
{current:post:post_date}2020-03-01 20:07:48
{current:post:post_date_gmt}2020-03-01 19:07:48
{current:post:post_content}Content
{current:post:post_title}Title
{current:post:post_excerpt}Excerpt
{current:post:permalink}https://www.acf-extended.com/my-post
{current:post:admin_url}https://www.acf-extended.com/wp-admin/post.php?post=128&action=edit
{current:post:post_status}publish
{current:post:comment_status}closed
{current:post:ping_status}closed
{current:post:post_password}password
{current:post:post_name}name
{current:post:to_ping}
{current:post:pinged}
{current:post:post_modified}2020-03-01 20:07:48
{current:post:post_modified_gmt}2020-03-01 19:07:48
{current:post:post_content_filtered}
{current:post:post_parent}0
{current:post:guid}https://www.acf-extended.com/?page_id=128
{current:post:menu_order}0
{current:post:post_type}page
{current:post:post_mime_type}
{current:post:comment_count}0
{current:post:filter}raw
{current:post:post_author}1
{current:post:post_author_data:ID}1
{current:post:post_author_data:user_login}login
{current:post:post_author_data:user_pass}password_hash
{current:post:post_author_data:user_nicename}nicename
{current:post:post_author_data:user_email}user@domain.com
{current:post:post_author_data:user_url}https://www.website.com
{current:post:post_author_data:permalink}https://www.acf-extended.com/author/johndoe
{current:post:post_author_data:admin_url}https://www.acf-extended.com/wp-admin/user-edit.php?user_id=1
{current:post:post_author_data:user_registered}2020-02-22 22:10:02
{current:post:post_author_data:user_activation_key}
{current:post:post_author_data:user_status}0
{current:post:post_author_data:display_name}John Doe
{current:post:post_author_data:nickname}JohnDoe
{current:post:post_author_data:first_name}John
{current:post:post_author_data:last_name}Doe
{current:post:post_author_data:description}Lorem ipsum dolor sit amet, consectetur adipiscing elit.
{current:post:post_author_data:rich_editing}true
{current:post:post_author_data:syntax_highlighting}true
{current:post:post_author_data:comment_shortcuts}false
{current:post:post_author_data:admin_color}fresh
{current:post:post_author_data:use_ssl}1
{current:post:post_author_data:show_admin_bar_front}true
{current:post:post_author_data:locale}
{current:post:post_author_data:wp_capabilities}a:1:{s:13:"administrator";b:1;}
{current:post:post_author_data:wp_user_level}10
{current:post:post_author_data:dismissed_wp_pointers}
{current:post:post_author_data:show_welcome_panel}1

Retrieve current term data (where the form is being printed)

{current:term}23
{current:term:ID}23
{current:term:term_id}23
{current:term:name}Term
{current:term:slug}term
{current:term:permalink}https://www.acf-extended.com/taxonomy/term
{current:term:admin_url}https://www.acf-extended.com/wp-admin/term.php?tag_ID=23
{current:term:term_group}0
{current:term:term_taxonomy_id}23
{current:term:taxonomy}taxonomy
{current:term:description}Content
{current:term:parent}0
{current:term:count}0
{current:term:filter}raw

Retrieve currently logged user data

{current:user}1
{current:user:ID}1
{current:user:user_login}login
{current:user:user_pass}password_hash
{current:user:user_nicename}nicename
{current:user:user_email}user@domain.com
{current:user:user_url}https://www.website.com
{current:user:permalink}https://www.acf-extended.com/author/johndoe
{current:user:admin_url}https://www.acf-extended.com/wp-admin/user-edit.php?user_id=1
{current:user:user_registered}2020-02-22 22:10:02
{current:user:user_activation_key}
{current:user:user_status}0
{current:user:display_name}John Doe
{current:user:nickname}JohnDoe
{current:user:first_name}John
{current:user:last_name}Doe
{current:user:description}Lorem ipsum dolor sit amet, consectetur adipiscing elit.
{current:user:rich_editing}true
{current:user:syntax_highlighting}true
{current:user:comment_shortcuts}false
{current:user:admin_color}fresh
{current:user:use_ssl}1
{current:user:show_admin_bar_front}true
{current:user:locale}
{current:user:wp_capabilities}a:1:{s:13:"administrator";b:1;}
{current:user:wp_user_level}10
{current:user:dismissed_wp_pointers}
{current:user:show_welcome_panel}1

Retrieve current post author data (where the form is being printed)

{current:author}1
{current:author:ID}1
{current:author:user_login}login
{current:author:user_pass}password_hash
{current:author:user_nicename}nicename
{current:author:user_email}user@domain.com
{current:author:user_url}https://www.website.com
{current:author:permalink}https://www.acf-extended.com/author/johndoe
{current:author:admin_url}https://www.acf-extended.com/wp-admin/user-edit.php?user_id=1
{current:author:user_registered}2020-02-22 22:10:02
{current:author:user_activation_key}
{current:author:user_status}0
{current:author:display_name}John Doe
{current:author:nickname}JohnDoe
{current:author:first_name}John
{current:author:last_name}Doe
{current:author:description}Lorem ipsum dolor sit amet, consectetur adipiscing elit.
{current:author:rich_editing}true
{current:author:syntax_highlighting}true
{current:author:comment_shortcuts}false
{current:author:admin_color}fresh
{current:author:use_ssl}1
{current:author:show_admin_bar_front}true
{current:author:locale}
{current:author:wp_capabilities}a:1:{s:13:"administrator";b:1;}
{current:author:wp_user_level}10
{current:author:dismissed_wp_pointers}
{current:author:show_welcome_panel}1

Getting Started

Just like ACF Forms, first you need to create a Field Group that will contain the form’s fields. You can then create a new form from the ACF > Forms menu and assign that field group to the form. Once saved, the form will now map the Fields from the Field Group. This means those fields will be usable directly from the UI.

Out-of-the-box, the form will do nothing on submission. You’ll have to add one or multiple actions to define what you want to do with the form. Once correctly configured, you can display the form using acfe_form() function or [acfe_form] shortcode. Usage example:

<?php get_header(); ?>

    <?php 
    
    // Using Form Name
    acfe_form('my-form');
    
    // Using Form ID
    acfe_form(120);
    
    // Using Form Array
    acfe_form(array(
        'name' => 'my-form'
    ));
    
    ?>
    
<?php get_footer(); ?>

Override Settings

You can override form settings directly in PHP by passing the setting key and its value.

acfe_form(array(
    'name'                         => 'my-form',                // Call by name
    'acfe_form_uploader'           => 'basic',                  // Force Uploader to basic
    'acfe_form_html_submit_button' => '<button>Submit</button>' // Change Submit Button 
));

Pass Custom Data

It is possible to pass custom data to the form using PHP. Those data can then be retrieved in the UI using the {form:my_user} Template Tag or in hooks using the $form['my_user'] parameter.

acfe_form(array(
    'name'    => 'my-form',
    'my_user' => get_current_user_id() // Add Current User ID
));

Custom data can also be passed using the acfe/form/load filter. Usage example:

add_filter('acfe/form/load/form=my-form', 'my_form_settings', 10, 2);
function my_form_settings($form, $post_id){
    
    // Add Current User ID
    $form['my_user'] = get_current_user_id();
    
    // Return
    return $form;
    
}

Template Tags

Templates Tags are UI helpers that retrieve & print dynamic content. There are different types of templates tags that retrieving different types of data.

Template TagOutput
{field:field_5e5c07b6dfae9}User field input
{field:my_field}User field input
{field:my_field:false}User field input (unformatted)
{fields}My text: User input

My textarea: User input

My date: 2020-03-01

{get_field:my_field}DB value (current post)
{get_field:my_field:current}DB value (current post)
{get_field:my_field:128}DB value (post:128)
{get_field:my_field:128:false}DB value (post:128 – unformatted)
{get_option:my_option}get_option('my_option') value
{get_option:my_option:key}get_option('my_option')['key'] value
{request:name}$_REQUEST['name'] value
{request:name:key}$_REQUEST['name']['key'] value
{query_var:name}get_query_var('name') value
{query_var:name:key}get_query_var('name')['key'] value
{current:post}Current Post ID
{current:post:parameter}Current Post parameter (such as post_title, post_content, post_date etc…)
{current:term}Current Term ID
{current:term:parameter}Current Term parameter (such as name, description etc…)
{current:user}Current User ID
{current:user:parameter}Current User parameter (such as user_login, user_email etc…)
{current:author}Current Post Author ID
{current:author:parameter}Current Post Author parameter (such as user_login, user_email etc…)
{form}Current Form ID
{form:parameter}Current Form parameter

Forms Hooks

Dynamic Forms are bundled with general hooks allowing you to change the form settings, add validation rules and trigger a custom action on submission. Those hooks are tied to forms, and act independently from Actions.

Get Field

The get_field() function used in form & actions hooks allows to retrieve the fields input that are entered by the user during the form submission. In order to retrieve the field value from the database, you must set a valid post ID reference.

Template TagOutput
get_field('my_field')“my_field” Field input
get_field('my_field', 128)“my_field” DB value

Loading Hook

The acfe/form/load fitler is used to change the form settings, right before it is rendered on the page. Note that fields inputs cannot be retrieved using get_field() here, as the form hasn’t been submitted yet. Usage example:

/*
 * Form Load
 * 
 * @array   $form     Form settings
 * @string  $post_id  Post ID (where the form is displayed)
 */
 
filter('acfe/form/load',              $form, $post_id);
filter('acfe/form/load/form=my-form', $form, $post_id);
add_filter('acfe/form/load/form=my-form', 'my_form_load', 10, 2);
function my_form_load($form, $post_id){
    
    // Change form success message dynamically
    $form['updated_message'] = 'New success message!';
    
    // Change form redirection URL
    $form['return'] = '/thank-you';
    
    // Hide the form
    // return false;
    
    // Return
    return $form;
    
}

Validation Hook

The acfe/form/validation action is used to add rules during the ajax form validation process, before form submission.

Unlike the acf/validate_value hook which validate each fields values individually, acfe/form/validation will validate the whole form. It can be used to check one field against an another.

The acfe_add_validation_error() function should be used to return an error. It is possible to return a general error by omitting to reference a field’s name. Example: acfe_add_validation_error('', 'General error message'). Usage example:

/*
 * Form Validation
 * 
 * @array   $form     Form settings
 * @string  $post_id  Post ID (where the form is displayed)
 */
 
action('acfe/form/validation',              $form, $post_id);
action('acfe/form/validation/form=my-form', $form, $post_id);
add_action('acfe/form/validation/form=my-form', 'my_form_validation', 10, 2);
function my_form_validation($form, $post_id){
    
    // Get field input value
    $my_field = get_field('my_field');
    
    if($my_field === 'Company'){
        
        // Add validation error
        acfe_add_validation_error('my_field', 'The value Company is not allowed');
        
    }
    
}

Submission Hook

The acfe/form/submit action is used to trigger a custom script on form submission, after its validation. Usage example:

/*
 * Form Submit
 * 
 * @array   $form     Form settings
 * @string  $post_id  Post ID (where the form is displayed)
 */
 
action('acfe/form/submit',              $form, $post_id);
action('acfe/form/submit/form=my-form', $form, $post_id);
add_action('acfe/form/submit/form=my-form', 'my_form_submit', 10, 2);
function my_form_submit($form, $post_id){
    
    // Get field input value
    $my_field = get_field('my_field');
    
    if($my_field === 'Company'){
    
        // Do something...
    
    }
    
}

Forms Actions

Actions are pre-defined templates that trigger a specific behavior. There can be an unlimited number of Actions per form. While every Actions have unique features like create a post, a user or send an e-mail, they also have their own validation & submit hooks.

Form Actions also have their own specific hooks that allow you to change their behavior. Learn more about Actions:

Export/Import Forms

It is possible to export and import Forms in a Json file using the ACF > Tools menu or directly within the Dynamic Forms UI.

Disable The Module

This module is enabled by default. To disable it, you can use the following code:

add_action('acf/init', 'my_acfe_modules');
function my_acfe_modules(){

    // Disable Dynamic Forms
    acfe_update_setting('modules/dynamic_forms', false);
    
    // Or:
    acf_update_setting('acfe/modules/dynamic_forms', false);
    
}