WooCommerce checkout: How can I change $field_container of a checkout field?

By default the checkout fields are wrapped inside <p class="form-row... HTML by the woocommerce_form_field() core function (see $field_container) – I want to change that bahaviour. How could this be done without altering the core function?

1 Answer
1

The woocommerce_form_field() is a pluggable function, defined as follows:

if ( ! function_exists( 'woocommerce_form_field' ) ) {

    /**
     * Outputs a checkout/address form field.
     *
     * @param string $key Key.
     * @param mixed  $args Arguments.
     * @param string $value (default: null).
     * @return string
     */
    function woocommerce_form_field( $key, $args, $value = null ) {
        ...
    }
}

So you can copy the whole code into your theme’s functions.php file, and modify the form field wrapper to suit your requirements, like so where I changed the wrapper’s tag from p to div:

if ( ! function_exists( 'woocommerce_form_field' ) ) {

    /**
     * Outputs a checkout/address form field.
     *
     * @param string $key Key.
     * @param mixed  $args Arguments.
     * @param string $value (default: null).
     * @return string
     */
    function woocommerce_form_field( $key, $args, $value = null ) {
        ...
        $field_container="<div class="form-row %1$s" id="%2$s" data-priority="" . esc_attr( $sort ) . '">%3$s</div>';

        switch ( $args['type'] ) {
            ...
            case 'state':
                ...

                if ( is_array( $states ) && empty( $states ) ) {

                    $field_container="<div class="form-row %1$s" id="%2$s" style="display: none">%3$s</div>";

                    ...

                } ...
            ...
        }

        ...
    }
}

Or you can use the woocommerce_form_field filter, like so (here I used preg_replace() to change the wrapper’s tag from p to div):

add_filter( 'woocommerce_form_field', 'my_woocommerce_form_field' );
function my_woocommerce_form_field( $field ) {
    return preg_replace(
        '#<p class="form-row (.*?)"(.*?)>(.*?)</p>#',
        '<div class="form-row $1 test"$2>$3</div>',
        $field
    );
}

The alternate method worked well in my case, but of course, there were no other (plugin, theme, or custom) code that changes the wrapper’s markup/HTML.

Hope that helps.

Leave a Comment