问题
In WooCommerce, I am trying to hide one custom added field whenever "free delivery" is selected (automatic selection, based on order amount).
I was thinking that I found a solution with code below, but when I load a page on new (incognito) browser window, the field is present and if refresh it, the field is hidden again.
// Hide address field, when Free Shipping mode is selected
add_filter('woocommerce_checkout_fields', 'xa_remove_billing_checkout_fields');
function xa_remove_billing_checkout_fields($fields) {
$shipping_method ='free_shipping:5'; // Set the desired shipping method to hide the checkout field(s).
global $woocommerce;
$chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
$chosen_shipping = $chosen_methods[0];
if ($chosen_shipping == $shipping_method) {
unset($fields['billing']['billing_field_432']); // Add/change filed name to be hide
}
return $fields;
}
Any help is appreciated.
回答1:
As it's a live event, you need to use javascript/jQuery to make it work. Your "billing_field_432" has to be not required, because when field is hidden and trying to submit the order, will throw an error notice message for this custom checkout field.
The code to show / hide that field based on 'free_shipping:5' Shipping method:
// Conditional Show hide checkout fields based on chosen shipping methods
add_action( 'wp_footer', 'conditionally_hidding_billing_custom_field' );
function conditionally_hidding_billing_custom_field(){
// Only on checkout page
if( ! is_checkout() ) return;
// HERE your shipping methods rate ID "Free shipping"
$free_shipping = 'free_shipping:5';
?>
<script>
jQuery(function($){
// Choosen shipping method selectors slug
var sm = 'input[name^="shipping_method"]',
smc = sm + ':checked',
cbf = '#billing_field_432_field',
ihc = 'input[name="hidden_check"]';
// Function that shows or hide imput select fields
function showHide( selector = '', action = 'show' ){
if( action == 'show' )
$(selector).show( 200, function(){
$(this).addClass("validate-required");
$(ihc).val('1'); // Set hidden field for checkout process
});
else
$(selector).hide( 200, function(){
$(this).removeClass("validate-required");
$(ihc).val(''); // Set hidden field for checkout process
});
$(selector).removeClass("woocommerce-validated");
$(selector).removeClass("woocommerce-invalid woocommerce-invalid-required-field");
}
// Initialising: Hide if choosen shipping method is "Free Shipping" method
if( $(smc).val() == '<?php echo $free_shipping; ?>' )
showHide( cbf, 'hide' );
else
$(ihc).val('1'); // Set hidden field for checkout process
// Live event (When shipping method is changed): Show or Hide based on "Free Shipping" method
$( 'form.checkout' ).on( 'change', sm, function() {
if( $(smc).val() == '<?php echo $free_shipping; ?>' )
showHide( cbf, 'hide' );
else
showHide( cbf );
});
});
</script>
<?php
}
The code to add a custom checkout hidden input field to enable the "required" field option check process when 'billing_field_432'
is not hidden:
// Add a hidden input field for "required" option check process
add_filter('woocommerce_checkout_fields', 'add_custom_hidden_input_field' );
function add_custom_hidden_input_field( $fields ) {
echo '<input type="hidden" id="hidden_check" name="hidden_check" value="">';
return $fields;
}
// Check custom checkout field "billing_field_432" when not hidden
add_action('woocommerce_checkout_process', 'check_custom_field_checkout_process');
function check_custom_field_checkout_process() {
// Check if set, if its not set add an error.
if ( isset( $_POST['hidden_check'] ) && $_POST['hidden_check'] && empty( $_POST['billing_field_432'] ) )
wc_add_notice( __( 'Please enter something in "billing field 432".' ), 'error' ); // SET your custom error notice
}
This code goes on function.php file of your active child theme (or theme). Tested and works.
It's based on: Conditionally hide a Checkout field in WooCommerce based on chosen shipping
As you are using free shipping method with a minimum order amount of "50" and hiding other shipping methods when "free shipping" is available. You should use this instead:
// Unset checkout field based on cart amount for free shipping
add_filter('woocommerce_checkout_fields', 'remove_checkout_billing_field_432', 999 );
function remove_checkout_billing_field_432( $fields ) {
if ( WC()->cart->cart_contents_total >= 50 ) {
unset($fields['billing']['billing_field_432']); // Unset field
}
return $fields;
}
This code goes on function.php file of your active child theme (or theme). Tested and works.
来源:https://stackoverflow.com/questions/49266306/conditionally-hide-woocommerce-checkout-custom-field-based-on-free-shipping