WooCommerce Custom Fields - Multiselect

I'm adding extra fields to the checkout page in WooCommerce, I can add basic fields like a text box, but need to add a (multi) select box, where the user can choose multiple items. I've figured out how to add a select box through code, like this:

add_action('woocommerce_after_order_notes', 'my_custom_checkout_field');

function my_custom_checkout_field( $checkout ) {

    echo '<div id="my_custom_checkout_field"><h3>'.__('My Field').'</h3>';

    woocommerce_form_field( 'my_field_name', array(
        'type'          => 'select',
        'class'         => array('my-field-class form-row-wide'),
        'label'         => __('Fill in this field'),
        'placeholder'       => __('Enter something'),
        'options'           => array(
            'Buick' => __('Buick', 'woocommerce' ),
            'Ford' => __('Ford', 'woocommerce' )
        )
        ), $checkout->get_value( 'my_field_name' ));

    echo '</div>';

}

But that's just a single select drop down.
Can I do something similar for a multi-select?
Or do you have a WooCommerce extension that'd you recommend?

Please advice, thanks in advance!


You need to create your own custom field type handler. If you look at WooCommerce source code you will see that you can use filter: 'woocommerce_form_field_' . $args['type']

I haven't really tested this, this is just slightly altered code from single "select" control, but you get the point:

add_filter( 'woocommerce_form_field_multiselect', 'custom_multiselect_handler', 10, 4 );

function custom_multiselect_handler( $field, $key, $args, $value ) {

    $options = '';

    if ( ! empty( $args['options'] ) ) {
        foreach ( $args['options'] as $option_key => $option_text ) {
            $options .= '<option value="' . $option_key . '" '. selected( $value, $option_key, false ) . '>' . $option_text .'</option>';
        }

        if ($args['required']) {
            $args['class'][] = 'validate-required';
            $required = '&nbsp;<abbr class="required" title="' . esc_attr__('required', 'woocommerce') . '">*</abbr>';
        }
        else {
            $required = '&nbsp;<span class="optional">(' . esc_html__('optional', 'woocommerce') . ')</span>';
        }

        $field = '<p class="form-row ' . implode( ' ', $args['class'] ) .'" id="' . $key . '_field">
            <label for="' . $key . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label']. $required . '</label>
            <select name="' . $key . '" id="' . $key . '" class="select" multiple="multiple">
                ' . $options . '
            </select>
        </p>' . $args['after'];
    }

    return $field;
}

And in your code just state the type as 'multiselect':

add_action('woocommerce_after_order_notes', 'my_custom_checkout_field');

function my_custom_checkout_field( $checkout ) {

    echo '<div id="my_custom_checkout_field"><h3>'.__('My Field').'</h3>';

    woocommerce_form_field( 'my_field_name', array(
        'type'          => 'multiselect',
        'class'         => array('my-field-class form-row-wide'),
        'label'         => __('Fill in this field'),
        'placeholder'   => __('Enter something'),
        'options'       => array(
            'Buick' => __('Buick', 'woocommerce' ),
            'Ford' => __('Ford', 'woocommerce' )
        )
        ), $checkout->get_value( 'my_field_name' ));

    echo '</div>';

}

Although it's late to answer this post but I am adding this solution for the help of those still looking for the solution. We can add custom data using custom_attributes that will make it a multiple-choice dropdown.

woocommerce_form_field('my_field_name',array(
   type=>"select",
   custom_attributes=>array("multiple"),
   options=>$options
));