Saving a Product Custom Field and Displaying It in Cart Page

Add product custom fields to cart and display them everywhere in WooCommerce

There are mistakes and some missing things in your code. Instead use the following revisited code:

// Display on product page
add_action( 'woocommerce_before_add_to_cart_button', 'display_acf_single_product_pages', 1 );
function display_acf_single_product_pages() {
global $product;

$colors = get_field( 'colors', $product->get_id() );
if ( ! empty($colors) ) {
echo '<div class="vorcartbutton">
<div class="vorcartbuttonlable">
<label for="farbe">'. __("Farbe wählen") .':</label>
<select name="farbe" id="farbe">';

foreach ( $colors as $color ) {
echo '<option value="'. $color['label'] .'"><span class="color">'. $color['label'] .'</span></option>';
}
echo '</select>
</div><br>';
}

$sizes = get_field( 'sizes', $product->get_id() );
if ( ! empty($sizes) ) {
echo '<div class="vorcartbutton">
<div class="vorcartbuttonlable">
<label for="groesse">'. __("Größe wählen") .':</label>
<select name="groesse" id="groesse">';

foreach ( $sizes as $size ) {
echo '<option value="'. $size['label'] .'"><span class="color">'. $size['label'] .'</span></option>';
}
echo '</select>
</div><br>
</div>';
}
}

// Add as custom cart item data
add_filter( 'woocommerce_add_cart_item_data', 'save_acf_as_cart_item_data', 10, 2 );
function save_acf_as_cart_item_data( $cart_item_data, $cart_item ) {
if ( isset($_POST['farbe']) || isset($_POST['groesse']) ) {
if ( isset($_POST['farbe']) ) {
$cart_item_data['farbe'] = esc_attr($_POST['farbe']);
}
if ( isset($_POST['groesse']) ) {
$cart_item_data['groesse'] = esc_attr($_POST['groesse']);
}
$cart_item_data['unique_key'] = md5( microtime().rand() );
}
return $cart_item_data;
}

// Display on cart and checkout
add_filter( 'woocommerce_get_item_data', 'display_acf_on_cart_and_checkout', 10, 2 );
function display_acf_on_cart_and_checkout( $cart_data, $cart_item ) {
if ( isset($cart_item['farbe']) ) {
$custom_items[] = array( 'name' => __("Farbe", "woocommerce"), 'value' => $cart_item['farbe'] );
}

if ( isset($cart_item['groesse']) ) {
$custom_items[] = array( 'name' => __("Größe", "woocommerce"), 'value' => $cart_item['groesse'] );
}
return $custom_items;
}

// Display on orders and email notifications (save as custom order item meta data)
add_action( 'woocommerce_checkout_create_order_line_item', 'display_acf_on_orders_and_emails', 10, 4 );
function display_acf_on_orders_and_emails( $item, $cart_item_key, $values, $order ) {
$colors = get_field( 'colors', $values['product_id'] );
$sizes = get_field( 'sizes', $values['product_id'] );

if ( isset($values['farbe']) ) {
$item->add_meta_data( 'farbe', $values['farbe'] );
}

if ( isset($values['groesse']) ) {
$item->add_meta_data( 'groesse', $values['groesse'] );
}
}

// Change displayed label for specific custom order item meta keys
add_filter('woocommerce_order_item_display_meta_key', 'filter_wc_order_item_display_meta_key', 10, 3 );
function filter_wc_order_item_display_meta_key( $display_key, $meta, $item ) {

// Change displayed label for specific order item meta key
if( is_admin() && $item->get_type() === 'line_item' ) {
if( $meta->key === 'farbe' ) {
$display_key = __("Farbe", "woocommerce");
}
if( $meta->key === 'groesse' ) {
$display_key = __("Größe", "woocommerce");
}
}
return $display_key;
}

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

Save product custom field value in cart and display it on Cart and checkout

Here is the complete code to Store product custom field in cart object and display that in Cart and Checkout pages:

// Output the Custom field in Product pages
add_action("woocommerce_before_add_to_cart_button", "options_on_single_product", 1);
function options_on_single_product(){
?>
<label for="custom_field">
<input type="radio" name="custom_field" checked="checked" value="option1"> option 1 <br />
<input type="radio" name="custom_field" value="option2"> option 2
</label> <br />
<?php
}

// Stores the custom field value in Cart object
add_filter( 'woocommerce_add_cart_item_data', 'save_custom_product_field_data', 10, 2 );
function save_custom_product_field_data( $cart_item_data, $product_id ) {
if( isset( $_REQUEST['custom_field'] ) ) {
$cart_item_data[ 'custom_field' ] = esc_attr($_REQUEST['custom_field']);
// below statement make sure every add to cart action as unique line item
$cart_item_data['unique_key'] = md5( microtime().rand() );
}
return $cart_item_data;
}

// Outuput custom Item value in Cart and Checkout pages
add_filter( 'woocommerce_get_item_data', 'output_custom_product_field_data', 10, 2 );
function output_custom_product_field_data( $cart_data, $cart_item ) {
if( isset( $cart_item['custom_field'] ) ) {
$cart_data[] = array(
'key' => __('Custom Item', 'woocommerce'),
'value' => $cart_item['custom_field'],
'display' => $cart_item['custom_field'],
);
}
return $cart_data;
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

This code is tested and works.

Save Custom Field Data to Cart and Order of a Woocommerce product variation

Updated

There are some mistakes in your code… The following revisited code will solve your issue:

// Display Variation custom fields (admin)
add_action( 'woocommerce_product_after_variable_attributes', 'display_variation_setting_custom_fields', 10, 3 );
function display_variation_setting_custom_fields( $loop, $variation_data, $variation ) {
echo '<div>';

woocommerce_wp_text_input( array( // Text Field
'id' => "_text_field[$loop]",
'label' => __("My Text Field", "woocommerce"),
'placeholder' => "http://",
'desc_tip' => true,
'description' => __("Enter the custom value here.", "woocommerce"),
'wrapper_class' => 'form-row form-row-full',
'value' => get_post_meta( $variation->ID, '_text_field', true ),
) );

woocommerce_wp_hidden_input( array( // Hidden field
'id' => "_hidden_field[$loop]",
'value' => 'hidden_value',
) );
echo '</div>';
}

// Save Variation custom fields
add_action( 'woocommerce_save_product_variation', 'save_variation_custom_fields', 10, 2 );
function save_variation_custom_fields( $variation_id, $i ) {
// Save Text Field
if( isset( $_POST['_text_field'][$i] ) && ! empty( $_POST['_text_field'][$i] ) )
update_post_meta( $variation_id, '_text_field', sanitize_text_field( $_POST['_text_field'][$i] ) );

// Save Hidden Field
if( isset( $_POST['_hidden_field'][$i] ) && ! empty( $_POST['_hidden_field'][$i] ) )
update_post_meta( $variation_id, '_hidden_field', esc_attr( $_POST['_hidden_field'][$i] ) );
}

// Include our variation custom field
add_filter( 'woocommerce_available_variation', 'include_variation_custom_field', 10, 3) ;
function include_variation_custom_field( $data, $product, $variation ) {
$data['text_field'] = $variation->get_meta( '_text_field' );

return $data;
}

// Save and display "Custom Field for Simple Products" on order items everywhere
add_filter( 'woocommerce_checkout_create_order_line_item', 'action_wc_checkout_create_order_line_item_2', 10, 4 );
function action_wc_checkout_create_order_line_item_2( $item, $cart_item_key, $values, $order ) {
// Get the Custom Field
$value = $values['data']->get_meta( '_text_field' );

if( ! empty( $value ) ) {
// Save it and display it
$item->update_meta_data( __( 'Custom Field', 'woocommerce' ), $value );
}
}

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

Related: Save and display product custom meta on WooCommerce orders and emails



Somme screenshots

On admin product variations settings:

Sample Image

On order received page (thankyou):

Sample Image

On admin edit orders pages:

Sample Image

Display product custom fields in cart next to each item name in Woocommerce

You can use woocommerce_after_cart_item_name hook for displaying the value of ACF custom field for each product below the product title.

//To display the ACF custom field 'shpng' below the product title on cart page
function lh_cart_item_sub_title( $cart_item ) {
$shpng = get_field( 'shpng', $cart_item['product_id'] );
echo "<div class='small custom-cart-shipping-date'>My Custom Shipping Date: $shpng.</div>";
}
add_action( 'woocommerce_after_cart_item_name', 'lh_cart_item_sub_title', 10, 1 );

How to Save Custom Field in woo commerce session in cart page after shipping calculator

You can set and get the WooCommerce session values with the below code.

WC()->session->set( 'group_order_data', $data_values );

$data_values = WC()->session->get( 'group_order_data' );

Thanks

Display and save added custom cart item data on Woocommerce Cart, Checkout and Orders

To display and save custom meta data added to cart in cart, checkout and orders when using:

WC()->cart->add_to_cart( $product_id ,1,  0,array(), array('add_size' => array('PR CODE'=>'1.0') );

You will use the following code:

// Display custom cart item meta data (in cart and checkout)
add_filter( 'woocommerce_get_item_data', 'display_cart_item_custom_meta_data', 10, 2 );
function display_cart_item_custom_meta_data( $item_data, $cart_item ) {
$meta_key = 'PR CODE';
if ( isset($cart_item['add_size']) && isset($cart_item['add_size'][$meta_key]) ) {
$item_data[] = array(
'key' => $meta_key,
'value' => $cart_item['add_size'][$meta_key],
);
}
return $item_data;
}

// Save cart item custom meta as order item meta data and display it everywhere on orders and email notifications.
add_action( 'woocommerce_checkout_create_order_line_item', 'save_cart_item_custom_meta_as_order_item_meta', 10, 4 );
function save_cart_item_custom_meta_as_order_item_meta( $item, $cart_item_key, $values, $order ) {
$meta_key = 'PR CODE';
if ( isset($values['add_size']) && isset($values['add_size'][$meta_key]) ) {
$item->update_meta_data( $meta_key, $values['add_size'][$meta_key] );
}
}

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

Example display on Cart (and Checkout) pages:

Sample Image

Example display on Orders (and email notifications):

Sample Image

Add custom field in products to display in cart, checkout and in orders

Update 2

Try the following (that normally adds a dropdown in single product pages and save/display the selected value in cart item):

// Frontend: custom select field (dropdown) in product single pages
add_action( 'woocommerce_before_add_to_cart_button', 'fabric_length_product_field' );
function fabric_length_product_field() {
global $product;

// Select field
woocommerce_form_field('fitting_color', array(
'type' => 'select',
'class' => array('my-field-class form-row-wide'),
'label' => __('_fitting_color', 'woocommerce'),
'required' => true, // or false
'options' => array(
'' => __('Select a color', 'woocommerce'),
'black' => __('Black', 'woocommerce'),
'white' => __('White', 'woocommerce'),
),
),'');
}

// Add "fitting_color" selected value as custom cart item data
add_filter( 'woocommerce_add_cart_item_data', 'add_custom_cart_item_data', 20, 2 );
function add_custom_cart_item_data( $cart_item_data, $product_id ){
if( isset($_POST['fitting_color']) && ! empty($_POST['fitting_color'])) {
$cart_item_data['fcolor']= array(
'value' => esc_attr($_POST['fitting_color']),
'unique_key' => md5( microtime() . rand() ), // <= Make each cart item unique
);
}
return $cart_item_data;
}

// Display custom cart item data in cart and checkout pages
add_filter( 'woocommerce_get_item_data', 'display_custom_cart_item_data', 10, 2 );
function display_custom_cart_item_data( $cart_item_data, $cart_item ) {
if ( isset( $cart_item['fcolor']['value'] ) ){
$cart_item_data[] = array(
'name' => __( 'Fitting color', 'woocommerce' ),
'value' => $cart_item['fcolor']['value'],
);
}
return $cart_item_data;
}

Code goes on function.php file of your active child theme (or active theme). It should works.


For save/display on order (and display on email notifications), you will use:

// Save chosen slelect field value to each order item as custom meta data and display it everywhere
add_action('woocommerce_checkout_create_order_line_item', 'save_order_item_product_fitting_color', 10, 4 );
function save_order_item_product_fitting_color( $item, $cart_item_key, $values, $order ) {
if( isset($values['fcolor']['value']) ) {
$key = __('Fitting color', 'woocommerce');
$value = $values['fcolor']['value'];
$item->update_meta_data( $key, $value );
}
}

And the missing field validation:

// Field validation
add_filter( 'woocommerce_add_to_cart_validation', 'dropdown_fitting_color_validation', 10, 3 );
function dropdown_fitting_color_validation( $passed, $product_id, $quantity ) {
if( isset($_POST['fitting_color']) && empty($_POST['fitting_color']) ) {
wc_add_notice( __( "Please select a Fitting color", "woocommerce" ), 'error' );
return false;
}

return $passed;
}

Set product custom field and display value in cart, checkout and view order

First: "Duplicating this custom field with key and value, in an self-generated custom field on the admin order page" is not the good approach.

To achieve what you are expecting, you have missed just some little things. You need to:

  1. Store custom field in Cart (when product is added to cart)
  2. Render this on cart and checkout pages
  3. Add the information in the order as meta data (to make it part of the order)

With point 3 you will be able to get this on WooCommerce PDF Invoice plugin to display "Warranty : 15 years".

So the code you need is:

// create the custom field on product admin tab
add_action( 'woocommerce_product_options_general_product_data', 'create_warranty_custom_field' );
function create_warranty_custom_field() {
// Create a custom text field
woocommerce_wp_text_input( array(
'id' => '_warranty',
'type' => 'text',
'label' => __('Warranty', 'woocommerce' ),
'description' => '',
'desc_tip' => 'true',
'placeholder' => __('i.e. 15 years', 'woocommerce' ),
) );
}

// save the data value from this custom field on product admin tab
add_action( 'woocommerce_process_product_meta', 'save_warranty_custom_field' );
function save_warranty_custom_field( $post_id ) {
$wc_text_field = $_POST['_warranty'];
if ( !empty($wc_text_field) ) {
update_post_meta( $post_id, '_warranty', esc_attr( $wc_text_field ) );
}
}

// Store custom field in Cart
add_filter( 'woocommerce_add_cart_item_data', 'store_warranty_custom_field', 10, 2 );

function store_warranty_custom_field( $cart_item_data, $product_id ) {
$warranty_item = get_post_meta( $product_id , '_warranty', true );
if( !empty($warranty_item) ) {
$cart_item_data[ '_warranty' ] = $warranty_item;

// below statement make sure every add to cart action as unique line item
$cart_item_data['unique_key'] = md5( microtime().rand() );
WC()->session->set( 'days_manufacture', $warranty_item );
}
return $cart_item_data;
}

// Render meta on cart and checkout
add_filter( 'woocommerce_get_item_data', 'rendering_meta_field_on_cart_and_checkout', 10, 2 );

function rendering_meta_field_on_cart_and_checkout( $cart_data, $cart_item ) {
$custom_items = array();
// Woo 2.4.2 updates
if( !empty( $cart_data ) ) {
$custom_items = $cart_data;
}
if( isset( $cart_item['_warranty'] ) ) {
$custom_items[] = array( "name" => __( "Warranty", "woocommerce" ), "value" => $cart_item['_warranty'] );
}
return $custom_items;
}

// Add the information in the order as meta data
add_action('woocommerce_add_order_item_meta','add_waranty_to_order_item_meta', 1, 3 );
function add_waranty_to_order_item_meta( $item_id, $values, $cart_item_key ) {
// Retrieving the product id for the order $item_id
$product_id = wc_get_order_item_meta( $item_id, '_product_id', true );
// Getting the warranty value for this product Id
$warranty = get_post_meta( $product_id, '_warranty', true );
// Add the meta data to the order
wc_add_order_item_meta($item_id, 'Warranty', $warranty, true);
}

Naturally, this goes in function.php file of your active child theme (or theme) or also in any plugin file.

This code is tested and works.


References:

  • WooCommerce : Add custom Metabox to admin order page
  • Admin product pages custom field displayed in Cart and checkout

Save checkout custom field value and display it in WooCommerce admin orders

There are some mistakes in some of your functions… You need to use the same checkout field key as meta key in the following functions:

In the 2nd function, you use another hook and save custom field as user meta data too:

add_action( 'woocommerce_checkout_create_order', 'aba_checkout_field_update_order_meta' );

function aba_checkout_field_update_order_meta( $order ) {
if ( isset($_POST['aba_hear']) && ! empty($_POST['aba_hear']) ) {
$order->update_meta_data( '_aba_hear', sanitize_text_field( $_POST['aba_hear'] ) );

// Update user data
if( $order->get_user_id() > 0 ) {
update_user_meta( $order->get_user_id(), 'aba_hear', true );
}
}
}

In the 3rd function use this:

add_action( 'woocommerce_admin_order_data_after_billing_address', 'aba_checkout_field_display_admin_order_meta', 10, 1 );
function aba_checkout_field_display_admin_order_meta( $order ){
$value = $order->get_meta( '_aba_hear' );

if ( ! empty($value) ) {
echo '<p><strong>'.__('How did You Hear About Us?').':</strong> ' . $value . '</p>';
}
}

It should better work now.



Notes:

Why saving this checkout field also as custom user meta data?

Because in your first function you have $checkout->get_value( 'aba_hear' ) that will display the selected value on from customer last order in this custom checkout field. The value is read from user meta 'aba_hear'.



Related Topics



Leave a reply



Submit