Select fields, checkboxes, and radio buttons are selection-based form fields since they provide predetermined options for users to choose from, unlike other form field types that are text-based. Contact Form 7 – Dynamic Text Extension (DTX) makes dynamically pulling in these options easier!
Return options as JSON in Custom Shortcode
The simplest of the return methods, you can write your custom shortcode to return a JSON string with it’s key/value pairs representing your choice’s values and labels.
For example, I’ve written this custom shortcode that dynamically pulls all posts of the product post type that are assigned the wordpress-plugin category of a custom product_cat taxonomy. Meaning, I want all of my WordPress plugin products to display as options!
/**
* Get WordPress Product Options for DTX
*
* @return string JSON encoded string of WordPress plugin products
*/
function au_dtx_demo_get_wordpress_plugin_options()
{
// Define my options array
$options = array();
// Get my products
$products = get_posts(array(
'fields' => 'ids', // Returns an array of ids
'post_type' => 'product', // Custom product post type
'post_status' => 'publish', // Only published products
'posts_per_page' => -1, // Get all of them
'orderby' => 'title', // Order by product title
'order' => 'ASC', // Sort alphabetically from A to Z
'ignore_sticky_posts' => false, // move featured products to the start
'tax_query' => array(array(
// Only get products assigned to my WordPress Plugin category
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => 'wordpress-plugin',
'include_children' => true,
'operator' => 'IN'
))
));
// Add products to the $options array
if (is_array($products) && count($products)) {
foreach ($products as $product_id) {
// Use the product ID as the option's value and the product's title as the label
$options[$product_id] = get_the_title($product_id);
}
}
// Return options as JSON encoded string
return json_encode($options);
}
add_shortcode('au_dtx_demo_get_wordpress_plugin_options', 'au_dtx_demo_get_wordpress_plugin_options');
Now I could use this shortcode to provide dynamic options for any of the select-based form tags like a dynamic select, dynamic checkbox, or dynamic radio buttons.
Setting the Default Value using JSON Options
In the form-tag generator, you can define the option, checkbox, or radio button that is selected by default with static text or a shortcode in the Selected Default field. This adds a default property to the form tag with the value encoded just like the dynamic placeholder.
Here’s an example of a form tag using a static pre-selected option:
[dynamic_select input_name default:hello "foo | Foo!!" "bar | BAR" "hello | Halo" "world | wurld"
And here’s an example of a form tag using the CF7_get_post_var key='post_title' shortcode for a dynamic pre-selected option:
[dynamic_select input_name default:CF7_get_post_var%20key%3D%26%2339%3Bpost_title%26%2339%3B "custom_shortcode_of_post_names"
Return options as HTML in Custom Shortcode
You can take full control over your options by writing the HTML and outputting the options/checkboxes/radio buttons yourself if needed.
For example, I’ve written this custom shortcode that dynamically pulls all posts of the product post type that are assigned the wordpress-plugin category of a custom product_cat taxonomy. Meaning, I want all of my WordPress plugin products to display as options! This does the same functionality as the example above, but outputs HTML instead of JSON.
/**
* Get WordPress Product Options for DTX
*
* @return string HTML of WordPress plugin products
*/
function au_dtx_demo_get_wordpress_plugin_options()
{
// Define my HTML string
$html = '';
// Get my products
$products = get_posts(array(
'fields' => 'ids', // Returns an array of ids
'post_type' => 'product', // Custom product post type
'post_status' => 'publish', // Only published products
'posts_per_page' => -1, // Get all of them
'orderby' => 'title', // Order by product title
'order' => 'ASC', // Sort alphabetically from A to Z
'ignore_sticky_posts' => false, // move featured products to the start
'tax_query' => array(array(
// Only get products assigned to my WordPress Plugin category
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => 'wordpress-plugin',
'include_children' => true,
'operator' => 'IN'
))
));
// Add products to the $html string
if (is_array($products) && count($products)) {
foreach ($products as $product_id) {
// Use the product ID as the option's value and the product's title as the label
$html .= sprintf('<option value="%s">%s</option>', esc_attr($product_id), esc_html(get_the_title($product_id)));
}
}
// Return options as HTML
return wp_kses($html, wpcf7dtx_get_allowed_field_properties('option'));
}
add_shortcode('au_dtx_demo_get_wordpress_plugin_options', 'au_dtx_demo_get_wordpress_plugin_options');
Now this shortcode can only dynamic options for the dynamic select and not the dynamic checkbox or dynamic radio buttons because the HTML I’m returning is specific to a <select> element.
Setting the Default Value using HTML Options
The Selected Default field in the form-tag generator, or the default property, is ignored when using this method. This is because you’re overwriting the HTML. However, you can modify your shortcode to pull the default value and check against it yourself.
For example, let’s retrieve the value of foo in a URL query. We can use the DTX helper function to do that.
$default_value = wpcf7dtx_get(array('key' => 'foo'));
Then in the part where we’re creating the HTML for the individual option, we compare the value of the option with the value from the URL, like this:
$html .= sprintf(
'<option value="%s"%s>%s</option>',
esc_attr($product_id),
$default_value == $product_id ? esc_attr(' selected') : '',
esc_html(get_the_title($product_id))
);
And so your completed code may look like this:
/**
* Get WordPress Product Options for DTX
*
* @return string HTML of WordPress plugin products
*/
function au_dtx_demo_get_wordpress_plugin_options()
{
// Define my HTML string
$html = '';
// Get default value e.g. https://example.com/?foo=123
$default_value = wpcf7dtx_get(array('key' => 'foo'));
// Get my products
$products = get_posts(array(
'fields' => 'ids', // Returns an array of ids
'post_type' => 'product', // Custom product post type
'post_status' => 'publish', // Only published products
'posts_per_page' => -1, // Get all of them
'orderby' => 'title', // Order by product title
'order' => 'ASC', // Sort alphabetically from A to Z
'ignore_sticky_posts' => false, // move featured products to the start
'tax_query' => array(array(
// Only get products assigned to my WordPress Plugin category
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => 'wordpress-plugin',
'include_children' => true,
'operator' => 'IN'
))
));
// Add products to the $html string
if (is_array($products) && count($products)) {
foreach ($products as $product_id) {
// Use the product ID as the option's value and the product's title as the label
$html .= sprintf(
'<option value="%s">%s</option>',
esc_attr($product_id), // Product ID is option's value
$default_value == $product_id ? esc_attr(' selected') : '', // Set as selected if match
esc_html(get_the_title($product_id)) // Product's title is option's label
);
}
}
// Return options as HTML
return wp_kses($html, wpcf7dtx_get_allowed_field_properties('option'));
}
add_shortcode('au_dtx_demo_get_wordpress_plugin_options', 'au_dtx_demo_get_wordpress_plugin_options');
Demos
Check out the dynamic select field, checkboxes, and radio buttons that are all using the same custom shortcode as their value in the demo forms below.
| Rendered Form Field | Form Tag |
|---|---|
|
For this dynamic select form tag, I’m also using the include_blank attribute native to Contact Form 7 select fields / drop-down menus to display a placeholder option and using the dynamic placeholder feature to change the placeholder text to “Select a WordPress Plugin” | [dynamic_select inputname placeholder:Select%20a%20WordPress%20Plugin include_blank "au_dtx_demo_get_wordpress_plugin_options"] |
|
For this dynamic checkbox form tag, I’m also using the use_label_element attribute native to Contact Form 7 checkboxes and radio buttons to wrap each checkbox in a label element so that the product name is clickable and toggles the input value too. Helps with accessibility. | [dynamic_checkbox inputname use_label_element "au_dtx_demo_get_wordpress_plugin_options"] |
|
For this dynamic radio buttons form tag, I’m also using the use_label_element attribute native to Contact Form 7 checkboxes and radio buttons to wrap each radio button in a label element so that the product name is clickable and toggles the input value too. Helps with accessibility. | [dynamic_radio inputname use_label_element "au_dtx_demo_get_wordpress_plugin_options"] |