I use the code, that on the product editing page shows the checkbox "Roast Level". When the manager clicks on this checkbox, a select box appears on the page of a single product, allowing the customer to select "Roast Level".
When selecting and adding a product to the cart, the selected value appears in the cart itself. This value is also shown on the checkout page, on the "Thank You" page, in the order, on the email notification, and on the order editing page in the admin panel.
Here is the code:
// Display Checkbox Field
add_action('woocommerce_product_options_general_product_data', 'roast_custom_field_add');
function roast_custom_field_add() {
global $post;
// Checkbox
woocommerce_wp_checkbox(
array(
'id' => '_roast_checkbox',
'label' => __('Roast Level', 'woocommerce'),
'description' => __('Enable roast level', 'woocommerce')
)
);
}
// Save Checkbox Field
add_action('woocommerce_process_product_meta', 'roast_custom_field_save');
function roast_custom_field_save($post_id) {
// Custom Product Checkbox Field
$roast_checkbox = isset($_POST['_roast_checkbox']) ? 'yes' : 'no';
update_post_meta($post_id, '_roast_checkbox', esc_attr($roast_checkbox));
}
/*---------------------------------------------------------------
*Display Select Box
---------------------------------------------------------------*/
add_action( 'woocommerce_before_add_to_cart_button', 'add_roast_custom_field', 0 );
function add_roast_custom_field() {
global $product;
// If is single product page and have the "roast_checkbox" enabled we display the field
if ( is_product() && $product->get_meta( '_roast_checkbox' ) === 'yes' ) {
echo '<div class="roast_select">';
$select = woocommerce_form_field( 'roast_custom_options', array(
'type' => 'select',
'class' => array('my-field-class form-row-wide'),
'label' => __('Roast Level'),
'required' => false,
'return' => false,
'options' => array(
'' => 'Please select',
'Blue' => 'Blue',
'Rare' => 'Rare',
'Medium Rare' => 'Medium Rare',
'Medium' => 'Medium',
'Medium Well' => 'Medium Well',
'Well Done' => 'Well Done'
)
), '' );
echo $select;
echo '</div>';
}
}
/*---------------------------------------------------------------
* Add as custom cart item data
---------------------------------------------------------------*/
add_filter( 'woocommerce_add_cart_item_data', 'add_custom_cart_item_data', 10, 21 );
function add_custom_cart_item_data($cart_item_data, $product_id, $variation_id ){
if( isset( $_POST['roast_custom_options'] ) ) {
$cart_item_data['roast_option'] = wc_clean( $_POST['roast_custom_options'] );
}
return $cart_item_data;
}
/*---------------------------------------------------------------
* Add custom fields values under cart item name in cart
---------------------------------------------------------------*/
add_filter( 'woocommerce_cart_item_name', 'roast_custom_field', 10, 21 );
function roast_custom_field( $item_name, $cart_item, $cart_item_key ) {
if( ! is_cart() )
return $item_name;
if( isset($cart_item['roast_option']) ) {
$item_name .= '<br /><div class="my-custom-class"><strong>' . __("Roast Level", "woocommerce") . ':</strong> ' . $cart_item['roast_option'] . '</div>';
}
return $item_name;
}
/*---------------------------------------------------------------
* Display roast custom fields values under item name in checkout
---------------------------------------------------------------*/
add_filter( 'woocommerce_checkout_cart_item_quantity', 'roast_custom_checkout_cart_item_name', 10, 21 );
function roast_custom_checkout_cart_item_name( $item_qty, $cart_item, $cart_item_key ) {
if( isset($cart_item['roast_option']) ) {
$item_qty .= '<br /><div class="my-custom-class"><strong>' . __("Roast Level", "woocommerce") . ':</strong> ' . $cart_item['roast_option'] . 'гр.</div>';
}
return $item_qty;
}
/*---------------------------------------------------------------
* 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, 21 );
function save_order_item_product_fitting_color( $item, $cart_item_key, $values, $order ) {
if( isset($values['roast_option']) ) {
$key = __('Roast Level', 'woocommerce');
$value = $values['roast_option'];
$item->update_meta_data( $key, $value ,$item->get_id());
}
}
add_action('wp_footer','add_footer_script');
function add_footer_script(){
?>
<script>
jQuery('#roast_custom_options').on('change',function(){
var roast_level = jQuery(this).val();
/*console.log(roast_level); */
var button = jQuery(this).closest('form').find('.add_to_cart_button'); console.log(button);
jQuery(button).attr('data-roast_custom_options',roast_level);
});
</script>
<?php
}
I need to add the “Roast Level” selection form to the quick view window, to the
content-product-quick-view.php file.
When adding code, errors appeared. The form does not show, or the "Add to Cart" button disappears.
global $product;
// If is single product page and have the "roast_checkbox" enabled we display the field
if ( $product->get_meta( '_roast_checkbox' ) === 'yes' ) {
echo '<div class="roast_select">';
$select = woocommerce_form_field( 'roast_custom_options', array(
'type' => 'select',
'class' => array('my-field-class form-row-wide'),
'label' => __('Roast Level'),
'required' => false,
'return' => false,
'options' => array(
'' => 'Please select',
'Blue' => 'Blue',
'Rare' => 'Rare',
'Medium Rare' => 'Medium Rare',
'Medium' => 'Medium',
'Medium Well' => 'Medium Well',
'Well Done' => 'Well Done'
)
), '' );
echo $select;
echo '</div>';
}
As a result, I could not put this code in the php file. Perhaps here need to add additional code. And I ask for your help.
Change your script in add_footer_script with this:
( function( $ ) {
$( document ).ready( function() {
$(document).on('change', '#roast_custom_options' ,function() {
$('.add_to_cart_button').data('roast_custom_options', this.value)
});
});
}( jQuery ) );
if you are using ajax, you must subscribe via the parent container or document. To pass custom field using data attribute.
That template already has the variable product and and you're redeclaring it. Remove global $product from it the code you added to content-product-quick-view.php file and you should be good to go.
Related
I read a few articles on the optgroup which is what i need, i manage to display it on the checkout page, but i need the selected option to be visible on email and the admin area where we view the order details.
Code comes from: "WooCommerce Select Dropdown With Optgroup On Checkout"
What I need: I'm creating a website where I need to add manually a few areas on the checkout page so the user can select his area so I can use it as validation and a way to limit the shipping, once the select area I need to be able to see this on the email order as well on the order that on Woocommerce zones doesn't fit in my case:
<?php
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 = __("zona", $domain);
$slug = zone_limit;
$default = __("Selecione su Zona", $domain);
$value = $checkout->get_value($slug);
// Region option data array with optgroup
$options = array(
__("North zone", $domain) => array(
'region1' => __("Region 1", $domain),
'region2' => __("Region 2", $domain),
),
__("South zone", $domain) => array(
'region3' => __("Region 3", $domain),
'region4' => __("Region 4", $domain),
)
__("Middle zone", $domain) => array(
'region3' => __("Region 5", $domain),
'region4' => __("Region 6", $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>';
}
I've tried this but not lucky
add_filter( 'woocommerce_email_order_meta_fields', 'custom_woocommerce_email_order_meta_fields', 10, 3 );
function custom_woocommerce_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
$fields['meta_key'] = array(
'label' => __( 'Label' ),
'value' => get_post_meta( $order->id, 'meta_key', true ),
);
return $fields;
}
add_filter('woocommerce_email_order_meta_keys', 'my_custom_order_meta_keys');
function my_custom_order_meta_keys( $keys ) {
$keys[] = $value ; // This will look for a custom field called 'Tracking Code' and add it to emails
return $keys;
}
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST[$value ] ) ) {
update_post_meta( $order_id, 'region', sanitize_text_field( $_POST[$value ] ) );
}
}
I hope i don't be penalized for this, my initial question was adding the selected value to the email order and use the optgroup collapse effect, however i was told the question was to broad, so i removed the jquery tag and effect and limit my self just the the php and getting it on the email order.
the php was fine i just couln'd get it on the email plus i needed the optgroup.
I did something else, i just used jquery instead of full php only, i created text type field and get it to send answer to email, then i created a modal manually(not wanted to use bootstrap) then a regular html for the optgroup and use jquery get the selected value and insert into the text field. here is my code.
The html is a basic that you can find here
And the css you can use this as example then bot css and html will need to be modify as you need
The php
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
echo '<div id="myZoneLimit"><h2>' . __('valida tu zona') . '</h2>';
woocommerce_form_field( 'my_field_limit', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('Fill in this field'),
'placeholder' => __('Enter something'),
), $checkout->get_value( 'my_field_limit' ));
echo '</div>';
}
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
// Check if set, if its not set add an error.
if ( ! $_POST['my_field_limit'] )
wc_add_notice( __( 'Por favor seleccione su zona de envio.' ), 'error' );
}
add_filter('woocommerce_email_order_meta_keys', 'my_custom_order_meta_keys');
function my_custom_order_meta_keys( $keys ) {
$keys[] = 'valida tu zona'; // This will look for a custom field called 'Tracking Code' and add it to emails
return $keys;
}
add_action( 'woocommerce_checkout_update_order_meta',
'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['my_field_limit'] ) ) {
update_post_meta( $order_id, 'valida tu zona', sanitize_text_field( $_POST['my_field_limit'] ) );
}
}
add_action( 'woocommerce_admin_order_data_after_billing_address','my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('valida tu zona').':</strong> ' . get_post_meta( $order->id, 'valida tu zona', true ) . '</p>';
My jquery
/// button that opens the modal that was created the html
$("#my_field_limit").click(function(){
$("#myModalarea").show();
});
//// get the value from the selected option and place in into the the text field
$('#coveredareas').change(function(){
var areazone = $(this).val();
$("#my_field_limit").val(areazone);
I added custom Select Box in the woocommerce checkout . I just want that the value first time entered by logged in customer gets saved in his user meta so that in future orders he does not need to select the value from custom select box again.
Every thing else working fine
below is the code
add_action('woocommerce_before_order_notes', 'wps_add_select_checkout_field');
function wps_add_select_checkout_field( $checkout ) {
echo '<h3>'.__('Locality').'</h3>';
woocommerce_form_field( 'daypart', array(
'type' => 'select',
'class' => array( 'wps-drop' ),
'label' => __( 'Deliverable Locations' ),
'required' => true,
'options' => array(
'blank' => __( 'Select a Locality', 'wps' ),
'morning' => __( 'opt1', 'wps' ),
'afternoon' => __( 'opt2', 'wps' ),
'evening' => __( 'opt2', 'wps' )
)
),
$checkout->get_value( 'daypart' ));
}
//* Process the checkout
add_action('woocommerce_checkout_process', 'wps_select_checkout_field_process');
function wps_select_checkout_field_process() {
global $woocommerce;
// Check if set, if its not set add an error.
if ($_POST['daypart'] == "blank")
wc_add_notice( '<strong>Please select a locality </strong>', 'error' );
}
//* Update the order meta with field value
add_action('woocommerce_checkout_update_order_meta', 'wps_select_checkout_field_update_order_meta');
function wps_select_checkout_field_update_order_meta( $order_id ) {
if ($_POST['daypart']) update_post_meta( $order_id, 'daypart', esc_attr($_POST['daypart']));
}
//* Display field value on the order edition page
add_action( 'woocommerce_admin_order_data_after_billing_address',
'wps_select_checkout_field_display_admin_order_meta', 10, 1 );
function wps_select_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Delivery option').':</strong> ' . get_post_meta( $order->id, 'daypart', true ) . '</p>';
}
//* Add selection field value to emails
add_filter('woocommerce_email_order_meta_keys', 'wps_select_order_meta_keys');
function wps_select_order_meta_keys( $keys ) {
$keys['Daypart:'] = 'daypart';
return $keys;
}
The following code displays a custom checkbox before add to cart button on single product pages:
add_action( 'woocommerce_before_add_to_cart_button', 'output_custom_text_field', 0 );
function output_custom_text_field() {
//Lots of code then:
<input type="checkbox" id="option1" name="option1">
}
Now I would like to trap/capture this checkbox option in Woocommerce session and then make a custom price calculations in the following code:
function final_cart_update( $cart_object ) {
foreach ( $cart_object->get_cart() as $cart_item ) {
// get the custom pricing for this product
if (isset( $_POST['option1'])) {
$pricing_custom = get_post_meta( $cart_item['product_id'], '_number_field_1', true );
}
// get product price
$price = floatval( $cart_item['data']->get_price() );
// set new price
$cart_item['data']->set_price( $price + $pricing_custom );
}
}
add_action( 'woocommerce_before_calculate_totals', 'final_cart_update', 99, 1 );
What is missing is the part that will capture the checkbox option to set it in sessions, like:
if (isset( $_POST['option1'])) {
// Set it in session
}
Any help is appreciated.
Admin Part of the code →
/*-------------------------------------------*/
/* 5. Adding Custom Field */
/*-------------------------------------------*/
// Add custom fields in "product data" settings metabox ("Advanced" tab)
add_action('woocommerce_product_options_advanced','woocious_add_custom_field_product_dashboard');
function woocious_add_custom_field_product_dashboard(){
global $post;
echo '<div class="product_custom_field">';
// Checkbox Field
woocommerce_wp_checkbox( array(
'id' => 'woocious_custom_services_fields',
'description' => __('Select if you want add on services', 'woocious'),
'label' => __('Display custom add on services', 'woocious'),
'desc_tip' => 'true',
) );
// Minimum Letter Text Box
woocommerce_wp_text_input( array(
'id' => 'addon_service_1',
'label' => __('Service 1', 'woocommerce'),
'description' => __('set custom minimum Lettering text field', 'woocommerce'),
'desc_tip' => 'true',
) );
// Number Field
woocommerce_wp_text_input(
array(
'id' => '_number_field_1',
'label' => __( 'Service amount 1', 'woocommerce' ),
'placeholder' => '',
'desc_tip' => false,
'description' => __( "Please enter the service amount", 'woocommerce' ),
'type' => 'number',
'desc_tip' => 'true',
'custom_attributes' => array(
'step' => 'any',
'min' => '0'
)
)
);
// Maximum Letter Text Box
woocommerce_wp_text_input( array(
'id' => 'addon_service_2',
'label' => __('Service 2', 'woocommerce'),
'description' => __('set custom maximum Lettering text field', 'woocommerce'),
'desc_tip' => 'true'
) );
// Number Field
woocommerce_wp_text_input(
array(
'id' => '_number_field_2',
'label' => __( 'Service amount 2', 'woocommerce' ),
'placeholder' => '',
'desc_tip' => false,
'description' => __( "Please enter the service amount", 'woocommerce' ),
'type' => 'number',
'desc_tip' => 'true',
'custom_attributes' => array(
'step' => 'any',
'min' => '0'
)
)
);
echo '</div>';
}
// Save Inputted Entries, in the Product Dashboard Text Fields.
add_action('woocommerce_process_product_meta', 'woocommerce_product_custom_fields_save');
function woocommerce_product_custom_fields_save($post_id){
// Checkbox Field
$checkbox = isset( $_POST['woocious_custom_services_fields'] ) ? 'yes' : 'no';
update_post_meta( $post_id, 'woocious_custom_services_fields', $checkbox );
// Save Minimum Letters
if ( isset( $_POST['addon_service_1'] ) )
update_post_meta($post_id, 'addon_service_1', sanitize_text_field( $_POST['addon_service_1'] ) );
// Save Maximum Letters
if ( isset( $_POST['addon_service_2'] ) )
update_post_meta($post_id, 'addon_service_2', sanitize_text_field( $_POST['addon_service_2'] ) );
// Save the services amount
if ( isset( $_POST['_number_field_1'] ) )
update_post_meta($post_id, '_number_field_1', sanitize_text_field( $_POST['_number_field_1'] ) );
}
Outputting HTML on Product Page →
// Output Custom Text Field to Product Page
add_action( 'woocommerce_before_add_to_cart_button', 'output_custom_text_field', 0 );
function output_custom_text_field() {
// Get the checkbox value
$custom_option = get_post_meta( $post->ID, 'woocious_custom_services_fields', true );
// If is single product page and have the "custom text option" enabled we display the field
if ( is_product() && ! empty($custom_option) ) {
?>
<div class="woociousbuy_inner">
<div class="woociousbuy_two">
<h3>Add on Services</h3>
<input type="checkbox" id="option1" name="option1">
<label for="option1"><?php global $post; echo get_post_meta($post->ID,'addon_service_1',true);?>
<svg class="svgcheckbox" width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><path d="M13 50.986L37.334 75 88 25" stroke-width="15" stroke="#66bb6a" fill="none" fill-rule="evenodd" stroke-dasharray="150" stroke-dashoffset="150"/></svg>
</label><span class="woocense_price bold">€<?php global $post; echo get_post_meta($post->ID,'_number_field_1',true);?></span>
</div>
<div class="woociousbuy_inner">
<input type="checkbox" id="option2" name="option2"/>
<label for="option2"><?php global $post; echo get_post_meta($post->ID,'addon_service_2',true);?>
<svg class="svgcheckbox" width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><path d="M13 50.986L37.334 75 88 25" stroke-width="15" stroke="#66bb6a" fill="none" fill-rule="evenodd" stroke-dasharray="150" stroke-dashoffset="150"/></svg>
</label><span class="woocense_price bold">€<?php global $post; echo get_post_meta($post->ID,'_number_field_2',true);?></span>
</div>
</div>
<?php
}
}
You don't need to use any session for that. Use woocommerce_add_cart_item_data filter hook like:
add_action( 'woocommerce_before_add_to_cart_button', 'custom_product_option_checkbox_field' );
function custom_product_option_checkbox_field() {
echo '<p><label><input type="checkbox" id="option1" name="option1"> '.__("Option 1").'</label></p>';
}
// Add selected add-on option as custom cart item data
add_filter( 'woocommerce_add_cart_item_data', 'filter_add_cart_item_data_callback', 10, 3 );
function filter_add_cart_item_data_callback( $cart_item_data, $product_id, $variation_id ) {
if ( isset( $_POST['option1'] ) && $pricing_custom = get_post_meta( $product_id, '_number_field_1', true ) ) {
$cart_item_data['pricing_custom'] = $pricing_custom;
$cart_item_data['unique_key'] = md5( microtime().rand() ); // Make each item unique
}
return $cart_item_data;
}
// Change the product price
add_action( 'woocommerce_before_calculate_totals', 'action_before_calculate_totals_callback', 10, 1 );
function action_before_calculate_totals_callback( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Avoiding hook repetition and price calculation problems
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// Loop through cart items
foreach ( $cart->get_cart() as $cart_item ) {
if ( isset( $cart_item['pricing_custom'] ) ) {
// Set the calculated price
$cart_item['data']->set_price( $cart_item['data']->get_price() + $cart_item['pricing_custom'] );
}
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
I have a code that shows the checkbox on the product edit page. When I click on this checkbox, a select box is displayed on the single product page.
Here is my code:
// Display Checkbox Field
add_action('woocommerce_product_options_general_product_data', 'roast_custom_field_add');
function roast_custom_field_add(){
global $post;
// Checkbox
woocommerce_wp_checkbox(
array(
'id' => '_roast_checkbox',
'label' => __('Roast Level', 'woocommerce' ),
'description' => __( 'Enable roast level!', 'woocommerce' )
)
);
}
// Save Checkbox Field
add_action('woocommerce_process_product_meta', 'roast_custom_field_save');
function roast_custom_field_save($post_id){
// Custom Product Checkbox Field
$roast_checkbox = isset( $_POST['_roast_checkbox'] ) ? 'yes' : 'no';
update_post_meta($post_id, '_roast_checkbox', esc_attr( $roast_checkbox ));
}
// Display Select Box
add_action( 'woocommerce_before_add_to_cart_button', 'add_roast_custom_field', 0 );
function add_roast_custom_field() {
global $post;
// If is single product page and have the "roast_checkbox" enabled we display the field
if ( is_product() && get_post_meta( $post->ID, '_roast_checkbox', true ) == 'yes' ) {
echo '<div>';
woocommerce_form_field( 'roast_custom_options', array(
'type' => 'select',
'class' => array('my-field-class form-row-wide'),
'label' => __('Roast Level'),
'required' => false,
'options' => array(
'' => 'Please select',
'Blue' => 'Blue',
'Rare' => 'Rare',
'Medium Rare' => 'Medium Rare',
'Medium' => 'Medium',
'Medium Well' => 'Medium Well',
'Well Done' => 'Well Done'
)
), '' );
echo '</div>';
}
}
When you click on the checkbox, the selection field is shown correctly.
But the data, after selecting the options are not saved.
Also, these data are not displayed on the cart page, on the checkout page, in the order, etc.
Нere is my code:
// Save roast custom field
add_action( 'woocommerce_add_to_cart', 'roast_custom_field_add_to_cart', 20, 6 );
function roast_custom_field_add_to_cart( $cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data ){
if( isset($_POST['roast_custom_options']) ){
$roast_values = (array) get_post_meta( $product_id, '_roast_custom_options_values', true );
$roast_values[] = sanitize_text_field( $_POST['roast_custom_options'] );
update_post_meta( $product_id, '_roast_custom_options_values', $roast_values );
}
}
// Add custom fields values under cart item name in cart
add_filter( 'woocommerce_cart_item_name', 'roast_custom_field', 10, 3 );
function roast_custom_field( $item_name, $cart_item, $cart_item_key ) {
if( ! is_cart() )
return $item_name;
if( $roast_values = $cart_item['data']->get_meta('_roast_custom_options_values') ) {
$item_name .= '<br /><div class="my-custom-class"><strong>' . __("Roast Level", "woocommerce") . ':</strong> ' . $roast_values . ' </div>';
}
return $item_name;
}
// Display roast custom fields values under item name in checkout
add_filter( 'woocommerce_checkout_cart_item_quantity', 'roast_custom_checkout_cart_item_name', 10, 3 );
function roast_custom_checkout_cart_item_name( $item_qty, $cart_item, $cart_item_key ) {
if( $roast_values = $cart_item['data']->get_meta('_roast_custom_options_values') ) {
$item_qty .= '<br /><div class="my-custom-class"><strong>' . __("Roast Level", "woocommerce") . ':</strong> ' . $roast_values . ' </div>';
}
return $item_qty;
}
// Display roast custom fields values on orders and email notifications
add_filter( 'woocommerce_order_item_name', 'roast_custom_order_item_name', 10, 2 );
function roast_custom_order_item_name( $item_name, $item ) {
$product = $item->get_product();
if( $roast_values = $product->get_meta('_roast_custom_options_values') ) {
$item_name .= '<br /><span class="my-custom-class"><strong>' . __("Roast Level", "woocommerce") . ':</strong> ' . $roast_values . ' </span>';
}
return $item_name;
}
How to fix the code so that everything works correctly?
I have revisited your code "in a hurry", also added some missing function and removed another one:
// Display Checkbox Field
add_action('woocommerce_product_options_general_product_data', 'roast_custom_field_add');
function roast_custom_field_add(){
global $post;
// Checkbox
woocommerce_wp_checkbox(
array(
'id' => '_roast_checkbox',
'label' => __('Roast Level', 'woocommerce' ),
'description' => __( 'Enable roast level!', 'woocommerce' )
)
);
}
// Save Checkbox Field
add_action('woocommerce_process_product_meta', 'roast_custom_field_save');
function roast_custom_field_save($post_id){
// Custom Product Checkbox Field
$roast_checkbox = isset( $_POST['_roast_checkbox'] ) ? 'yes' : 'no';
update_post_meta($post_id, '_roast_checkbox', esc_attr( $roast_checkbox ));
}
// Display Select Box
add_action( 'woocommerce_before_add_to_cart_button', 'add_roast_custom_field', 0 );
function add_roast_custom_field() {
global $product;
// If is single product page and have the "roast_checkbox" enabled we display the field
if ( is_product() && $product->get_meta( '_roast_checkbox' ) === 'yes' ) {
echo '<div>';
woocommerce_form_field( 'roast_custom_options', array(
'type' => 'select',
'class' => array('my-field-class form-row-wide'),
'label' => __('Roast Level'),
'required' => false,
'options' => array(
'' => 'Please select',
'Blue' => 'Blue',
'Rare' => 'Rare',
'Medium Rare' => 'Medium Rare',
'Medium' => 'Medium',
'Medium Well' => 'Medium Well',
'Well Done' => 'Well Done'
)
), '' );
echo '</div>';
}
}
// Add as custom cart item data
add_filter( 'woocommerce_add_cart_item_data', 'add_custom_cart_item_data', 10, 3 );
function add_custom_cart_item_data($cart_item_data, $product_id, $variation_id ){
if( isset( $_POST['roast_custom_options'] ) ) {
$cart_item_data['roast_option'] = wc_clean( $_POST['roast_custom_options'] );
}
return $cart_item_data;
}
// Add custom fields values under cart item name in cart
add_filter( 'woocommerce_cart_item_name', 'roast_custom_field', 10, 3 );
function roast_custom_field( $item_name, $cart_item, $cart_item_key ) {
if( ! is_cart() )
return $item_name;
if( isset($cart_item['roast_option']) ) {
$item_name .= '<br /><div class="my-custom-class"><strong>' . __("Roast Level", "woocommerce") . ':</strong> ' . $cart_item['roast_option'] . '</div>';
}
return $item_name;
}
// Display roast custom fields values under item name in checkout
add_filter( 'woocommerce_checkout_cart_item_quantity', 'roast_custom_checkout_cart_item_name', 10, 3 );
function roast_custom_checkout_cart_item_name( $item_qty, $cart_item, $cart_item_key ) {
if( isset($cart_item['roast_option']) ) {
$item_qty .= '<br /><div class="my-custom-class"><strong>' . __("Roast Level", "woocommerce") . ':</strong> ' . $cart_item['roast_option'] . 'гр.</div>';
}
return $item_qty;
}
// 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['roast_option']) ) {
$key = __('Roast Level', 'woocommerce');
$value = $values['roast_option'];
$item->update_meta_data( $key, $value );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
On frontend Cart page:
On backend Order edit pages:
On email notifications:
Your checkbox value is stored to database, try to change this code
$roast_checkbox = isset( $_POST['_roast_checkbox'] ) ? 'yes' : 'no';
with
if ( isset( $_POST['_roast_checkbox'] ) {
$roast_checkbox = $_POST['_roast_checkbox'];
//update_post_meta
}
I am trying to get some custom fields attached to my order in Woocommerce.
I have succeeded previously in getting some new fields entered by the user in the checkout based on this official documentation.
What I am trying to achieve is passing a set string value to a custom field based on some other product checking logic I have working. Basically if product of a certain category:
is in cart, display message one: (shipping_instructions_delivery_field_update_order_meta)
otherwise display message two (shipping_instructions_pickup_field_update_order_meta).
My code:
// adds order note at checkout page for the RRNC to pickup at home
add_action( 'woocommerce_before_checkout_form', 'specific_checkout_content', 12 );
function specific_checkout_content() {
// set your special category name, slug or ID here:
$special_cat = 'randwick-rugby-netball-club';
$bool = false;
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$item = $cart_item['data'];
if ( has_term( $special_cat, 'product_cat', $item->id ) )
$bool = true;
}
// If the special category is detected in one items of the cart
// It displays the message
if ($bool)
{
echo '<div class="checkout-instructions"><p><strong>PLEASE PICK UP ORDER FROM THE CLUB.</strong></p></div>';
add_filter( 'woocommerce_cart_needs_shipping_address', '__return_false'); //Removes the ship to different address for club store items
add_filter( 'woocommerce_enable_order_notes_field', 'remove_wc_order_notes' ); //Removes the order notes
add_action( 'woocommerce_checkout_update_order_meta', 'shipping_instructions_pickup_field_update_order_meta' ); //Adds the pick up note for the pdf slip
add_action( 'woocommerce_checkout_process', 'my_custom_checkout_field_process_pickup' );
}
else
{
echo '<p><strong>Orders are dispatched within 2 business days and shipping times are estimated at between 3-7 business days depending on your location within Australia.</strong></p>';
add_action( 'woocommerce_before_order_notes', 'delivery_instructions_field', 10 ); //Adds the Delivery Instructions fields to the checkout
add_action( 'woocommerce_checkout_update_order_meta', 'shipping_instructions_delivery_field_update_order_meta' ); //Adds the delivery note for the pdf slip
add_action( 'woocommerce_checkout_process', 'my_custom_checkout_field_process_delivery' );
}
}
function my_custom_checkout_field_process_delivery( ) {
global $woocommerce;
// Check if set, if its not set add an error.
if ( !$_POST[ 'delivery_instructions' ] )
wc_add_notice( __( 'Please select from the delivery options.' ), 'error' );
/*$woocommerce->add_error( __( 'Please select from the delivery options.' ) );*/
if ( !$_POST[ 'sport_instructions' ] )
wc_add_notice( __( 'Please select the sport of the order' ), 'error' );
/*$woocommerce->add_error( __( 'Please select the sport of the order' ) );*/
}
function my_custom_checkout_field_process_pickup( ) {
global $woocommerce;
// Check if set, if its not set add an error.
if ( !$_POST[ 'sport_instructions' ] )
wc_add_notice( __( 'Please select the sport of the order' ), 'error' );
/*$woocommerce->add_error( __( 'Please select the sport of the order' ) );*/
}
// remove Order Notes from checkout field in Woocommerce
function remove_wc_order_notes() {
return false;
}
function shipping_instructions_delivery_field_update_order_meta( $order_id ) {
update_post_meta( $order_id, 'shipping_instructions', 'IF YOU HAVE NOT RECEIVED YOUR ORDER WITHIN 7 DAYS, PLEASE CONTACT US TO FOLLOW UP' );
}
function shipping_instructions_pickup_field_update_order_meta( $order_id ) {
update_post_meta( $order_id, 'shipping_instructions', 'PLEASE PICK UP FROM THE CLUB SHOP' );
}
//Admin side
/**
* Update the order meta with field value
**/
add_action( 'woocommerce_checkout_update_order_meta', 'delivery_instructions_field_update_order_meta' );
function delivery_instructions_field_update_order_meta( $order_id ) {
if ( $_POST[ 'delivery_instructions' ] )
update_post_meta( $order_id, 'delivery_instructions', esc_attr( $_POST[ 'delivery_instructions' ] ) );
}
add_action('woocommerce_admin_order_data_after_billing_address', 'my_custom_shipping_fields_display_admin_order_meta', 10, 1);
function my_custom_shipping_fields_display_admin_order_meta($order) {
echo '<p><strong>' . __('Shipping Note') . ':</strong><br> ' . get_post_meta($order->id, 'shipping_instructions', true) . '</p>';
}
$shipping_instructions = get_post_meta($wpo_wcpdf->export->order->id,'shipping_instructions',true);
if (isset($shipping_instructions)) {
echo $shipping_instructions;
}
/**
* Add the delivery instructions field to the checkout
**/
function delivery_instructions_field( $checkout ) {
echo '<div id="delivery_instructions_field"><h2>' . __('Delivery Instructions') . '</h2>';
woocommerce_form_field_radio( 'delivery_instructions', array(
'type' => 'select',
'class' => array(
'delivery_instructions form-row-wide'
),
'label' => __( '' ),
'placeholder' => __( '' ),
'required' => true,
'options' => array(
'Signature Required' => '<b> Signature Required</b><br/>A signature is required for the goods to be left at the intended address. If there is no one to sign for your delivery, a card will be left and it is then your responsibility to collect the items from the nearest depot or arrange for the courier to return. This will be at your expense<br/><br/>',
'Leave Unattended' => '<b> Authority to leave unattended</b><br/>Courier will leave your goods at the intended address. You can give directions in the “Order Notes” below for the best place to leave your delivery',
)
), $checkout->get_value( 'delivery_instructions' ) );
echo '</div>';
}
add_action('woocommerce_admin_order_data_after_billing_address', 'my_custom_billing_fields_display_admin_order_meta', 10, 1);
function my_custom_billing_fields_display_admin_order_meta($order) {
echo '<p><strong>' . __('Delivery Instructions') . ':</strong><br> ' . get_post_meta($order->id, 'delivery_instructions', true) . '</p>';
}
$delivery_instructions = get_post_meta($wpo_wcpdf->export->order->id,'_delivery_instructions',true);
if (isset($delivery_instructions)) {
echo $delivery_instructions;
}
/**
* Add the field to the checkout to get the sport of what the customer orders
**/
add_action( 'woocommerce_after_order_notes', 'sport_instructions_field', 20 );
function sport_instructions_field( $checkout ) {
echo '<div id="sport_instructions_field"><h2>' . __('Which sport is this order in relation to?') . '</h2>';
woocommerce_form_field_radio( 'sport_instructions', array(
'type' => 'select',
'class' => array(
'sport_instructions form-row-wide'
),
'label' => __( '' ),
'placeholder' => __( '' ),
'required' => true,
'options' => array(
'Rugby Union' => '<b>Rugby Union</b><br/>',
'Rugby League' => '<b>Rugby League</b><br/>',
'Netball' => '<b>Netball</b><br/>',
'Football' => '<b>Football</b><br/>',
'AFL' => '<b>AFL</b><br/>',
'Touch Tag' => '<b>Touch & Tag</b>',
)
), $checkout->get_value( 'sport_instructions' ) );
echo '</div>';
}
/**
* Update the order meta with field value
**/
add_action( 'woocommerce_checkout_update_order_meta', 'sport_instructions_field_update_order_meta' );
function sport_instructions_field_update_order_meta( $order_id ) {
if ( $_POST[ 'sport_instructions' ] )
update_post_meta( $order_id, 'sport_instructions', esc_attr( $_POST[ 'sport_instructions' ] ) );
}
add_action('woocommerce_admin_order_data_after_billing_address', 'my_custom_sports_fields_display_admin_order_meta', 20, 1);
function my_custom_sports_fields_display_admin_order_meta($order) {
echo '<p><strong>' . __('Sport in relation to') . ':</strong><br> ' . get_post_meta($order->id, 'sport_instructions', true) . '</p>';
}
$sport_instructions = get_post_meta($wpo_wcpdf->export->order->id,'_sport_instructions',true);
if (isset($sport_instructions)) {
echo $sport_instructions;
}
I would think that the update_post_meta() with a string at the end should set it but it does not appear to do anything. Or perhaps I don't have the proper fuctionality with:
function my_custom_checkout_field($checkout).
Any help is appreciated.
Try this code. _shipping_instructions replace this with shipping_instructions
$shipping_instructions = get_post_meta($wpo_wcpdf->export->order >id,'shipping_instructions',true);
if (isset($shipping_instructions)) {
echo $shipping_instructions;
}