'woocommerce_order_item_display_meta_value filtering out input fields? Checkbox for order item meta

I'm trying to display some order item meta data as checkboxes instead of plain text via the woocommerce_order_item_display_meta_value hook (hope my terminology is right. I'm new to this woocommerce game).

add_filter( 'woocommerce_order_item_display_meta_value', 'modify_order_item_display_value' , 10, 3 );

function modify_order_item_display_value( $display_value, $meta, $wc_order_item ) {
    $meta_data = $meta->get_data();

    if( $meta_data['key'] === '_Packed' ) {
        $display_value =  __('<input type="checkbox" name="mycheckbox" id="mycheckbox" value="1" />', 'woocommerce' );
    }

    return $display_value;
}

If I do something like $display_value = '<p>TEST</p>'; it comes out fine. When I try to use an input it doesn't show up. Looking at DOM in the browser I can get down to the <td> that should contain my input and the HTML just isn't there.

Does woocommerce_order_item_display_meta_value filter out input fields? Is there another way to get a checkbox for order item meta data ?



Solution 1:[1]

I don't know if this is the right way to do it but it works. I'd love any feedback about the "woocommercyness" of it...

STEP1 Use woocommerce_hidden_order_itemmeta to hide my field so it doesn't get shown "the normal way"

add_filter( 'woocommerce_hidden_order_itemmeta', 'myplugin_hide_order_item_meta_fields' );
function myplugin_hide_order_item_meta_fields( $fields ) 
{
    $fields[] = '_Packed';
    return $fields;
}

STEP 2 Use woocommerce_after_order_itemmeta to display my field in a custom way after all of the other Meta data. Note that I give the checkbox an ID based on the order item id. In other code I need to see if these IDs are passed in requests or not

add_action( 'woocommerce_after_order_itemmeta', 'myplugin_order_meta_customized_display',10, 3 );
function myplugin_order_meta_customized_display( $item_id, $item, $product )
{
    $packed = $item->get_meta('_Packed') === 'Y';
    echo "<div>";
    woocommerce_form_field("packed_$item_id", 
        array(
            'type'      => 'checkbox',
            'label'     => __('Packed', 'woocommerce'),
            'required'  => false,
            'class'     => array('input-checkbox')
    ), $packed);
    echo "</div>";
 }
 

STEP 3 Use the REQUEST to set the meta datafunction myplugin_set_meta_from_post($order_id, $order) I call a wrapper from the actions woocommerce_checkout_order_processed and save_post_shop_order. The actuions get the order id - I lookup the order (because I'm doing other stuff, not just the crazy meta display)

function myplugin_set_meta_from_post($order_id, $order)
{
    // For each meta data in each order item
    //   If it is '_Packed' then see if a corresponding packed_<id> parameter
    //   is in the request and update the item's meta data accordingly.
    //
    foreach ($order->get_items() as $item_key => $item ) {
        $item_meta = $item->get_meta_data();
        
        foreach($item_meta as $meta)
        {
            if ($meta->__get('key') === '_Packed')
            {
                $k = 'packed_'.$item->get_id();
                $packed = 'Y';
                if ( ! isset( $_REQUEST[ $k ] ) || empty( $_REQUEST[ $k ] ) ) {
                    $packed = 'N';
                }
                if ($packed != $item->get_meta('_Packed'))
                {
                    $item->update_meta_data('_Packed', $packed);
                }
            }
        }
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 John3136