Introduction
Being able to dynamically populate the values in a select (aka drop down) field is a common requirement for product selection forms, product option forms, or any form that requires earlier submissions to drive choices in a latter collection field.
This walkthrough will teach you how to configure a specific example of this population, using custom code to present a list of existing posts as options in the drop down.
Third Party Options
If you are not comfortable with custom code or require more complex capabilities, check for third-party solutions across popular WordPress plugin repositories and in our Community Add-On Library.
Custom Code Approach
The premise of this walkthrough is to populate the options in a Gravity Forms select field with all published posts on the site. In this example, we want to know the user’s favorite post from a dynamically generated list.
Note: Dynamic population cannot run when the page where your form is embedded is cached. This is not a Gravity Forms limitation but a consequence of using caching.
The Code
add_filter( 'gform_pre_render_123', 'populate_posts' );
add_filter( 'gform_pre_validation_123', 'populate_posts' );
add_filter( 'gform_pre_submission_filter_123', 'populate_posts' );
add_filter( 'gform_admin_pre_render_123', 'populate_posts' );
function populate_posts( $form ) {
foreach ( $form['fields'] as &$field ) {
if ( $field->type != 'select' || strpos( $field->cssClass, 'populate-posts' ) === false ) {
continue;
}
// you can add additional parameters here to alter the posts that are retrieved
// more info: https://developer.wordpress.org/reference/functions/get_posts/
$posts = get_posts( 'numberposts=-1&post_status=publish' );
$choices = array();
foreach ( $posts as $post ) {
$choices[] = array(
'text' => esc_html( $post->post_title ),
'value' => $post->post_title
);
}
// update 'Select a Post' to whatever you'd like the instructive option to be
$field->placeholder = 'Select a Post';
$field->choices = $choices;
}
return $form;
}
This code should be pasted in your theme’s functions.php file.
The Hooks
This code uses four different hooks to ensure the field is populated correctly in all contexts:
| Hook | Purpose |
|---|---|
gform_pre_render | Populates choices when the form is displayed on the front end |
gform_pre_validation | Ensures choices are available during form validation |
gform_pre_submission_filter | Maintains choices during form submission processing |
gform_admin_pre_render | Populates choices when viewing entries in the admin |
add_filter( 'gform_pre_render_123', 'populate_posts' );
add_filter( 'gform_pre_validation_123', 'populate_posts' );
add_filter( 'gform_pre_submission_filter_123', 'populate_posts' );
add_filter( 'gform_admin_pre_render_123', 'populate_posts' );
Custom Filter Function
In this example, our custom filter function is titled populate_posts. Since we told Gravity Forms to call this function from the filter, Gravity Forms will also send the gform_pre_render$form object as a parameter to this function. This means we can modify the $form object with this function and return our changes at the end.
Looping Through the Fields
foreach ( $form['fields'] as $field ) { ... }
Since we have the $form object, we loop through the fields in the form and find the field(s) we’d like to modify. Note the &$field syntax, which passes the field by reference, allowing us to modify the actual field object rather than a copy.
if ( $field->type != 'select' || strpos( $field->cssClass, 'populate-posts' ) === false ) {
continue;
}
We only want to modify fields that are select (drop down) fields AND have a CSS class titled populate-posts. We could check for the field ID instead of a CSS class. However, if we ever change our form we’d have to update the code to match the new field ID. Using a CSS class to identify our desired field lets us target it directly from the Gravity Forms admin.
If the current field in the loop is not a select OR does not have our designated CSS class, we simply skip it and move on to the next.
Get the Posts
Now it’s time to get an array of all the posts to display in our drop down.
$posts = get_posts( 'numberposts=-1&post_status=publish' );
get_posts() is a WordPress function that returns an array of posts based on the parameters you provide it. For more information on how to modify which posts are returned, see the WordPress developer documentation.
Quick Tip: You can retrieve any kind of post type here, even custom post types. Just pass the name of your post type with the post_type parameter:
$posts = get_posts( 'post_type=event&numberposts=-1&post_status=publish' );
You can also filter by taxonomy terms:
$posts = get_posts( array(
'post_type' => 'product',
'numberposts' => -1,
'post_status' => 'publish',
'tax_query' => array(
array(
'taxonomy' => 'product_category',
'field' => 'slug',
'terms' => 'featured'
)
)
) );
Creating an Array of Choices
The way Gravity Forms handles fields with multiple options (such as a select field) is with a choices property for the field, which contains an array of options. Each option consists of:
| Property | Description |
|---|---|
text | What the user will see in the drop down |
value | What will be recorded by Gravity Forms |
isSelected | Whether the option is currently selected |
price | Applies only to pricing fields |
In our scenario, we are only concerned with the text and value properties.
$choices = array();
The first thing we do is create an array to store all of our options.
foreach ( $posts as $post ) {
$choices[] = array(
'text' => esc_html( $post->post_title ),
'value' => $post->post_title
);
}
Next, we loop through the posts retrieved with get_posts() and create an option array for each post. For the text property, we use the Post Title wrapped in esc_html() for security. For the value property, we use the same title. In some cases you may want to collect the ID of the selected post. If so, you’d use $post->ID instead of $post->post_title. However, for our goal of recording the user’s favorite post, the post title is sufficient.
$field->choices = $choices;
Once we’ve looped through all posts and created all our options, we assign the $choices array (which contains all our new options) to the $field->choices property.
Add a Placeholder Choice
$field->placeholder = 'Select a Post';
We also want to make the first option in the drop down a placeholder choice. It lets the user know what they should do with this dropdown (e.g., “Select a Post”). We do this by assigning the choice text to the field’s placeholder property.
When the drop down is rendered on the form, the placeholder choice will have an empty value for the value property. This ensures that if this field is required, the user must select an option other than the placeholder. Failing to do so will generate a validation error.
What about Checkboxes?
Checkbox fields can also be dynamically populated, but they require additional handling since their structure is created by a fieldset of inputs and choices. The process is similar but requires working with the inputs property as well as the choices property. See in the gform_pre_render documentation for more information.