Hide selected WooCommerce checkout field based on selected payment method - php

I want to disable several WooCommerce checkout billing fields based on payment method. Currently, I have two payment methods that require email and name only in the billing form. 
I have found the solution in this thread (Show hide custom Woocommerce checkout field based on selected payment method) but the solution is for one payment method only. In addition, when testing that code, the checkout still shows the billing field, not to hide it. It hides the billing field for other payment methods only.
Here is the code that I have tested but the code is for one payment method only:
<?php
// Add custom Theme Functions here
// 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_address_1_field',
d = '#billing_address_2_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 "banktransfer"
if( $(b).val() !== 'banktransfer')
showHide( c, 'hide' ),
showHide( d, 'hide' );
else
showHide( c ),
showHide( d );
// Live event (When payment method is changed): Show or Hide based on "banktransfer"
$( 'form.checkout' ).on( 'change', a, function() {
if( $(b).val() !== 'banktransfer')
showHide( c, 'hide' ),
showHide( d, 'hide' );
else
showHide( c ),
showHide( d );
});
});
</script>
<?php
endif;
}
What is the solution for multiple payment methods?

Related

Show or hide checkout postcode field based on chosen city in WooCommerce

In Woocommerce, I am trying to hide the checkout postcode field if a specific city field is selected. I found a working code that hides the billing phone if company field is empty:
add_action( 'woocommerce_after_checkout_form', 'conditionally_hide_show_checkout_field', 9999 );
function conditionally_hide_show_checkout_field() {
wc_enqueue_js( "
jQuery('#billing_company').keyup(function() {
if (jQuery(this).val().length == 0) {
jQuery('#billing_phone').hide();
} else {
jQuery('#billing_phone').show();
}
}).keyup();
");
}
I don't know how to alter this code to make the required postcode field to be hidden when a specific billing city is selected. Any help is appreciated.
It's a bit much more complicated and you will need to define the city in the last function.
The following code handles multiple necessary tasks to show / hide the postcode field based on a specific defined selected city:
// Make postcode field optional
add_filter( 'woocommerce_default_address_fields', 'customizing_checkout_fields' );
function customizing_checkout_fields( $fields ) {
if( is_checkout() ) {
$fields['postcode']['required'] = false;
}
return $fields;
}
// Replace "(optional)" text by required "*"
add_filter( 'woocommerce_form_field' , 'replace_checkout_optional_by_required', 10, 4 );
function replace_checkout_optional_by_required( $field, $key, $args, $value ) {
// Only on checkout page for postcode field
if( is_checkout() && ! is_wc_endpoint_url() && in_array($key, ['billing_postcode', 'shipping_postcode']) ) {
$optional = '<span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) . ')</span>';
$required = '<abbr class="required" title="required">*</abbr>';
$field = str_replace( $optional, $required, $field );
}
return $field;
}
// Hidden input fields for Postcode validation when it's visible
add_action( 'woocommerce_after_order_notes', 'checkout_hidden_field_for_validation', 10, 1 );
function checkout_hidden_field_for_validation( $checkout ) {
// Hidden field for the phone number validation
echo '<input type="hidden" name="billing_postcode_check" id="billing_postcode_check" value="">
<input type="hidden" name="shipping_postcode_check" id="shipping_postcode_check" value="">';
}
// Postcode field validation when it's visible
add_action('woocommerce_checkout_process', 'wps_select_checkout_field_process');
function wps_select_checkout_field_process() {
if( isset($_POST['billing_postcode_check']) && $_POST['billing_postcode_check'] === 'yes'
&& isset($_POST['billing_postcode']) && empty($_POST['billing_postcode']) ) {
wc_add_notice( __("The billing postcode field is a required field.", "woocommerce"), 'error' );
}
if( isset($_POST['shipping_postcode_check']) && $_POST['shipping_postcode_check'] === 'yes'
&& isset($_POST['shipping_postcode']) && empty($_POST['shipping_postcode']) ) {
wc_add_notice( __("The shipping postcode is a required field.", "woocommerce"), 'error' );
}
}
// 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() ) :
// HERE define the city that will hide postcode field
$city = 'Paris';
$required = ' <abbr class="required" title="required">*</abbr>';
?>
<script>
jQuery(function($){
var bc = '#billing_city_field input',
sc = '#shipping_city_field input',
bp = '#billing_postcode_field',
sp = '#shipping_postcode_field',
bpc = '#billing_postcode_check',
spc = '#shipping_postcode_check',
city = '<?php echo $city; ?>',
req = '<?php echo $required; ?>';
// On "update" checkout form event, replace "(optional)" by required "*"
$(document.body).on('update_checkout', function(){
$('#billing_postcode_field label > .optional').replaceWith(req);
});
// Function that shows or hide checkout fields
function showHide( selector = '', action = 'show' ){
var check = selector == bp ? $(bpc) : $(spc);
if( action == 'show' )
$(selector).show( 200, function(){
$(this).addClass("validate-required");
check.val('yes');
});
else
$(selector).hide( 200, function(){
$(this).removeClass("validate-required");
check.val('');
});
$(selector).removeClass("woocommerce-validated");
$(selector).removeClass("woocommerce-invalid woocommerce-invalid-required-field");
}
// 1. Initialising (on load): Show/hide based on customer city
// Billing field
if( $(bc).val() === city || $(bc).val() == '' )
showHide( bp, 'hide' );
else
showHide( bp );
// Shipping field
if( $(sc).val() === city || $(sc).val() == '' )
showHide( sp, 'hide' );
else
showHide( sp );
// 2. Change live event: Show/hide based on city change
$( 'form.checkout' ).on( 'change input', bc, function() { // Billing field
if( $(bc).val() === city )
showHide( bp, 'hide' );
else
showHide( bp );
});
$( 'form.checkout' ).on( 'change input', sc, function() { // Shipping field
if( $(sc).val() === city )
showHide( sp, 'hide' );
else
showHide( sp );
});
});
</script>
<?php
endif;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
Some related answers:
Show hide custom Woocommerce checkout field based on selected payment method
Remove "(optional)" text from checkout fields in Woocommerce 3.4+
Hidding billing and shipping postcode on load:
Replace:
// 1. Initialising (on load): Show/hide based on customer city
// Billing field
if( $(bc).val() === city || $(bc).val() == '' )
showHide( bp, 'hide' );
else
showHide( bp );
// Shipping field
if( $(sc).val() === city || $(sc).val() == '' )
showHide( sp, 'hide' );
else
showHide( sp );
by:
// 1. Initialising (on load): Hide postcode
showHide( bp, 'hide' ); // Billing field
showHide( sp, 'hide' ); // Shipping field
You can do it like this:
$("#billing_city").on("change", function() {
if ($(this).val() != "") {
$("#postcode").removeAttr('required');
} else {
$("#postcode").prop("required", true);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="billing_city">
<option value="">Select City</option>
<option value="losangeles">LosAngeles</option>
<option value="newyork">New York</option>
</select>
<input type="text" id="postcode" placeholder="Postcode" required />

Show hide custom Woocommerce checkout field based on selected payment method

Hi I added custom field in billing form using this code below.
add_filter('woocommerce_billing_fields', 'custom_woocommerce_billing_fields');
function custom_woocommerce_billing_fields($fields)
{
$fields['billing_options'] = array(
'label' => __('If you pay by Invoice. Please add Your Invoice Number Here ', 'woocommerce'), // Add custom field label
'placeholder' => _x('Invoice Number', 'placeholder', 'woocommerce'), // Add custom field placeholder
'required' => false, // if field is required or not
'clear' => false, // add clear or not
'type' => 'text', // add field type
'class' => array('my-css') // add class name
);
return $fields;
}
I have two payment options 1. Cash on delivery 2.Realex Payments HPP – Credit Card.
Is it possible to show custom field only then 1. Cash on delivery selected as payment option.?
Thank you
The following code will hide billing_options custom optional checkout field when the selected payment method is Cash on delivery ("cod"):
// 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_options_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 "cod"
if( $(b).val() !== 'cod' )
showHide( c, 'hide' );
else
showHide( c );
// Live event (When payment method is changed): Show or Hide based on "cod"
$( 'form.checkout' ).on( 'change', a, function() {
if( $(b).val() !== 'cod' )
showHide( c, 'hide' );
else
showHide( c );
});
});
</script>
<?php
endif;
}
Code goes in function.php file of your active child theme (or active theme). tested and works.

Show or hide html element on chosen shipping method change in Woocommerce

I'm trying to show/hide some elements from my checkout page, based on the chosen shipping method. The page elements I'm trying to show/hide come from another plugin, so I tried to change the display properties for them. I've looked to many thread like:
Show or hide checkout fields based on shipping method in Woocommerce 3
But it's for checkout fields, and I'm not sure how to do it for page elements.
Then based on this answer thread Here's my code so far:
add_action( 'wp_footer', 'conditionally_hidding_order_delivery_date' );
function conditionally_hidding_order_delivery_date(){
// Only on checkout page
if( ! is_checkout() ) return;
// HERE your shipping methods rate ID "Home delivery"
$home_delivery = 'distance_rate_shipping';
?>
<script>
jQuery(function($){
// Choosen shipping method selectors slug
var shipMethod = 'input[name^="shipping_method"]',
shipMethodChecked = shipMethod+':checked';
// Function that shows or hide imput select fields
function showHide( actionToDo='show', selector='' ){
if( actionToDo == '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 shipping method is "Home delivery"
if( $(shipMethodChecked).val() != '<?php echo $home_delivery; ?>' ) {
showHide('hide','#e_deliverydate_field' );
showHide('hide','#time_slot_field' );
}
// Live event (When shipping method is changed)
$( 'form.checkout' ).on( 'change', shipMethod, function() {
if( $(shipMethodChecked).val() == '<?php echo $home_delivery; ?>' ) {
showHide('show','#e_deliverydate_field' );
showHide('show','#time_slot_field' );
}
else {
showHide('hide','#e_deliverydate_field' );
showHide('hide','#time_slot_field' );
}
});
});
</script>
<?php
}
But it's not working completely (the initializing function is not working.)
Any help is very much appreciated.
Additional edit:
<p class="form-row form-row-wide validate-required" id="e_deliverydate_field" data-priority="" style="display: block;"><label for="e_deliverydate" class="">Date<abbr class="required" title="required">*</abbr></label><span class="woocommerce-input-wrapper"><input class="input-text hasDatepicker" name="e_deliverydate" id="e_deliverydate" placeholder="Choose a Date" value="" style="cursor:text !important;" type="text"></span></p>
My objective is to change the display properties for p element from block to none, and vice versa.
The needed code is something much more simple, than the one used in my other answers, but you need to be sure that the targeted chosen shipping method is 'distance_rate_shipping' as I can't test it.
For initialization problem, see the solution exposed at the end of my answer.
The simplified needed code:
// Embedded jQuery script
add_action( 'wp_footer', 'checkout_delivery_date_script' );
function checkout_delivery_date_script() {
// Only checkout page
if( ! ( is_checkout() && ! is_wc_endpoint_url() ) ) return;
?>
<script type="text/javascript">
jQuery( function($){
var a = 'input[name^="shipping_method"]', b = a+':checked',
c = 'distance_rate_shipping',
d = '#e_deliverydate_field,#time_slot_field';
// Utility function that show or hide the delivery date
function showHideDeliveryDate(){
if( $(b).val() == c )
$(d).show();
else
$(d).hide('fast');
console.log('Chosen shipping method: '+$(b).val()); // <== Just for testing (to be removed)
}
// 1. On start
showHideDeliveryDate();
// 2. On live event "change" of chosen shipping method
$('form.checkout').on('change', a, function(){
showHideDeliveryDate();
});
});
</script>
<?php
}
Code goes in function.php file of your active child theme (or theme). It should work.
The initialization problem:
It's certainly because the plugin you are using that generates the delivery date output is delayed after initialization
The solution can be to add some delay on initialization execution.
So should try to replace this:
// 1. On start
showHideDeliveryDate();
By the following in my code (adjusting the execution delay to something higher or lower than 500):
// 1. On start
setTimeout(function(){
showHideDeliveryDate();
}, 500);

Conditionally hide Woocommerce checkout custom field based on free shipping

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.
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.

Conditionally hide a Checkout field in WooCommerce based on chosen shipping

in WooCommerce, I am trying to hide the company name field whenever "delivery to home" is selected. I've tried a bunch of different things.
This is my most recent attempt:
add_filter('woocommerce_checkout_fields', 'xa_remove_billing_checkout_fields');
function xa_remove_billing_checkout_fields($fields) {
$shipping_method ='pakkelabels_shipping_gls1'; // 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_company']); // Add/change filed name to be hide
}
return $fields;
}
But all it does is move the Shipping company from the first field to the last.
How can I conditionally hide a specific checkout field based on chosen shipping method?
As it's a live event, you need to use javascript/jQuery to make it work. The Billing company has to be not required like in default WooCommerce checkout page.
The following code will hide the "Billing company" field, when "Home delivery" shipping is chosen:
// Conditional Show hide checkout fields based on chosen shipping methods
add_action( 'wp_footer', 'conditionally_hidding_billing_company' );
function conditionally_hidding_billing_company(){
// Only on checkout page
if( ! ( is_checkout() && ! is_wc_endpoint_url() ) ) return;
// HERE your shipping methods rate ID "Home delivery"
$home_delivery = 'pakkelabels_shipping_gls1';
?>
<script>
jQuery(function($){
// Choosen shipping method selectors slug
var shipMethod = 'input[name^="shipping_method"]',
shipMethodChecked = shipMethod+':checked';
// Function that shows or hide imput select fields
function showHide( actionToDo='show', selector='' ){
if( actionToDo == '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 shipping method is "Home delivery"
if( $(shipMethodChecked).val() == '<?php echo $home_delivery; ?>' )
showHide('hide','#billing_company_field' );
// Live event (When shipping method is changed)
$( 'form.checkout' ).on( 'change', shipMethod, function() {
if( $(shipMethodChecked).val() == '<?php echo $home_delivery; ?>' )
showHide('hide','#billing_company_field');
else
showHide('show','#billing_company_field');
});
});
</script>
<?php
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and works.

Categories