Dynamic Dropdown Fields in ACF

Advanced Custom Fields is a powerful tool for building metaboxes, theme settings, custom blocks, and more.

The acf/load_field filter lets you customize a field before it loads. I often use it for dynamically populating dropdown lists.

These code snippets can go in your theme’s functions.php file or a Core Functionality plugin.

Selecting a form

When a site contains multiple forms that might need to change over time, I like to create a site options page for managing which forms appear where.

The acf/load_field filter runs before each field loads. I’ll then check to see if the field name matches the ones I have for the Subscribe and User Registration forms, and if so I’ll populate $field['choices'] with all the forms we have on the site.

I’m using WPForms so will use wpforms()->forms->get() to list all forms, but you could do the same thing with Gravity Forms (example) or any other form plugin.

/** * Dynamically select form in ACF * @link https://www.billerickson.net/dynamic-dropdown-fields-in-acf/ * @author Bill Erickson * * @param array $field, the field settings array * @return array $field */ function be_acf_select_form( $field ) { // These are the field names we're updating $form_fields = array( 'ea_subscribe_form', 'ea_registration_form,' ); if( ! in_array( $field['name'], $form_fields ) ) return $field; // Get form list from WPForms if( ! function_exists( 'wpforms' ) ) return $field; $forms = wpforms()->form->get(); // Build list of choices $field['choices'] = array( 0 => '(None)' ); foreach( $forms as $form ) { $field['choices'][ $form->ID ] = $form->post_title; } return $field; } add_filter( 'acf/load_field', 'be_acf_select_form' );

When you need to display the form, you pull the form ID from the Site Options page.

Using ACF function: get_field( 'ea_subscribe_form', 'options' );
Using WP function: get_option( 'options_ea_subscribe_form' );

Display WPForm: wpforms_display( $form_id )
Display Gravity Form: gravity_form( $form_id )

I use this approach to define theme locations for forms, which adds a class of .location-subscribe to the subscribe form. I can then style the form using this class rather than the form ID, which ensures the styling continues to work if the form assigned to the “Subscribe” location changes.

Selecting an icon

On my homepage I have an Industries block with an icon for each industry.

WordPress Developer for…


Your website needs a captivating design that keeps readers engaged and loads fast at scale.

Food Bloggers

Your website needs a recipe-centric design that allows your content to shine and projects your unique voice.


Your website needs flexible landing pages that are easy to build, showcase your brand, and optimized to convert.


Your website needs to reflect the quality and professionalism of your practice, and rank high in local search results.

The icons are stored as SVGs in my theme’s /assets/icons/category directory. In the ACF block metabox, the select dropdown dynamically lists all icons in that directory.

Since I want this to only apply to a single field (name=”icon”), we can use a more specific filter: acf/load_field/name=icon.

/** * Dynamically select icon in ACF * @link https://www.billerickson.net/dynamic-dropdown-fields-in-acf/ * @author Bill Erickson * * @param array $field, the field settings array * @return array $field */ function be_acf_select_icon( $field ) { $field['choices'] = array( 0 => '(None)' ); $icons = ea_get_theme_icons( 'category' ); foreach( $icons as $icon ) { $field['choices'][ $icon ] = $icon; } return $field; } add_filter( 'acf/load_field/name=icon', 'be_acf_select_icon' ); /** * Get Theme Icons * Refresh cache by bumping CHILD_THEME_VERSION */ function ea_get_theme_icons( $directory = 'utility' ) { $icons = get_option( 'ea_theme_icons_' . $directory ); $version = get_option( 'ea_theme_icons_' . $directory . '_version' ); if( empty( $icons ) || ( defined( 'CHILD_THEME_VERSION' ) && version_compare( CHILD_THEME_VERSION, $version ) ) ) { $icons = scandir( get_stylesheet_directory() . '/assets/icons/' . $directory ); $icons = array_diff( $icons, array( '..', '.' ) ); $icons = array_values( $icons ); if( empty( $icons ) ) return $icons; // remove the .svg foreach( $icons as $i => $icon ) { $icons[ $i ] = substr( $icon, 0, -4 ); } update_option( 'ea_theme_icons_' . $directory, $icons ); if( defined( 'CHILD_THEME_VERSION' ) ) update_option( 'ea_theme_icons_' . $directory . '_version', CHILD_THEME_VERSION ); } return $icons; }

To display the icon, we use the ea_icon() function in our theme (see here).

$icon = get_field( 'icon' ); if( !empty( $icon ) ) echo ea_icon( array( 'icon' => $icon, 'group' => 'category' ) );

Bill Erickson

Bill Erickson is a freelance WordPress developer and a contributing developer to the Genesis framework. For the past 14 years he has worked with attorneys, publishers, corporations, and non-profits, building custom websites tailored to their needs and goals.

Ready to upgrade your website?

I build custom WordPress websites that look great and are easy to manage.

Let's Talk

Reader Interactions


  1. Cisco says

    Hi Bill,

    I’m starting with ACF to create Gutemberg Blocks. My goal is to create a block where the editor can create a list of resource links. These links can be external or internal resources (for this last one, it can be a link to a page or a link to a media from the library). I’m trying to find a way to dynamically display the relevant icon depending of the file format of the resource (usually .pdf, .doc or .xls) and also a different icon if the resource is external or internal. What is the best approach ? Doing it conditioning with ACF or programming with a php function ? Thanks in advance if you have a clue or a resource (internal or external i’m ok 🙂

    • Bill Erickson says

      I’d use PHP code in your theme to do that. In ACF you’d probably have a dropdown with three options: page link, media file, or external link. If they select a media file, ACF will give you the attachment ID and you can use get_post_mime_type() to figure out what type of attachment it is (more information).

Leave A Reply