Reputation: 77
The answer to the above question helped me, but I still have a problem: Show hide custom Woocommerce checkout field based on selected payment method
I want the Phone field (a field is required) to be displayed when the customer selects the cheque payment gateway, and the mobile field is not displayed and disabled if he selects other payment gateways.
// Conditional Show hide checkout fields based on chosen payment methods
add_action( 'wp_footer', 'conditionally_show_hide_billing_custom_field' );
function conditionally_show_hide_billing_custom_field(){
// Only on checkout page
if ( is_checkout() && ! is_wc_endpoint_url() ) :
?>
<script>
jQuery(function($){
var a = 'input[name="payment_method"]',
b = a + ':checked',
c = '#billing_phone_field'; // The checkout field <p> container selector
// Function that shows or hide checkout fields
function showHide( selector = '', action = 'show' ){
if( action == 'show' )
$(selector).show( 200, function(){
$(this).addClass("validate-required");
});
else
$(selector).hide( 200, function(){
$(this).removeClass("validate-required");
});
$(selector).removeClass("woocommerce-validated");
$(selector).removeClass("woocommerce-invalid woocommerce-invalid-required-field");
}
// Initialising: Hide if choosen payment method is "cheque"
if( $(b).val() !== 'cheque' )
showHide( c, 'hide' );
else
showHide( c );
// Live event (When payment method is changed): Show or Hide based on "cheque"
$( 'form.checkout' ).on( 'change', a, function() {
if( $(b).val() !== 'cheque' )
showHide( c, 'hide' );
else
showHide( c );
});
});
</script>
<?php
endif;
}
The problem is when I choose other payment gateways besides cheque, even though the Phone field is hidden, it is still validated and displays the error (Billing Phone is a required field) - and this field needs to be filled, I don't want this!
Upvotes: 2
Views: 1304
Reputation: 253773
The following will do the job, adding a hidden field to handle the billing phone validation when the billing phone field is visible. When the billing phone field is hidden and empty, no validation error will be prompted, allowing placing the order silently:
// Your settings goes in here
function my_checkout_settings()
{
return array(
'payment_id' => 'cheque', // The payment Id
'field_key_id' => 'billing_phone', // The checkout field key ID
);
}
// Add a hidden billing input field for phone validation purpose
add_action('woocommerce_billing_fields', 'add_an_hidden_billing_fields');
function add_an_hidden_billing_fields($billing_fields) {
extract(my_checkout_settings()); // Load your settings
// Add a hidden input field
$billing_fields[$field_key_id . '_is_valid'] = array(
'type' => 'hidden',
'required' => false,
'default' => '',
);
return $billing_fields;
}
// Disabling conditionally the Billing phone validation
add_action('woocommerce_after_checkout_validation', 'disable_specific_checkout_field_validation_conditionally', 20, 2);
function disable_specific_checkout_field_validation_conditionally($data, $errors) {
extract(my_checkout_settings()); // Load your settings
$validation_key = $field_key_id . '_is_valid'; // The key Id of the hidden field
if (empty($data[$field_key_id]) && isset($data[$validation_key]) && $data[$validation_key]) {
$errors->remove($field_key_id . '_required'); // Remove unwanted error for this field
}
}
// Conditional Show hide billing phone checkout fields based on chosen payment methods
add_action('woocommerce_checkout_init', 'enqueue_checkout_custom_script');
function enqueue_checkout_custom_script() {
extract(my_checkout_settings()); // Load your settings
wc_enqueue_js("const a = 'input[name=payment_method]',
b = a + ':checked',
c = '#{$field_key_id}',
d = c + '_field',
v = c + '_is_valid',
p = '{$payment_id}';
function triggerShowHide(b, d, p, v) {
$(b).val() !== p ? $(d).show(200) : $(d).hide(200);
$(b).val() !== p ? $(v).val('') : $(v).val('1');
}
// On the first load
triggerShowHide(b, d, p, v);
// On payment method 'change' live event
$('form.checkout').on('change', a, function() {
triggerShowHide(b, d, p, v);
});");
}
Code goes in functions.php
file of your active child theme (or in a plugin). Tested and works.
Upvotes: 4