Search code examples
phpwordpresswoocommercecustom-taxonomyproduct-variations

Add a dropdown based on product categories in Woocommerce admin product variation


I need to replace checkboxes fields with a unique select field to display product categories term names that I get from a child term ID, in admin product variation settings (for my variable products only).

So woocommerce_wp_checkbox() function will be replaced by woocommerce_wp_select() instead.

Here is my WORKING code for checkboxes:

<?php
// Woocommerce Product meta
// Add Variation Settings
add_action( 'woocommerce_product_after_variable_attributes', 'variation_settings_fields', 10, 3 );
// Save Variation Settings
add_action( 'woocommerce_save_product_variation', 'save_variation_settings_fields', 10, 2 );
// Add fields
function variation_settings_fields( $loop, $variation_data, $variation ) {  
    // Characteristics
    $args = array( 'type' => 'product', 'taxonomy' => 'product_cat', 'child_of' => 20 ); 
    $categories = get_categories( $args );
    foreach ($categories as $cat) {
        woocommerce_wp_checkbox( array( 
            "id"            => $cat->name .'_['. $variation->ID .']', 
            "label"         => __(" " . $cat->name, "woocommerce" ), 
            "value"         => get_post_meta( $variation->ID, $cat->name .'_', true ), 
            )
        );
    }

    ?>
<?php
}
// Save
function save_variation_settings_fields( $post_id ) {
    // Characteristics
    $args = array( 'type' => 'product', 'taxonomy' => 'product_cat', 'child_of' => 20 ); 
    $categories = get_categories( $args );
    foreach ($categories as $cat) {
        $checkbox = isset( $_POST[$cat->name . '_'][ $post_id ] ) ? 'yes' : 'no';
        update_post_meta( $post_id, $cat->name . '_', $checkbox );
    }
}
?>

How can I replace the checkboxes by a dropdown (OR eventually radio buttons)?

Any help is really appreciated.


Solution

  • In your actual code there is some mistakes like using get_categories() to get product category custom taxonomy terms. Instead just use get_terms()

    The below code will enable a select field instead of multiple checkboxes. The select value is well saved.

    The revisited code:

    // Add Variation settings custom field
    add_action( 'woocommerce_product_after_variable_attributes', 'add_product_category_variation_field', 11, 3 );
    function add_product_category_variation_field( $loop, $variation_data, $variation ) {
        // Get product categories that are child of term = 20
        $terms   = get_terms( array('taxonomy' => 'product_cat', 'child_of' => 20 ) );
        $options = []; // Initializing
    
        // Loop through each wp_term object and set term names in an array
        foreach ($terms as $term) {
            $term_name = __( $term->name, "woocommerce" );
            $options[$term_name] = $term_name;
        }
    
        // The select field
        woocommerce_wp_select( array(
            'id'            => '_product_category',
            'name'          => "_product_category_$loop",
            'label'         => __("product categories", "woocommerce" ),
            'options'       => $options,
            'value'         => get_post_meta( $variation->ID, '_product_category', true ),
        ) );
    }
    
    // Save Variation settings custom field
    add_action( 'woocommerce_save_product_variation', 'save_product_category_variation_field', 11, 2 );
    function save_product_category_variation_field( $variation_id, $loop ){
        if( isset($_POST["_product_category_$loop"]) )
            update_post_meta( $variation_id, '_product_category', esc_attr( $_POST["_product_category_$loop"] ) );
    }
    

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