woocommerce_form_field() │ WC 1.0
Used to create form fields on the checkout and shipping and payment address edit pages.
Can also be used in other places, such as in the admin panel.
Returns
String . Depending on the return parameter, outputs or returns the HTML code of the form field.
Usage
woocommerce_form_field( $key, $args, $value );
$key(string) (required)
Field name and ID if the ID parameter is not filled in the $args array.
$args(array) (required)
Array of field arguments.
$value(string)
Default value of the field.
Default: null
Parameters of the $args array
Default values:
$defaults = [
'type' => 'text',
'label' => '',
'description' => '',
'placeholder' => '',
'maxlength' => false,
'required' => false,
'autocomplete' => false,
'id' => $key,
'class' => array(),
'label_class' => array(),
'input_class' => array(),
'return' => false,
'options' => array(),
'custom_attributes' => array(),
'validate' => array(),
'default' => '',
'autofocus' => '',
'priority' => '',
];
type(string)
Type of the field. Possible options:
text
select
radio
password
datetime
datetime-local
date
month
time
week
number
email
url
tel
country – a dropdown list of countries supported by your store, which are set in WooCommerce settings.
state
Default: text
country(string)
Used only for the state field type. The name of the country from WooCommerce settings. If the field is omitted, the function will try to get the billing or shipping country value.
Default: ''
label(string)
Label of the field
Default: ''
description(string)
Description of the field that will be displayed under the field (HTML is also supported)
Default: ''
placeholder(string)
Placeholder text
Default: ''
maxlength(number)
Maximum number of allowed characters in the text
Default: false
required(boolean)
Adds an asterisk next to the label
Example: <abbr class="required" title="required">*</abbr>
Default: ''
autocomplete(string)
Turns on or off autocomplete. Possible valid values are on or off
Default: ''
id(string)
ID of the field, by default taken from the field name value passed as the first argument of the function
Default: $key
class(array)
Classes for the container of the created block
Default: array()
label_class(array)
Class for the tag
Default: array()
input_class(array)
Class for the field
Default: array()
return(boolean)
Output or return the created field
Default: false
options(array)
Only for the <select> and radio types.
Example: ['' => 'Select...', 'value_1' => 'Text']
Default: array()
custom_attributes(array)
Associative array of attributes for the <input> field.
Example: ['data-value' => 'test']
Default: array()
validate(array)
The parameter adds a class for the field wrapper validate-{any value}, which will be used during JS validation, for example validate-email will check email addresses.
validate-email is the only predefined validation class.
Default: array()
default(string)
Default value of the field
Default: ''
autofocus(boolean)
Automatically focuses on the form field; if there are multiple fields with autofocus, the focus will occur on the first field in the list
Default: ''
priority(number)
Priority of displaying the field
Default: ''
Examples
#1 Add a subscription field after the note on the checkout page
add_action( 'woocommerce_after_order_notes', 'add_subscribe_checkbox' );
add_action( 'woocommerce_checkout_update_order_meta', 'save_subscribe_field' );
// Add a new field after the order note
function add_subscribe_checkbox( $checkout ) {
woocommerce_form_field( 'subscribed', [
'type' => 'checkbox',
'class' => ['subscribe-field'],
'label' => __( 'Subscribe to our newsletter.' ),
], $checkout->get_value( 'subscribed' ) );
}
// save the field
function save_subscribe_field( $order_id ) {
if( ! empty( $_POST['subscribed'] ) && $_POST['subscribed'] == 1 ) {
update_post_meta( $order_id, 'subscribed', 1 );
}
}
#2 Display the number of product orders on the product edit page
add_action( 'woocommerce_product_options_general_product_data', 'woo_add_sale_fields_to_general' );
add_action( 'woocommerce_process_product_meta', 'woo_sale_fields_save' );
// Display the number of sales of the product on the main editing tab of the product
function woo_add_sale_fields_to_general() {
global $woocommerce, $post;
echo '<div class="options_group">';
woocommerce_form_field( 'total_sales', [
'type' => 'number',
'id' => 'total_sales',
'label' => __( 'Sales', 'woocommerce' ),
'placeholder' => '',
'description' => __( 'All product sales, your can change it', 'woocommerce' ),
'default' => get_post_meta( $post->ID, 'total_sales', true ),
'class' => ['form-field'],
'input_class' => ['short'],
] );
echo '</div>';
}
// Save the value of the field
function woo_sale_fields_save( $post_id ) {
if( ! empty( $_POST['total_sales'] ) ) {
update_post_meta( $post_id, 'total_sales', sanitize_text_field( $_POST['total_sales'] ) );
}
}
Add Your Own Example
woocommerce_form_field() woocommerce form field code
WC 10.6.2
function woocommerce_form_field( $key, $args, $value = null ) {
$defaults = array(
'type' => 'text',
'label' => '',
'description' => '',
'placeholder' => '',
'maxlength' => false,
'minlength' => false,
'required' => false,
'autocomplete' => false,
'id' => $key,
'class' => array(),
'label_class' => array(),
'input_class' => array(),
'return' => false,
'options' => array(),
'custom_attributes' => array(),
'validate' => array(),
'default' => '',
'autofocus' => '',
'priority' => '',
'unchecked_value' => null,
'checked_value' => '1',
);
$args = wp_parse_args( $args, $defaults );
$args = apply_filters( 'woocommerce_form_field_args', $args, $key, $value );
if ( is_string( $args['class'] ) ) {
$args['class'] = array( $args['class'] );
}
if ( is_string( $args['label_class'] ) ) {
$args['label_class'] = array( $args['label_class'] );
}
if ( is_null( $value ) ) {
$value = $args['default'];
}
// Custom attribute handling.
$custom_attributes = array();
$args['custom_attributes'] = array_filter( (array) $args['custom_attributes'], 'strlen' );
if ( $args['required'] ) {
// hidden inputs are the only kind of inputs that don't need an `aria-required` attribute.
// checkboxes apply the `custom_attributes` to the label - we need to apply the attribute on the input itself, instead.
if ( ! in_array( $args['type'], array( 'hidden', 'checkbox' ), true ) ) {
$args['custom_attributes']['aria-required'] = 'true';
$args['label_class'][] = 'required_field';
}
$args['class'][] = 'validate-required';
$required_indicator = ' <span class="required" aria-hidden="true">*</span>';
} else {
$required_indicator = ' <span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) . ')</span>';
}
if ( $args['maxlength'] ) {
$args['custom_attributes']['maxlength'] = absint( $args['maxlength'] );
}
if ( $args['minlength'] ) {
$args['custom_attributes']['minlength'] = absint( $args['minlength'] );
}
if ( ! empty( $args['autocomplete'] ) ) {
$args['custom_attributes']['autocomplete'] = $args['autocomplete'];
}
if ( true === $args['autofocus'] ) {
$args['custom_attributes']['autofocus'] = 'autofocus';
}
if ( $args['description'] ) {
$args['custom_attributes']['aria-describedby'] = $args['id'] . '-description';
}
if ( ! empty( $args['custom_attributes'] ) && is_array( $args['custom_attributes'] ) ) {
foreach ( $args['custom_attributes'] as $attribute => $attribute_value ) {
$custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
}
}
if ( ! empty( $args['validate'] ) ) {
foreach ( $args['validate'] as $validate ) {
$args['class'][] = 'validate-' . $validate;
}
}
$field = '';
$label_id = $args['id'];
$sort = $args['priority'] ? $args['priority'] : '';
$field_container = '<p class="form-row %1$s" id="%2$s" data-priority="' . esc_attr( $sort ) . '">%3$s</p>';
$is_hidden_field = false;
switch ( $args['type'] ) {
case 'country':
$countries = 'shipping_country' === $key ? WC()->countries->get_shipping_countries() : WC()->countries->get_allowed_countries();
if ( 1 === count( $countries ) ) {
$country_code = current( array_keys( $countries ) );
$country_name = current( array_values( $countries ) );
$field .= '<select name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" ' . implode( ' ', $custom_attributes ) . ' class="country_to_state country_to_state--single ' . esc_attr( implode( ' ', $args['input_class'] ) ) . '">';
$field .= '<option value="' . esc_attr( $country_code ) . '" selected>' . esc_html( $country_name ) . '</option>';
$field .= '</select>';
} else {
$data_label = ! empty( $args['label'] ) ? 'data-label="' . esc_attr( $args['label'] ) . '"' : '';
$field = '<select name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" class="country_to_state country_select ' . esc_attr( implode( ' ', $args['input_class'] ) ) . '" ' . implode( ' ', $custom_attributes ) . ' data-placeholder="' . esc_attr( $args['placeholder'] ? $args['placeholder'] : esc_attr__( 'Select a country / region…', 'woocommerce' ) ) . '" ' . $data_label . '><option value="">' . esc_html__( 'Select a country / region…', 'woocommerce' ) . '</option>';
foreach ( $countries as $ckey => $cvalue ) {
$field .= '<option value="' . esc_attr( $ckey ) . '" ' . selected( $value, $ckey, false ) . '>' . esc_html( $cvalue ) . '</option>';
}
$field .= '</select>';
$field .= '<noscript><button type="submit" name="woocommerce_checkout_update_totals" value="' . esc_attr__( 'Update country / region', 'woocommerce' ) . '">' . esc_html__( 'Update country / region', 'woocommerce' ) . '</button></noscript>';
}
break;
case 'state':
/* Get country this state field is representing */
$for_country = isset( $args['country'] ) ? $args['country'] : WC()->checkout->get_value( 'billing_state' === $key ? 'billing_country' : 'shipping_country' );
$states = WC()->countries->get_states( $for_country );
if ( is_array( $states ) && empty( $states ) ) {
$field_container = '<p class="form-row %1$s" id="%2$s" style="display: none">%3$s</p>';
$field .= '<input type="hidden" class="hidden" name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" value="" ' . implode( ' ', $custom_attributes ) . ' placeholder="' . esc_attr( $args['placeholder'] ) . '" readonly="readonly" data-input-classes="' . esc_attr( implode( ' ', $args['input_class'] ) ) . '"/>';
} elseif ( ! is_null( $for_country ) && is_array( $states ) ) {
$data_label = ! empty( $args['label'] ) ? 'data-label="' . esc_attr( $args['label'] ) . '"' : '';
$field .= '<select name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" class="state_select ' . esc_attr( implode( ' ', $args['input_class'] ) ) . '" ' . implode( ' ', $custom_attributes ) . ' data-placeholder="' . esc_attr( $args['placeholder'] ? $args['placeholder'] : esc_html__( 'Select an option…', 'woocommerce' ) ) . '" data-input-classes="' . esc_attr( implode( ' ', $args['input_class'] ) ) . '" ' . $data_label . '>
<option value="">' . esc_html__( 'Select an option…', 'woocommerce' ) . '</option>';
foreach ( $states as $ckey => $cvalue ) {
$field .= '<option value="' . esc_attr( $ckey ) . '" ' . selected( $value, $ckey, false ) . '>' . esc_html( $cvalue ) . '</option>';
}
$field .= '</select>';
} else {
$field .= '<input type="text" class="input-text ' . esc_attr( implode( ' ', $args['input_class'] ) ) . '" value="' . esc_attr( $value ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" ' . implode( ' ', $custom_attributes ) . ' data-input-classes="' . esc_attr( implode( ' ', $args['input_class'] ) ) . '"/>';
}
break;
case 'textarea':
$field .= '<textarea name="' . esc_attr( $key ) . '" class="input-text ' . esc_attr( implode( ' ', $args['input_class'] ) ) . '" id="' . esc_attr( $args['id'] ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" ' . ( empty( $args['custom_attributes']['rows'] ) ? ' rows="2"' : '' ) . ( empty( $args['custom_attributes']['cols'] ) ? ' cols="5"' : '' ) . implode( ' ', $custom_attributes ) . '>' . esc_textarea( $value ) . '</textarea>';
break;
case 'checkbox':
$field = '<label class="checkbox ' . esc_attr( implode( ' ', $args['label_class'] ) ) . '" ' . implode( ' ', $custom_attributes ) . '>';
// Output a hidden field so a value is POSTed if the box is not checked.
if ( ! is_null( $args['unchecked_value'] ) ) {
$field .= sprintf( '<input type="hidden" name="%1$s" value="%2$s" />', esc_attr( $key ), esc_attr( $args['unchecked_value'] ) );
}
$field .= sprintf(
'<input type="checkbox" name="%1$s" id="%2$s" value="%3$s" class="%4$s" %5$s%6$s /> %7$s',
esc_attr( $key ),
esc_attr( $args['id'] ),
esc_attr( $args['checked_value'] ),
esc_attr( 'input-checkbox ' . implode( ' ', $args['input_class'] ) ),
checked( $value, $args['checked_value'], false ),
$args['required'] ? ' aria-required="true"' : '',
wp_kses_post( $args['label'] )
);
$field .= $required_indicator . '</label>';
break;
case 'text':
case 'password':
case 'datetime':
case 'datetime-local':
case 'date':
case 'month':
case 'time':
case 'week':
case 'number':
case 'email':
case 'url':
case 'tel':
$field .= '<input type="' . esc_attr( $args['type'] ) . '" class="input-text ' . esc_attr( implode( ' ', $args['input_class'] ) ) . '" name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" value="' . esc_attr( $value ) . '" ' . implode( ' ', $custom_attributes ) . ' />';
break;
case 'hidden':
$field .= '<input type="' . esc_attr( $args['type'] ) . '" class="input-hidden ' . esc_attr( implode( ' ', $args['input_class'] ) ) . '" name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" value="' . esc_attr( $value ) . '" ' . implode( ' ', $custom_attributes ) . ' />';
$is_hidden_field = true;
break;
case 'select':
$options = '';
if ( ! empty( $args['options'] ) ) {
foreach ( $args['options'] as $option_key => $option_text ) {
if ( '' === $option_key ) {
// A blank option is the proper way to set a placeholder. If one is supplied we make sure the placeholder key is set for selectWoo.
if ( empty( $args['placeholder'] ) ) {
$args['placeholder'] = $option_text ? $option_text : __( 'Choose an option', 'woocommerce' );
}
$custom_attributes[] = 'data-allow_clear="true"';
}
$options .= '<option value="' . esc_attr( $option_key ) . '" ' . selected( $value, $option_key, false ) . '>' . esc_html( $option_text ) . '</option>';
}
$field .= '<select name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" class="select ' . esc_attr( implode( ' ', $args['input_class'] ) ) . '" ' . implode( ' ', $custom_attributes ) . ' data-placeholder="' . esc_attr( $args['placeholder'] ) . '">
' . $options . '
</select>';
}
break;
case 'radio':
$label_id .= '_' . current( array_keys( $args['options'] ) );
if ( ! empty( $args['options'] ) ) {
foreach ( $args['options'] as $option_key => $option_text ) {
$field .= '<input type="radio" class="input-radio ' . esc_attr( implode( ' ', $args['input_class'] ) ) . '" value="' . esc_attr( $option_key ) . '" name="' . esc_attr( $key ) . '" ' . implode( ' ', $custom_attributes ) . ' id="' . esc_attr( $args['id'] ) . '_' . esc_attr( $option_key ) . '"' . checked( $value, $option_key, false ) . ' />';
$field .= '<label for="' . esc_attr( $args['id'] ) . '_' . esc_attr( $option_key ) . '" class="radio ' . implode( ' ', $args['label_class'] ) . '">' . esc_html( $option_text ) . $required_indicator . '</label>';
}
}
break;
}
if ( ! empty( $field ) ) {
$field_html = '';
if ( $args['label'] && 'checkbox' !== $args['type'] ) {
$maybe_for_attr = $is_hidden_field ? '' : ' for="' . esc_attr( $label_id ) . '"';
$field_html .= '<label' . $maybe_for_attr . ' class="' . esc_attr( implode( ' ', $args['label_class'] ) ) . '">' . wp_kses_post( $args['label'] ) . $required_indicator . '</label>';
}
$field_html .= '<span class="woocommerce-input-wrapper">' . $field;
if ( $args['description'] ) {
$field_html .= '<span class="description" id="' . esc_attr( $args['id'] ) . '-description" aria-hidden="true">' . wp_kses_post( $args['description'] ) . '</span>';
}
$field_html .= '</span>';
$container_class = esc_attr( implode( ' ', $args['class'] ) );
$container_id = esc_attr( $args['id'] ) . '_field';
$field = sprintf( $field_container, $container_class, $container_id, $field_html );
}
/**
* Filter by type.
*/
$field = apply_filters( 'woocommerce_form_field_' . $args['type'], $field, $key, $args, $value );
/**
* General filter on form fields.
*
* @since 3.4.0
*/
$field = apply_filters( 'woocommerce_form_field', $field, $key, $args, $value );
if ( $args['return'] ) {
return $field;
} else {
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $field;
}
}
Related Functions