With some PHP code it’s really easy to dynamically populate an Advanced Custom Fields (ACF) value or choices. You can do this for any kind of inputs, including the choices of radio, checkboxes and similar. In this post we’ll look at how.

The filter

Advanced Custom Fields offers a filter named acf/load_field. You can use this filter in several different ways. Either filter acf/load_field to apply it to all kind of fields or include code inside your hooked function to figure out which field type or name you want. Or you can specify either field type (acf/load_field/type=<type>), name (acf/load_field/name=<name>), or key (acf/load_field/key=<key>).

Assume we create a text field like so:

We could target this by acf/load_field/name=dyn_pop_example (targets only this specific field), acf/load_field/type=text (applies to all fields of type text), or acf/load_field (applies to all fields of any type or name). When using the last two filters you can of course inside the function target by specific field information, such as name. Each field in ACF gets an unique key as well, but they are hidden and are mostly for ACF’s internal use.

The filter provides one variable; the field array. This array gives you all the information about the current field. What you do is simply changing the information in the array and return the modified field array. Depending on the type of field the elements in the array differ. For example multi-choice field types such as select and radioboxes will have an array element ‘choices‘ that fields of e.g. type text won’t have. I recommend that you do a var_dump() of the provided array to see what kind of information you have access to.

Let’s start looking into some actual code!

Population: simple examples

Setting the default value of a text input would look something like this:

add_filter('acf/load_field/name=dyn_pop_example', function($field) {
	$field['default_value'] = __('This is default value', 'txtdomain');
	return $field;
});

We target our text input with the name dyn_pop_example and set its default value (key ‘default_value‘) to a string of our own choosing. The field will then render like this:

You can modify any settings to the field. In the example below we set the text’s placeholder and instructions:

add_filter('acf/load_field/name=dyn_pop_example', function($field) {
	$field['placeholder'] = __('Type in here', 'txtdomain');
	$field['instructions'] = __('Some instructions coming from code', 'txtdomain');
	return $field;
});

Which will make the field render like so:

Populate choices

If you want to dynamically populate the choices of a select, radio, or checkbox field, you do this in the array key element ‘choices‘. This ‘choices‘ element applies to all fields of type select, radio and checkbox.

The ‘choices‘ element needs to be an array of key + value pairs. The keys are the values (that will be saved) and the values are the label that appears as the choice.

Assume we change our field to a select. You can leave the choices empty as they will be set via our code.

For populating the select’s chocies we do it like this:

add_filter('acf/load_field/name=dyn_pop_example', function($field) {
	$choices = [
		'red' => __('Red Color', 'txtdomain'),
		'blue' => __('Blue Color', 'txtdomain'),
		'green' => __('Green Color', 'txtdomain')
	];
	$field['choices'] = $choices;
	$field['default_value'] = 'blue';
	return $field;
});

At line #2 - #6 we simply define an array of choices. Modify this to your needs. At line #7 we assign the field’s choices to our array. For good measure we also set the field’s default value. This is not necessary – without line #8 the select would simply automatically choose the first choice in the array (‘red’).

The above code will render the field like so:

The choices are up to you, all you need to take care of is providing a proper key + value array to the field’s ‘choices‘ element. As a basic example this code example shows how you can turn a normal select field into a choice of posts.

add_filter('acf/load_field/name=dyn_pop_example', function($field) {
	$posts = new WP_Query([
		'post_type' => 'page',
		'posts_per_page' => -1
	]);
	$choices = [];
	while ($posts->have_posts()) { 
		$posts->the_post();
		$choices[get_the_ID()] = get_the_title();
	}
	wp_reset_query();
	$field['choices'] = $choices;
	return $field;
});

Thecode example above makes a post query fetching all pages and populates the choice array with post IDs as keys and the post titles as values. This is just as an example; if you are going to make a choice of posts ACF offers other field types specifically for this.