Search code examples
phpwordpressselectwoocommerceoptgroup

WooCommerce Select Dropdown With Optgroup On Checkout


I'm using WordPress 5.0.2 with WooCommerce 3.5.3 and I have created a select dropdown on the checkout page, it works good, however I want to add some options groups into it to organized the select options

Here is my code from my functions.php :

add_action('woocommerce_before_order_notes', 'add_select_checkout_field');
function add_select_checkout_field( $checkout ) {
  echo '<p>New Select Dropdown</p>';
  woocommerce_form_field( 'region', array(
      'type'          => 'select',
      'class'         => array( 'region-dropdown' ),
      'label'         => __( 'Select your region' ),
      'options'       => array(
          'region1'   => __( 'Region 1', 'woocommerce' ),
          'region2' => __( 'Region 2', 'woocommerce' ),
          'region3' => __( 'Region 3', 'woocommerce' ),
          'region4'   => __( 'Region 4', 'woocommerce' )
      )
 ),
  $checkout->get_value( 'region' ));
}

And I want to the result is outputed like this :

<select>
    <optgroup label="North Region">
        <option>Region 1</option>
        <option>Region 2</option>
    </optgroup>
    <optgroup label="South Region">
        <option>Region 3</option>
        <option>Region 4</option>
    </optgroup>
</select>

I don't know why woocommerce doesn't implement this functionality but I hope there is a way to do it.

Any help would be appreciated


Solution

  • You can do it in 2 ways:

    1) Enabling <optgroup> in Woocommerce select form fields, you can use from GitHub:

    2) Enabling <optgoup> manually in a select field like:

    add_action('woocommerce_before_order_notes', 'custom_checkout_select_field_with_optgroup', 10, 1 );
    function custom_checkout_select_field_with_optgroup( $checkout ) {
        $domain  = 'woocommerce';
        $title   = __("Region", $domain);
        $slug    = sanitize_title($title);
        $default = __("Select your region", $domain);
        $value   = $checkout->get_value($slug);
    
        // Region option data array with optgroup
        $options = array(
            __("North Region", $domain) => array(
                'region1' => __("Region 1", $domain),
                'region2' => __("Region 2", $domain),
            ),
            __("South Region", $domain) => array(
                'region3' => __("Region 3", $domain),
                'region4' => __("Region 4", $domain),
            )
        );
    
        // The field
        echo '<p class="form-row form-row-wide '.$slug.'-dropdown" id="'.$slug.'_field" data-priority="">
        <label for="'.$slug.'" class="">'.$title.'</label>
        <span class="woocommerce-input-wrapper">
        <select name="'.$slug.'" id="'.$slug.'" class="select " data-placeholder="" autocomplete="'.$slug.'">
        <option value="">'.$default.'</option>';
    
        // Loop through "optgroup"
        foreach( $options as $optgroup_label => $optgroup_options ) {
            echo '<optgroup label="'.$optgroup_label.'">';
            // Loop through "options" in the "optgroup"
            foreach( $optgroup_options as $key => $label ) {
                $selected = $value === $key ? ' selected="selected"': '';
                echo '<option value="'.$key.'"'.$selected.'>'.$label.'</option>';
            }
            echo '</optgroup>';
        }
    
        echo '</select></span></p>';
    }
    

    Code goes in functions.php file of your active child theme (or active theme). Tested and works.

    enter image description here


    Related thread: Add a custom field below billing country in Woocommerce Checkout