Search code examples
phpwordpresswoocommercebackendhook-woocommerce

Add a custom column to order items and make it sortable in WooCommerce admin order details page


I have been working to add a item product attribute to the admin order details page - which I have managed. You can see the extra column titled "Packing Weight".

enter image description here

// Add custom column headers here
add_action('woocommerce_admin_order_item_headers', 'my_woocommerce_admin_order_item_headers');
function my_woocommerce_admin_order_item_headers() {
    // set the column name
    $column_name = 'Packing Weight';

    // display the column name
    echo '<th>' . $column_name . '</th>';
}

// Add custom column values here
add_action('woocommerce_admin_order_item_values', 'my_woocommerce_admin_order_item_values', 10, 3);
function my_woocommerce_admin_order_item_values($_product, $item, $item_id = null) {
    // get the post meta value from the associated product
    // $value = get_post_meta($_product->post->ID, '_custom_field_name', 1);
    $value = array_shift( wc_get_product_terms( $_product->post->ID, 'pa_packing-order', array( 'fields' => 'names' ) ) );

    // display the value
    echo '<td>' . $value . '</td>';
}

However, I would ideally like to order the items in the order by this column e.g. Very Soft, Soft, Hard. I am happy to change the values of packing weight to a numeric scale 1 - 10 if this makes ordering easier.

How would I go about doing this?


Solution

    • Note that I've added some CSS classes, to make it sortable
    • Also notice that I'm using an array of strings for the output, and displaying them randomly. Replace this with your own code. This is because my products do not contain the specific terms

    So to make your custom column added to admin order item sortable, you can use:

    // Add header
    function action_woocommerce_admin_order_item_headers( $order ) {
        // Set the column name
        $column_name = __( 'Packing Weight', 'woocommerce' );
        
        // Display the column name
        echo '<th class="line_packing_weight sortable" data-sort="string-ins">' . $column_name . '</th>';
    }
    add_action( 'woocommerce_admin_order_item_headers', 'action_woocommerce_admin_order_item_headers', 10, 1 );
    
    //Add content
    function action_woocommerce_admin_order_item_values( $product = null, $item, $item_id ) {
        //  WC_Order_Refund OR WC_Order_item
        if ( $item->get_type() == 'shop_order_refund' ) {
            $item = new WC_Order_Refund( $item_id );
        } else {
            $item = new WC_Order_Item_Product( $item_id );
    
            // Only for "line_item" items type, to avoid errors
            if ( ! $item->is_type( 'line_item' ) ) return;
        }
        
        // Replace this part with your own code
        $some_strings = array( 'Soft', 'Very soft', 'Hard' );
        
        // Replace this part with your own code
        $value = $some_strings[array_rand( $some_strings )];
        
        if ( $value ) { 
            echo '<td class="line_packing_weight" data-sort-value="' . $value . '">' . $value . '</td>';
        }
    }
    add_action( 'woocommerce_admin_order_item_values', 'action_woocommerce_admin_order_item_values', 10, 3 );