Reputation: 71
I need to show this custom field only if I have some product from a specified category. Then only the fields is required.
The code below is just only set to display:none the field, in fact if I click on checkout there is an error like "the field myfield is required", but I need to remove my field not to set display none.
Please any idea?
I have the latest version of WooCommerce.
This is my code :
/**
* Add the field to the checkout
*/
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
// Our hooked in function - $fields is passed via the filter!
function custom_override_checkout_fields( $fields ) {
$fields['billing']['my_field_name'] = array(
'label' => __('Codice medico', 'woocommerce'),
'placeholder' => _x('Inserisci il codice del tuo medico', 'placeholder', 'woocommerce'),
'required' => true,
'class' => array('form-row-wide'),
'clear' => true
);
return $fields;
}
/**
* Process the checkout
*/
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_name'] )
wc_add_notice( __( '<h4 style="color:red;">Stai acquistando un prodotto per cui è necessaria la prescrizione medica. Per favore inserisci il codice del tuo medico per proseguire. Grazie.</h4>' ), 'error' );
}
/**
* Update the order meta with field value
*/
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_name'] ) ) {
update_post_meta( $order_id, 'Codice Medico', sanitize_text_field( $_POST['my_field_name'] ) );
}
}
/**
* Display field value on the order edit page
*/
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>'.__('Codice Medico').':</strong> ' . get_post_meta( $order->id, 'Codice Medico', true ) . '</p>';
}
/* Adding Custom Fields to Emails
1. Add this snippet to your theme's functions.php file
2. Change the meta key names in the snippet
3. Create a custom field in the order post - e.g. key = "Tracking Code" value = abcdefg
4. When next updating the status, or during any other event which emails the user, they will see this field in their email
*/
add_filter('woocommerce_email_order_meta_keys', 'my_custom_order_meta_keys');
function my_custom_order_meta_keys( $keys ) {
$keys[] = 'Codice Medico'; // This will look for a custom field called 'Tracking Code' and add it to emails
return $keys;
}
/**
* Conditionally remove checkout fields
*/
add_filter( 'woocommerce_checkout_fields' , 'conditional_unset_checkout_field' );
function conditional_unset_checkout_field( $fields ) {
$categories = array( 'prodotti-in-polvere-e-bustine', 'gel-e-creme', 'prodotti-in-capsule', 'prodotti-plantari', 'prodotti-liquidi', 'area-riservata' );
$has_cat = false;
// Iterating through each cart items (products)
foreach(WC()->cart->get_cart() as $cart_item){
// Iterating through each category in your array
foreach($categories as $category){
if ( has_term( $category, 'product_cat', $cart_item['product_id'] ) ) {
$has_cat = true;
break;
}
}
if ( $has_cat ) break;
}
// If one of the categories is in one cart item, we unset the field
if ( $has_cat ) {
unset( $fields['billing']['my_field_name'] );
}
return $fields;
}
Upvotes: 1
Views: 810
Reputation: 254448
To unset the field only if there is a defined category in the cart items, and NOT if there is also another category, as you required.
First: You are using here the working code of my answer to your yesterday question:
Remove a checkout field if cart items are from some specific product categories
You didn't mention it here.
After that, I have tested your code (with some minors modifications) on this test server, and It's working perfect as expected! If you add the 1st product of the shop "Flying Ninja" that is in 'posters' category, your custom checkout field will be removed as desired… if you remove "Flying Ninja" from cart and you add for example the 2nd product "Happy Ninja" that is not in 'posters' category, your custom field will show again…
That is your lightly changed code:
/**
* Add the field to the checkout
*/
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
// Our hooked in function - $fields is passed via the filter!
function custom_override_checkout_fields( $fields ) {
$fields['billing']['my_field_name'] = array(
'label' => __('Codice medico', 'woocommerce'),
'placeholder' => _x('Inserisci il codice del tuo medico', 'placeholder', 'woocommerce'),
'required' => true,
'class' => array('form-row-wide'),
'clear' => true
);
return $fields;
}
/**
* Process the checkout
*/
add_action('woocommerce_checkout_process', 'custom_checkout_field_process');
function custom_checkout_field_process() {
// Check if set, if its not set add an error.
if ( ! $_POST['my_field_name'] )
wc_add_notice( __( '<h4 style="color:red;">Stai acquistando un prodotto per cui è necessaria la prescrizione medica. Per favore inserisci il codice del tuo medico per proseguire. Grazie.</h4>' ), 'error' );
}
/**
* Update the order meta with field value
*/
add_action( 'woocommerce_checkout_update_order_meta', 'custom_checkout_field_update_order_meta' );
function custom_checkout_field_update_order_meta( $order_id ) {
$my_field_name = $_POST['my_field_name'];
if ( !empty($my_field_name) )
update_post_meta( $order_id, 'Codice Medico', sanitize_text_field( $my_field_name ) );
}
/**
* Display field value on the order edit page
*/
add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_custom_checkout_field_in_admin_order_meta', 10, 1 );
function display_custom_checkout_field_in_admin_order_meta($order){
echo '<p><strong>'.__('Codice Medico').':</strong> ' . get_post_meta( $order->id, 'Codice Medico', true ) . '</p>';
}
/**
* Conditionally remove checkout fields
*/
add_filter( 'woocommerce_checkout_fields' , 'conditional_unset_checkout_field' );
function conditional_unset_checkout_field( $fields ) {
$categories = array( 'prodotti-in-polvere-e-bustine', 'gel-e-creme', 'prodotti-in-capsule', 'prodotti-plantari', 'prodotti-liquidi', 'area-riservata', 'posters' );
$has_cat = false;
$has_other_cat = false;
// Iterating through each cart items (products)
foreach(WC()->cart->get_cart() as $cart_item){
// Getting the item product categories
$item_categories = wp_get_post_terms( $cart_item['product_id'], 'product_cat' );
foreach($item_categories as $item_category){
if(in_array($item_category->slug, $categories))
$has_cat = true;
else
$has_other_cat = true;
}
}
// If one of your defined categories is in the cart item
// and not the others categories, we unset the field
if ( $has_cat && !$has_other_cat ) {
unset( $fields['billing']['my_field_name'] );
}
return $fields;
}
Upvotes: 3