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.
Related
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?
Works on small home project, and want to add checkmark option bellow "Proceed to Checkout" button into Cart page into my Woocommerce site. I found this function, that is add that option:
add_action( 'woocommerce_after_cart', 'bbloomer_add_checkout_privacy_policy', 9 );
function bbloomer_add_checkout_privacy_policy() {
woocommerce_form_field( 'privacy_policy', array(
'type' => 'checkbox',
'class' => array('form-row privacy'),
'label_class' => array('woocommerce-form__label woocommerce-form__label-for-checkbox checkbox'),
'input_class' => array('woocommerce-form__input woocommerce-form__input-checkbox input-checkbox'),
'required' => true,
'label' => 'By proceeding, you are agreeing to our Terms and Conditions',
));
}
// Show notice if customer does not tick
add_action( 'woocommerce_proceed_to_checkout', 'bbloomer_not_approved_privacy' );
function bbloomer_not_approved_privacy() {
if ( ! (int) isset( $_POST['privacy_policy'] ) ) {
wc_add_notice( __( 'Please acknowledge the Terms and Conditions' ), 'error' );
}
}
But seems that something is not fine with this function, because no matter if checked or not, customer can proceed to checkout page. I want to ensure that ONLY customers who will check the checkbox, can proceed to checkout. In opposite, warning message will be shown at top.
Can someone to tell me where is issue with this function or to point me to some working solution? Thanks in advance. This is image how currently looks with this function i posted before.
The following code will work in cart page for your privacy policy checkbox using mandatory jQuery code to make it work as "proceed to checkout" button is just linked to checkout page without submitting any data.
The code will disable the button on start:
It use "Sweet alert 2" JS message to display an error message on button click when the checkbox is not checked:
The complete code:
add_action( 'woocommerce_proceed_to_checkout', 'cart_privacy_policy_checkbox', 5 );
function cart_privacy_policy_checkbox() {
woocommerce_form_field( 'privacy_policy', array(
'type' => 'checkbox',
'class' => array('form-row privacy'),
'label_class' => array('woocommerce-form__label woocommerce-form__label-for-checkbox checkbox'),
'input_class' => array('woocommerce-form__input woocommerce-form__input-checkbox input-checkbox'),
'required' => true,
'label' => sprintf( __( "I've read and accept the %s", "woocommerce" ),
''.__( "Privacy Policy", "woocommerce" ).'' ),
));
// jQuery code start below
?>
<script src="https://unpkg.com/sweetalert2#8.8.1/dist/sweetalert2.all.min.js"></script>
<script src="https://unpkg.com/promise-polyfill#8.1.0/dist/polyfill.min.js"></script>
<script type="text/javascript">
jQuery( function($){
var a = '.checkout-button', b = '#privacy_policy',
c = '<?php echo wc_get_checkout_url(); ?>', d = 'disabled';
// Set disable button state
$(a).addClass(d).prop('href', '#');
// Woocommerce Ajax cart events
$('body').on('updated_cart_totals removed_from_cart', function(){
if( ! ( $(a).hasClass(d) && $(b).prop('checked') ) ){
$(a).addClass(d).prop('href', '#');
}
})
// On button click event
$('body').on('click', a, function(e){
if( ! $(b).prop('checked') ) {
// Disable "Proceed to checkout" button
e.preventDefault();
// disabling button state
if( ! $(a).hasClass(d) ){
$(a).addClass(d).prop('href', '#');
}
// Sweet alert 2
swal({
title: '<?php _e("Pricacy Policy", "woocommerce"); ?>',
text: '<?php _e("Please acknowledge the privacy policy Terms and Conditions", "woocommerce"); ?>',
type: 'error',
timer: 3500,
showConfirmButton: false
});
}
});
// On checkbox change event
$(b).change(function(){
if($(this).prop('checked')){
if( $(a).hasClass(d) ){
$(a).removeClass(d).prop('href', c);
}
} else {
if( ! $(a).hasClass(d) ){
$(a).addClass(d).prop('href', '#');
}
}
});
});
</script>
<?php
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Sweet Alert Two documentation
Thanks a lot for this code!
It works for me, except for when the cart is updated via ajax such as when deleting an item.
In that situation, the checkbox no longer enables the Proceed to Checkout button unless I refresh the page. I finally found a solution:
Add the following snippet to the header to reload the cart page after an item is deleted from the cart.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript">
jQuery( document.body ).on( 'updated_cart_totals', function () {
location.reload( true );
} );
</script>
In Woocommerce checkout form im trying to hide billing_city and billing_address_1 fields first and after I fill the fields postcode and housenumber the other fields (address_1 and city) has to show.
This is the script, but I does not work well and I dont know what I do wrong:
?>
<script type="text/javascript">
jQuery('input#billing_housenumber').change(function(){
if (this.checked) {
jQuery('#billing_city').fadeIn();
jQuery('#billing_city input').val('');
} else {
jQuery('#billing_city').fadeOut();
}
});
</script>
<?php
Any help is appreciated.
Update 2
There is some errors, mistakes and missing things in your code. Also you should hooked it in a function (or register it as an external file).
I have added at the end a function that add the billing "housenumber" field in checkout (just for testing purpose)…
In the code below I am using some CSS inline styles to hide the billing city and address_1 fields and to show them when they have an additional selector class "on".
Here is a hooked function that will enable this code in checkout only:
add_action( 'wp_footer', 'custom_checkout_script' );
function custom_checkout_script() {
// Only checkout page
if( ! ( is_checkout() && ! is_wc_endpoint_url() ) ) return;
// CSS Styles (Hidding fields)
?>
<style>
#billing_city_field, #billing_address_1_field { display:none !important;}
#billing_city_field.on ,#billing_address_1_field.on { display:block!important;}
</style>
<?php
// Jquery script
?>
<script type="text/javascript">
jQuery( function($){
var a = 'input#billing_housenumber',
b = 'input#billing_postcode',
c = '#billing_city_field,#billing_address_1_field';
// On start
if( $(a).val() != '' && $(b).val() != '' && ! $(c).hasClass('on') ){
$(c).css('display','none !important').addClass('on').show();
console.log('start');
}
// On change: If housenumber and postcode fields are filled, we display other hidden fields
$(a+','+b).on( 'change', function(){
if ( $(a).val() != '' && $(b).val() != '' && ! $(c).hasClass('on') ) {
$(c).css('display','none !important').addClass('on').show( 500 );
console.log('change - in');
} else if( ( $(a).val() == '' || $(b).val() == '' ) && $(c).hasClass('on') ) {
$(c).hide( 200, function(){
$(c).removeClass('on').css('display','block')
});
console.log('change - out');
}
});
});
</script>
<?php
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
This code has been tested with this temporary additional code, that generates the checkout "housenumber" text field (just for testing purpose):
// Add custom checkout field
add_action( 'woocommerce_billing_fields', 'my_custom_checkout_field' );
function my_custom_checkout_field( $fields ) {
$fields['billing_housenumber'] = array(
'class' => array('form-row-wide'),
'label' => __('Housenumber ?'),
'required' => false,
'clear' => true
);
return $fields;
}
Code goes in function.php file of your active child theme (or active theme).
Related: Show or hide html element on chosen shipping method change in Woocommerce
There is one step left. I don't see the housenumber (after a customer purchase a product). So you don't see the housenumber in the mail or in invoice.
This is in the e-mail but I don't see more detail for address:
/**
* #hooked WC_Emails::customer_details() Shows customer details
* #hooked WC_Emails::email_address() Shows email address
*/
do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email );
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.
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.