This question already has answers here:
WooCommerce conditional custom checkout fields
(1 answer)
Conditional custom checkout fields based on product category in Woocommerce
(1 answer)
Closed 10 months ago.
I need to provide conditional required fields on 2 of 3 products in my very specific "store" . 1st product has no added fields. Second one has 1 required. 3rd has the same as the second plus one more required. I have tried plugins as I am right brained but they all cause cart failure. I have cobbled together some code from the inter web that has gotten me passed the cart failure but it presents both of the fields to all of the products (I set the second condition to optional in the code so that it would at least work on a basic level with placeholder text in the second field about requirement). In addition I need these conditional fields to be passed to to the completed order so that they show up in the order tables in admin. here is my rudimentary code.
/**
* checkout field addition License Plate.
*
* #param array $fields List of existing billing fields.
* #return array List of modified billing fields.
*/
function parking_add_checkout_fields( $fields ) {
$fields['billing_FIELD_ID'] = array(
'label' => __( 'License Plate & State' ),
'type' => 'text',
'class' => array( 'form-row-wide' ),
'priority' => 110,
'required' => true,
);
return $fields;
}
add_filter( 'woocommerce_billing_fields', 'parking_add_checkout_fields' );
function js_woocommerce_admin_billing_fields( $fields ) {
$fields['FIELD_ID'] = array(
'label' => __( 'License Plate & State' ),
'show' => true,
);
return $fields;
}
add_filter( 'woocommerce_admin_billing_fields', 'js_woocommerce_admin_billing_fields' );
/* checkout field addition Citation.
*
* #param array $fields List of existing billing fields.
* #return array List of modified billing fields.
*/
function citation_add_checkout_fields( $fields ) {
$fields['billing_FIELD2_ID'] = array(
'label' => __( 'Enter Citation #' ),
'type' => 'text',
'class' => array( 'form-row-wide' ),
'priority' => 112,
'required' => false,
'placeholder' => 'If you are purchasing a Citation Dismissal Permit, enter Citation number here',
);
return $fields;
}
add_filter( 'woocommerce_billing_fields', 'citation_add_checkout_fields' );
$fields['FIELD2_ID'] = array(
'label' => __( 'Enter Citation #' ),
'show' => true,
);
return $fields;
add_filter( 'woocommerce_admin_billing_fields', 'js_woocommerce_admin_billing_fields' );
/**
* Remove optional label
* https://elextensions.com/knowledge-base/remove-optional-text-woocommerce-checkout-fields/
*/
add_filter( 'woocommerce_form_field' , 'elex_remove_checkout_optional_text', 10, 4 );
function elex_remove_checkout_optional_text( $field, $key, $args, $value ) {
if( is_checkout() && ! is_wc_endpoint_url() ) {
$optional = ' <span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) . ')</span>';
$field = str_replace( $optional, '', $field );
}
return $field;
}
Related
This question already has answers here:
Order custom fields not displayed on WooCommerce email notifications
(2 answers)
Show the result of custom delivery field on the checkout page in WooCommerce frontend, backend & email notifications
(1 answer)
Closed 8 months ago.
Thanks to some help, I've created a dropdown list on the checkout page of my Woocommerce site. It works beautifully but on my email notification, it shows the code and not the value of the selection. Eg: "My Marketer: mariaMarais" instead of "My Marketer: Maria Marais - Natal." How can I change it to show the string and not the code?
// add marketer list
//* Add select field to the checkout page
add_action('woocommerce_before_order_notes', 'dd_add_select_two_checkout_field');
function dd_add_select_two_checkout_field( $checkout ) {
woocommerce_form_field( 'myquestion', array(
'type' => 'select',
'class' => array( 'select2-wrapper' ),
'label' => __( 'Please select your marketer.' ),
'required' => true,
'input_class' => array( 'add-select2' ),
'options' => array( // added extra for effect.
'headoffice' => __( 'Head Office', 'wps' ),
'mariaMarais' => __( 'Maria Marais - Natal', 'wps' )
)
),
$checkout->get_value( 'myquestion' ));
wc_enqueue_js( "$( '.add-select2' ).selectWoo(); ");
}
//* 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['myquestion']) update_post_meta( $order_id, 'myquestion', esc_attr($_POST['myquestion']));
}
//* 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>'.__('Found by').':</strong> ' . get_post_meta( $order->id, 'myquestion', 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['My Marketer:'] = 'myquestion';
return $keys;
}
I create custome data field to my woocommerce product. I'll like to display this info (date, time and venue) on every step of the reservation. In check out page, order details and email. Could you please help me ? Find below the code I use for md custom fiels. Thanks a lot
add_action( 'woocommerce_product_options_inventory_product_data', 'woocom_inventory_product_data_custom_field' );
function woocom_Inventory_product_data_custom_field() {
// Create a custom text field
// Text Field
woocommerce_wp_text_input(
array(
'id' => 'venue',
'label' => __( 'Venue', 'woocommerce' ),
'placeholder' => 'Venue',
'desc_tip' => 'true',
'description' => __( 'Enter the location here.', 'woocommerce' )
)
);
woocommerce_wp_text_input(
array(
'id' => 'date',
'label' => __( 'Date', 'woocommerce' ),
'placeholder' => 'date',
'desc_tip' => 'true',
'description' => __( 'Enter the date here.', 'woocommerce' )
)
);
woocommerce_wp_text_input(
array(
'id' => 'time',
'label' => __( 'Time', 'woocommerce' ),
'placeholder' => 'time',
'desc_tip' => 'true',
'description' => __( 'Enter the time here.', 'woocommerce' )
)
);
}
// Hook to save the data value from the custom fields
add_action( 'woocommerce_process_product_meta', 'woocom_save_inventory_proddata_custom_field' );
/** Hook callback function to save custom fields information */
function woocom_save_inventory_produdata_custom_field( $post_id ) {
// Save Text Field
$text_field = $_POST['venue'];
if( ! empty( $text_field ) ) {
update_post_meta( $post_id, 'venue', esc_attr( $text_field ) );
}
$text_field = $_POST['date'];
if( ! empty( $text_field ) ) {
update_post_meta( $post_id, 'date', esc_attr( $text_field ) );
}
$text_field = $_POST['time'];
if( ! empty( $text_field ) ) {
update_post_meta( $post_id, 'time', esc_attr( $text_field ) );
}
}
Adding a custom field in the back-end:
This will add a new field in the Product Data section of a WooCommerce product.
/**
* Display the custom text field
* #since 1.0.0
*/
function cfwc_create_custom_field() {
$args = array(
'id' => 'custom_text_field_title',
'label' => __( 'Custom Text Field Title', 'cfwc' ),
'class' => 'cfwc-custom-field',
'desc_tip' => true,
'description' => __( 'Enter the title of your custom text field.', 'ctwc' ),
);
woocommerce_wp_text_input( $args );
}
add_action( 'woocommerce_product_options_general_product_data', 'cfwc_create_custom_field' );
Hooking the custom field function:
To ensure that the custom field displays in the correct place – in this case, it’s just on the General tab – we need to hook our function to the correct action: woocommerce_product_options_general_product_data.
If you wanted to add your custom field to a different tab, you could try actions like:
woocommerce_product_options_inventory_product_data
woocommerce_product_options_shipping
Saving the custom field value
With this code, we’ve got a really simple way to add custom fields to products, using standard WooCommerce functions and actions. All we need to do know is save the value of the field when the product is updated.
/**
* Save the custom field
* #since 1.0.0
*/
function cfwc_save_custom_field( $post_id ) {
$product = wc_get_product( $post_id );
$title = isset( $_POST['custom_text_field_title'] ) ? $_POST['custom_text_field_title'] : '';
$product->update_meta_data( 'custom_text_field_title', sanitize_text_field( $title ) );
$product->save();
}
add_action( 'woocommerce_process_product_meta', 'cfwc_save_custom_field' );
This function runs when the product is first published or when it’s updated. It looks for a value in our custom field, sanitises it, then saves it as product meta data using the CRUD methodology introduced to WooCommerce a few versions ago.
The function hooks to the woocommerce_process_product_meta action.
Adding custom values to the cart
Assuming the product successfully validates, it’ll get added to the WooCommerce cart object. We can add our own meta data to this object so that we can use it later in the process, e.g. on the cart and checkout pages and for orders and emails.
/**
* Add the text field as item data to the cart object
* #since 1.0.0
* #param Array $cart_item_data Cart item meta data.
* #param Integer $product_id Product ID.
* #param Integer $variation_id Variation ID.
* #param Boolean $quantity Quantity
*/
function cfwc_add_custom_field_item_data( $cart_item_data, $product_id, $variation_id, $quantity ) {
if( ! empty( $_POST['cfwc-title-field'] ) ) {
// Add the item data
$cart_item_data['title_field'] = $_POST['cfwc-title-field'];
}
return $cart_item_data;
}
add_filter( 'woocommerce_add_cart_item_data', 'cfwc_add_custom_field_item_data', 10, 4 );
This function hooks to woocommerce_add_cart_item_data, which filters the data passed to the cart object when a product is added to the cart. So here we check that the cfwc-title-field has a value then add that to $cart_item_data.
Displaying custom fields in the cart and checkout
Having ensured that our custom field is visible to the user in the cart and checkout forms, we now need to pass its value to the order when the user checks out.
/**
* Add custom field to order object
*/
function cfwc_add_custom_data_to_order( $item, $cart_item_key, $values, $order ) {
foreach( $item as $cart_item_key=>$values ) {
if( isset( $values['title_field'] ) ) {
$item->add_meta_data( __( 'Custom Field', 'cfwc' ), $values['title_field'], true );
}
}
}
add_action( 'woocommerce_checkout_create_order_line_item', 'cfwc_add_custom_data_to_order', 10, 4 );
We can do this very easily using the woocommerce_checkout_create_order_line_item action.
How to add custom field in shipping method using woocommerce wordpress
Please see my screenshot
Please try this code.
if ( ! function_exists( 'dimative_shipping_instance_form_fields_filters' ) ) {
/**
* Shipping Instance form add extra fields.
*
* #param array $settings Settings.
* #return array
*/
function dimative_shipping_instance_form_add_extra_fields( $settings ) {
$settings['shipping_extra_field_title'] = array(
'title' => esc_html__( 'Shipping method title', 'zincheco' ),
'type' => 'text',
'placeholder' => esc_html__( 'Please add shipping method title', 'zincheco' ),
'description' => '',
);
$settings['shipping_extra_field_description'] = array(
'title' => esc_html__( 'Shipping method description', 'zincheco' ),
'type' => 'textarea',
'placeholder' => esc_html__( 'Please add your shipping method description', 'zincheco' ),
'description' => '',
);
return $settings;
}
/**
* Shipping instance form fields.
*/
function dimative_shipping_instance_form_fields_filters() {
$shipping_methods = WC()->shipping->get_shipping_methods();
foreach ( $shipping_methods as $shipping_method ) {
add_filter( 'woocommerce_shipping_instance_form_fields_' . $shipping_method->id, 'dimative_shipping_instance_form_add_extra_fields' );
}
}
add_action( 'woocommerce_init', 'dimative_shipping_instance_form_fields_filters' );
}
In case if someone is looking how to get the value using #Өлзийбат-Нансалцог code example. I was able to retrieve it this way:
//Get Shipping rate object
//$method->id is the ID of the shipping method.
//In my case I used that in cart-shipping.php template
$WC_Shipping_Rate = new WC_Shipping_Rate($method->id);
// Returned value is flat_rate:1
$shipping_rate_id = $WC_Shipping_Rate->get_id();
//Replacing : with underscore to have the id in format of flat_rate_1
$shipping_rate_id = str_replace(':', '_', $shipping_rate_id);
//Get the description field value
//Since the value is stored inside options table use get_option() method
get_option('woocommerce_'.$shipping_rate_id.'_settings')['shipping_extra_field_description']
Here is the code for getting the value.
if ( ! function_exists( 'dimative_shipping_method_description' ) ) {
/**
* Function will print shipping method description.
*
* #param object $method Shipping method object.
* #param int $index Shipping method index.
* #return void
*/
function dimative_shipping_method_description( $method, $index ) {
$dimative_method_fields = get_option( 'woocommerce_' . $method->method_id . '_' . $method->instance_id . '_settings' );
$dimative_method_allowed_html = array(
'p' => array(
'class' => array(),
),
'strong' => array(),
'b' => array(),
'a' => array(
'href' => array(),
),
'span' => array(
'class' => array(),
),
);
// Shipping method custom description.
if ( $dimative_method_fields['shipping_extra_field_description'] ) {
?>
<div class="method-description"><?php echo wp_kses( $dimative_method_fields['shipping_extra_field_description'], $dimative_method_allowed_html ); ?></div>
<?php
}
}
add_action( 'woocommerce_after_shipping_rate', 'dimative_shipping_method_description', 1, 2 );
}
This question already has answers here:
Add custom order status and send email on status change in Woocommerce
(1 answer)
Display orders with a custom status for "all" in Woocommerce admin orders list
(1 answer)
Closed 4 years ago.
Add shipped status on order status change and when status changed to shipped email notification will be send to billing email address.
I tried more and more articles, Please help. I need more explanation from this one.
Please use below code in your functions.php
Register Shipped Order Status in WooCommerce
/**
* Add custom status to order list
*/
add_action( 'init', 'register_custom_post_status', 10 );
function register_custom_post_status() {
register_post_status( 'wc-shipped', array(
'label' => _x( 'Shipped', 'Order status', 'woocommerce' ),
'public' => true,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop( 'Shipped <span class="count">(%s)</span>', 'Shipped <span class="count">(%s)</span>', 'woocommerce' )
) );
}
/**
* Add custom status to order page drop down
*/
add_filter( 'wc_order_statuses', 'custom_wc_order_statuses' );
function custom_wc_order_statuses( $order_statuses ) {
$order_statuses['wc-shipped'] = _x( 'Shipped', 'Order status', 'woocommerce' );
return $order_statuses;
}
Here is the code for ending email to custom order status
add_action('woocommerce_order_status_changed', 'shipped_status_custom_notification', 10, 4);
function shipped_status_custom_notification( $order_id, $from_status, $to_status, $order ) {
if( $order->has_status( 'shipped' )) {
// Getting all WC_emails objects
$email_notifications = WC()->mailer()->get_emails();
// Customizing Heading and subject In the WC_email processing Order object
$email_notifications['WC_Email_Customer_Processing_Order']->heading = __('Your Order shipped','woocommerce');
$email_notifications['WC_Email_Customer_Processing_Order']->subject = 'Your {site_title} order shipped receipt from {order_date}';
// Sending the customized email
$email_notifications['WC_Email_Customer_Processing_Order']->trigger( $order_id );
}
}
add_action( 'woocommerce_order_status_wc-shipped', array( WC(), 'send_transactional_email' ), 10, 1 );
add_filter( 'woocommerce_email_actions', 'filter_woocommerce_email_actions' );
function filter_woocommerce_email_actions( $actions ){
$actions[] = 'woocommerce_order_status_wc-shipped';
return $actions;
}
Thanks to the filter "WooCommerce admin billing fields" I have ordered the billing fields in the notificiación footer by email but when I try to insert my custom billing field does not appear.
add_filter( 'woocommerce_order_formatted_billing_address' , 'woo_reorder_billing_fields', 10, 2 );
function woo_reorder_billing_fields( $address, $wc_order ) {
$address = array(
'first_name' => $wc_order->billing_first_name,
'last_name' => $wc_order->billing_last_name,
'company' => $wc_order->billing_company,
'my_field' => $wc_order->billing_my_field,
'country' => $wc_order->billing_country
);
return $address;
}
In order admin edit I can show my custom billing field thanks to the filter "woocommerce_admin_billing_fields", first adding the field and then reordering the Array.
I note that I added before and I have reordered this field in my checkout with the filter "woocommerce_checkout_fields".
Why not show my custom field if "$ wc_order" object stores the field in the checkout?
Any ideas?
Thanks in advance!
Yes, here the explanation:
We will register the new cusotm field, in this example the field "VAT" to store the fiscal document for companies in the European Union. There is a lot of documentation on how to register the custom fields and display them in the admin / user panel.
add_filter( 'woocommerce_default_address_fields', 'woo_new_default_address_fields' );
function woo_new_default_address_fields( $fields ) {
$fields['vat'] = array(
'label' => __( 'VAT number', 'woocommerce' ),
'class' => array( 'form-row-wide', 'update_totals_on_change' ),
);
return $fields;
}
Then add the new field "VAT" only to the registration of billing fields for mails, we do not want it to appear in the address fileds section.
add_filter( 'woocommerce_order_formatted_billing_address' , 'woo_custom_order_formatted_billing_address', 10, 2 );
function woo_custom_order_formatted_billing_address( $address, $WC_Order ) {
$address = array(
'first_name' => $WC_Order->billing_first_name,
'last_name' => $WC_Order->billing_last_name,
'vat' => $WC_Order->billing_vat,
'company' => $WC_Order->billing_company,
'address_1' => $WC_Order->billing_address_1,
'address_2' => $WC_Order->billing_address_2,
'city' => $WC_Order->billing_city,
'state' => $WC_Order->billing_state,
'postcode' => $WC_Order->billing_postcode,
'country' => $WC_Order->billing_country
);
return $address;
}
The following code customizes the appearance of the addresses, this is where we must add the call to the new VAT field. This allows us to customize the address view for each country independently.
add_filter( 'woocommerce_formatted_address_replacements', function( $replacements, $args ){
$replacements['{vat}'] = $args['vat'];
return $replacements;
}, 10, 2 );
add_filter( 'woocommerce_localisation_address_formats' , 'woo_includes_address_formats', 10, 1);
function woo_includes_address_formats($address_formats) {
$address_formats['ES'] = "{name}\n{company}\n{vat}\n{address_1}\n{address_2}\n{postcode} {city}\n{state}\n{country}";
$address_formats['default'] = "{name}\n{company}\n{vat}\n{nif}\n{address_1}\n{address_2}\n{city}\n{state}\n{postcode}\n{country}";
return $address_formats;
}
Any questions ask!