Using Values from A Form-Tag

The previous recipe illustrated how you can add custom form-tags simply. In this recipe, you’ll learn how to retrieve values from a form-tag and use those values in the HTML output in a form.

We are going to create a custom form-tag that represents an input field with an associated datalist. Datalist is a new element introduced in HTML5; it provides a list of predefined options for an input field associated with a datalist.

The following listing shows an example HTML markup for a text input field and a datalist.

<input name="currency" type="text" list="currency-options" />
<datalist id="currency-options">
	<option>U.S. Dollars ($)</option>
	<option>Euros (€)</option>
</datalist>

In this example, the list attribute of the input element and the id attribute of the datalist element share the same value (“currency-options”), thus the two elements are associated with each other.

This input field expects a currency name. While you can type an arbitrary currency name here, it provides “U.S. Dollars ($)” and “Euros (€)” as predefined options because they are the most likely answers.

Screenshot of an example datalist.

Designing a Form-Tag

Let’s design the form-tag for an input field with a datalist. First, you need to decide the type of form-tag. Let’s name it “datalist”.

You can see three variables in the HTML markup in the listing above: the name attribute value (“currency” in the example), the list and id attribute values (“currency-options”), and the option element contents (“U.S. Dollars ($)” and “Euros (€)”).

The list and id attributes need to have the same value, and it doesn’t matter what that value is (as long as it is valid as an id value). If the value can be automatically defined, say, by adding a suffix -options to the name attribute value, you can reduce the number of variables. Now, you only have to define the name attribute value and option element contents in the form-tag.

For the name attribute value, let’s use the name part (the second word) in a form-tag because it’s commonly used for the name attribute value in other form-tag types of Contact Form 7.

For the option element contents, since the contents are likely to be in a free format, using the values part (quoted strings; the final part) in a form-tag is suitable.

See also: How Tags Work

To sum up these design decisions, the following simple form-tag should be able to represent the example HTML markup in the listing above:

[datalist currency "U.S. Dollars ($)" "Euros (€)"]

Let’s start coding to implement this form-tag.

Implementing the Form-Tag

First, register the “datalist” form-tag type with wpcf7_add_shortcode() function. Unlike the [clock] form-tag that we saw in the previous recipe, this tag has a name part so you need to set the third argument of wpcf7_add_shortcode() to true.

add_action( 'wpcf7_init', 'custom_add_shortcode_datalist' );

function custom_add_shortcode_datalist() {
	wpcf7_add_shortcode( 'datalist', 'custom_datalist_shortcode_handler', true );
}

Then, define the callback function that generates HTML output.

function custom_datalist_shortcode_handler( $tag ) {
	$tag = new WPCF7_FormTag( $tag );

	$atts = array(
		'type' => 'text',
		'name' => $tag->name,
		'list' => $tag->name . '-options' );

	$input = sprintf(
		'<input %s />',
		wpcf7_format_atts( $atts ) );

	$datalist = '';

	foreach ( $tag->values as $val ) {
		$datalist .= sprintf( '<option>%s</option>', esc_html( $val ) );
	}

	$datalist = sprintf(
		'<datalist id="%1$s">%2$s</datalist>',
		$tag->name . '-options',
		$datalist );

	return $input . $datalist;
}

The $tag argument, which is passed to the callback function as its only parameter, is originally a multi-dimensional associative array composed of given form-tag components. A WPCF7_FormTag object wraps it up to make it easy to handle. The WPCF7_FormTag object generated at the beginning of the function is used throughout the function.

In this function, you first create the input element. There, you set the necessary attributes (type, name, and list) as items of an array ($atts), and then using wpcf7_format_atts() function, you generate a formatted attribute string. Using wpcf7_format_atts() is recommended because it properly escapes values to provide a secure output.

Then, you build the datalist element that contains child option elements with the values from the form-tag. Finally, the input and datalist elements are concatenated and returned as the result of this function.

That’s it. This form-tag is still too simple and doesn’t even provide user-input validation. Upcoming recipes will deal with validation.