Using values from a form-tag

Posts in the developer's cookbook category describe topics that require technical knowledge. Be warned and use the techniques at your own risk. Unless you are an experienced developer, you are strongly advised to ask a professional for support.

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_form_tag() 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_form_tag() to array( 'name-attr' => true ).

add_action( 'wpcf7_init', 'custom_add_form_tag_datalist' );
 
function custom_add_form_tag_datalist() {
  wpcf7_add_form_tag(
    'datalist',
    'custom_datalist_form_tag_handler',
    array( 'name-attr' => true )
  );
}

Then, define the callback function that generates HTML output.

function custom_datalist_form_tag_handler( $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 parameter passed to the callback function is a WPCF7_FormTag object. WPCF7_FormTag class provides several properties and methods to access information from the form-tag.

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.