I need to override all states in WooCommerce checkout but I need to do this only for shipping section.
So "billing_state" is working fine with all current Italian states and I need to override only "shipping_state" with new states.
With code below will override both billing_states and also shipping states. How can I modify code in order to override "shipping_states"
Thanks in advance
add_filter( 'woocommerce_states', 'custom_woocommerce_states' );
function custom_woocommerce_states( $states ) {
$states['IT'] = array(
//I have to display only these 3 states in shipping Checkout
'TV' => 'Treviso',
'CA' => 'Carità',
'CS' => 'Castrette',
);
return $states;
}
This is what you are looking for. Add this to your active child themes functions.php
Refer to this WebToffee article
add_action( 'wp_footer', 'webtoffee_checkout_shipping_filter_it_states' );
function webtoffee_checkout_shipping_filter_it_states() {
if ( ! is_checkout() ) {
return;
}
?>
<script>
jQuery(document).ready(function($) {
$(document.body).on('country_to_state_changed', function() {
var $shipping_country = $('#shipping_country');
var new_shipping_state = '';
switch($shipping_country.val()) {
case 'IT':
new_shipping_state = {'TV': "Treviso", "CA": "Carità", "Cs": "Castrette"};
break;
}
if( ! $.isEmptyObject(new_shipping_state)) {
var optionsAsString = "";
for (var key in new_shipping_state) {
optionsAsString += "<option value='" + key + "'>" + new_shipping_state[key] + "</option>";
}
$( 'select[name="shipping_state"]' ).html( optionsAsString );
}
});
});
</script>
<?php
}
Related
The requirement:
Depending on the chosen payment option, certain checkout fields should not be required.
My scenario:
It clients select "local pickup" they get the option to select PayPal, credit card etc. and "pay at pickup".
If they pay at pickup, we don't need they payment address. The invoice will be handled at pickup and the checkout is actually a reservation.
I have found a solution myself and share this question as a reference.
Find the solution in an answer.
This is my solution:
add_action( 'woocommerce_checkout_process', 'gw_deactivate_some_fields_on_condition');
function gw_deactivate_some_fields_on_condition() {
add_filter( 'woocommerce_checkout_fields' , 'gw_some_billing_fields_not_required_for_cash_on_delivery_payment_method' );
}
function gw_some_billing_fields_not_required_for_cash_on_delivery_payment_method( $fields ) {
$chosen_payment_method = WC()->session->get('chosen_payment_method');
if ( 0 === strpos( $chosen_payment_method, 'cash_on_delivery' ) ) {
$fields['billing']['billing_address_1']['required'] = false;
$fields['billing']['billing_address_2']['required'] = false;
$fields['billing']['billing_city']['required'] = false;
$fields['billing']['billing_postcode']['required'] = false;
$fields['billing']['billing_country']['required'] = false;
$fields['billing']['billing_state']['required'] = false;
}
return $fields;
}
add_action( 'woocommerce_after_checkout_form', 'gw_disable_payment_fields_if_local_payment' );
function gw_disable_payment_fields_if_local_payment( $available_gateways ) {
?>
<script type="text/javascript">
jQuery( document ).ready(function() {
show_hide_payment_options();
});
jQuery('form.checkout').on('change','input[name^="payment_method"]',function() {
show_hide_payment_options();
});
jQuery('form.checkout').on('change','input[name^="shipping_method"]',function() {
show_hide_payment_options();
});
function show_hide_payment_options() {
var val = jQuery('input[name^="payment_method"]:checked').val(); // If it changed, then it must be the radio options so check the one that's selected
var fields_selector = '#billing_country_field, #billing_address_1_field, #billing_address_2_field, #billing_city_field, #billing_postcode_field';
if (val.match("^cash_on_delivery")) {
jQuery( fields_selector ).fadeOut();
} else {
jQuery( fields_selector ).fadeIn();
}
}
</script>
<?php
}
For handling the shipping fields see this post:
https://www.businessbloomer.com/woocommerce-hide-shipping-local-pickup-selected/
This was also a strong inspiration for my code.
I am trying the following code by LoicTheAztec - Add to cart and redirect to checkout for variable products in WooCommerce
Now, the problem is whenever I am clicking on the Buy Now button with the default variations set in the Product editor, the code is not working.
The Buy Now URL in this case becomes …/?addtocart=0&quantity=n
The Theme I am using - Basel
Any solutions?
Tried the code by LoicTheAztec.
function add_custom_addtocart_and_checkout() {
global $product;
$addtocart_url = wc_get_checkout_url().'?add-to-cart='.$product->get_id();
$button_class = 'single_add_to_cart_button button alt custom-checkout-btn';
$button_text = __("Buy & Checkout", "woocommerce");
if( $product->is_type( 'simple' )) :
?>
<script>
jQuery(function($) {
var url = '<?php echo $addtocart_url; ?>',
qty = 'input.qty',
button = 'a.custom-checkout-btn';
// On input/change quantity event
$(qty).on('input change', function() {
$(button).attr('href', url + '&quantity=' + $(this).val() );
});
});
</script>
<?php
elseif( $product->is_type( 'variable' ) ) :
$addtocart_url = wc_get_checkout_url().'?add-to-cart=';
?>
<script>
jQuery(function($) {
var url = '<?php echo $addtocart_url; ?>',
vid = 'input[name="variation_id"]',
pid = 'input[name="product_id"]',
qty = 'input.qty',
button = 'a.custom-checkout-btn';
// Once DOM is loaded
setTimeout( function(){
if( $(vid).val() != '' ){
$(button).attr('href', url + $(vid).val() + '&quantity=' + $(qty).val() );
}
}, 300 );
// On input/change quantity event
$(qty).on('input change', function() {
if( $(vid).val() != '' ){
$(button).attr('href', url + $(vid).val() + '&quantity=' + $(this).val() );
}
});
// On select attribute field change event
$('.variations_form').on('change blur', 'table.variations select', function() {
if( $(vid).val() != '' ){
$(button).attr('href', url + $(vid).val() + '&quantity=' + $(qty).val() );
}
});
});
</script>
<?php
endif;
echo ''.$button_text.'';
} ```
I expect this code to work when the user does not change or update any variations on the product page. That is when the user clicks on the Buy Now button with the default variations.
you don’t need all that you should add the button in the variation form it will work as submiting the form as the add to cart button then make the redirect
this is tested and working with me
add_action( 'woocommerce_single_variation', 'second_button_single_variation', 30 );
function second_button_single_variation() {
global $product;
echo '<form method="post">
<button type="submit" name="checkout_now" id="checkout_now" class="single_add_to_cart_button button alt buy_now_button" value="'.$product->get_id().'">Buy Now</button></form>';
}
function woo_redirect_to_checkout() {
global $woocommerce;
if( isset($_POST['checkout_now']) ){
wc_clear_notices();
$checkout_url = $woocommerce->cart->get_checkout_url();
wp_redirect($checkout_url);
}
}
add_filter ('add_to_cart_redirect', 'woo_redirect_to_checkout');
// clearing the cart if you want to go to checkout with the desired product only
add_filter( 'woocommerce_add_to_cart_validation', 'remove_cart_item_before_add_to_cart', 20, 3 );
function remove_cart_item_before_add_to_cart( $passed, $product_id, $quantity ) {
if( isset($_POST['checkout_now']) ){
if( ! WC()->cart->is_empty() )
WC()->cart->empty_cart();
}
return $passed;
}
I got help in this answer thread that allow to add an additional add-to-cart button that redirects to checkout. It works fine for simple products.
But how to make it work for variable products as well?
I've been trying myself, but no matter what I do, I break the site. I simply do not understand how to make this work with/ for variable products.
Here's the lightly changed code that works for simple products and which takes the quantity field into consideration:
add_action( 'woocommerce_after_add_to_cart_button', 'add_custom_addtocart_and_checkout' );
function add_custom_addtocart_and_checkout() {
global $product;
$addtocart_url = wc_get_checkout_url().'?add-to-cart='.$product->get_id();
$button_class = 'single_add_to_cart_button button alt custom-checkout-btn';
$button_text = __("Buy & Checkout", "woocommerce");
if( $product->is_type( 'simple' )) :
?>
<script>
jQuery(function($) {
var url = '<?php echo $addtocart_url; ?>',
qty = 'input.qty',
button = 'a.custom-checkout-btn';
// On input/change quantity event
$(qty).on('input change', function() {
$(button).attr('href', url + '&quantity=' + $(this).val() );
});
});
</script>
<?php
echo ''.$button_text.'';
endif;
}
Does anyone know how to get this working for variable products too?
Update 3
The following code will handle simple and variable products adding an additional Add to cart button that redirects to cart (with synchronized quantity).
The code works for simple and variable products as well.
add_action( 'woocommerce_after_add_to_cart_button', 'add_custom_addtocart_and_checkout' );
function add_custom_addtocart_and_checkout() {
global $product;
$addtocart_url = wc_get_checkout_url().'?add-to-cart='.$product->get_id();
$button_class = 'single_add_to_cart_button button alt custom-checkout-btn';
$button_text = __("Buy & Checkout", "woocommerce");
if( $product->is_type( 'simple' )) :
?>
<script>
jQuery(function($) {
var url = '<?php echo $addtocart_url; ?>',
qty = 'input.qty',
button = 'a.custom-checkout-btn';
// On input/change quantity event
$(qty).on('input change', function() {
$(button).attr('href', url + '&quantity=' + $(this).val() );
});
});
</script>
<?php
elseif( $product->is_type( 'variable' ) ) :
$addtocart_url = wc_get_checkout_url().'?add-to-cart=';
?>
<script>
jQuery(function($) {
var url = '<?php echo $addtocart_url; ?>',
vid = 'input[name="variation_id"]',
pid = 'input[name="product_id"]',
qty = 'input.qty',
button = 'a.custom-checkout-btn';
// Once DOM is loaded
setTimeout( function(){
if( $(vid).val() != '' ){
$(button).attr('href', url + $(vid).val() + '&quantity=' + $(qty).val() );
}
}, 300 );
// On input/change quantity event
$(qty).on('input change', function() {
if( $(vid).val() != '' ){
$(button).attr('href', url + $(vid).val() + '&quantity=' + $(this).val() );
}
});
// On select attribute field change event
$('.variations_form').on('change blur', 'table.variations select', function() {
if( $(vid).val() != '' ){
$(button).attr('href', url + $(vid).val() + '&quantity=' + $(qty).val() );
}
});
});
</script>
<?php
endif;
echo ''.$button_text.'';
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
In Woocommerce, I wrote the code for billing_state to use the shipping charge. Now I want to write the value from billing_state to billing_city, when changing billing_state, billing_city also changes
This are my custom states code:
add_filter( 'woocommerce_states', 'vietnam_cities_woocommerce' );
function vietnam_cities_woocommerce( $states ) {
$states['VN'] = array(
'HCM' => __('Hồ Chí Minh', 'woocommerce') ,
'HANOI' => __('Hà Nội', 'woocommerce') ,
'HAIPHONG' => __('Hải Phòng', 'woocommerce') ,
);
return $states;
}
Any help is appreciated.
The following code will fill up the city from the state value when the country is Vietnam (VN) in the checkout page:
// Add checkout custom select fields
add_action( 'wp_footer', 'custom_checkout_city_field', 20, 1 );
function custom_checkout_city_field() {
// Only checkout page
if( is_checkout() && ! is_wc_endpoint_url() ):
$country = 'VN'; // <=== <=== The country code
// $states = WC()->countries->get_shipping_country_states()[$country];
?>
<script type="text/javascript">
jQuery(function($){
var c = '<?php echo $country; ?>', f = 'form.checkout';
// On billing state change
$(f).on('change', '#billing_state', function(){
if($('#billing_country').val() == c ){
$('#billing_city').val($(this).val());
}
});
// On shipping state change
$(f).on('change', '#shipping_state', function(){
if($('#shipping_country').val() == c ){
$('#shipping_city').val($(this).val());
}
});
});
</script>
<?php
endif;
}
Code goes in function.php file of your active child theme (active theme). Tested and works.
I've added DatePicker to my checkout page for customers to pick the delivery date. Also added a script to disable past dates (obviously) and delivery on some holidays.
Here is the script:
<script>
var disableddates = ["14-02-2018", "25-12-2018"];
function DisableSpecificDates(date) {
var string = jQuery.datepicker.formatDate("dd-mm-yy", date);
return [disableddates.indexOf(string) == -1];
}
jQuery(function() {
jQuery("#billing_delivery_date").datepicker({
dateFormat: "DD, d MM, yy",
beforeShowDay: DisableSpecificDates,
minDate: new Date()
});
});
</script>
And it works perfectly until I try to put some restrictions on it. I need just disable holiday delivery for some categories, not for all. I did it like that:
function add_checkout_script() {
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
// if a product is not in our cat, bail out since we know the cat is not alone
if ( has_term( my_category, 'product_cat', $cart_item['data']->id ) ) {
wp_enqueue_script( 'newscript', get_stylesheet_directory_uri() . '/restrict_day_script.js', array( 'jquery' ));
}
}
}
add_action( 'woocommerce_after_checkout_form', 'add_checkout_script' );
Also tried just paste the script:
function add_checkout_script() {
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
// if a product is not in our cat, bail out since we know the cat is not alone
if ( has_term( my_category, 'product_cat', $cart_item['data']->id ) ) {
?>
<script>
var disableddates = ["14-02-2018", "25-12-2018"];
function DisableSpecificDates(date) {
var string = jQuery.datepicker.formatDate("dd-mm-yy", date);
return [disableddates.indexOf(string) == -1];
}
jQuery(function() {
jQuery("#billing_delivery_date").datepicker({
dateFormat: "DD, d MM, yy",
beforeShowDay: DisableSpecificDates,
minDate: new Date()
});
});
</script>
<?php
}
}
}
add_action( 'woocommerce_after_checkout_form', 'add_checkout_script' );
What am I doing wrong?
I have made some changes to your code, where you will need to define your specific targeted product categories:
add_action( 'woocommerce_after_checkout_form', 'add_checkout_script' );
function add_checkout_script() {
// HERE define your product categories in the array (Ids, slugs or names)
$categories = array( 't-shirts', 'sweet-shirts' );
$product_id = $cart_item['product_id'];
$found = false;
// Loop through cart items to find out specific product categories
foreach( WC()->cart->get_cart() as $cart_item )
if( has_term( $categories, 'product_cat', $product_id ) ) {
$found = true;
break;
}
// If product categories are not found in cart items, we exit
if ( ! $found ) return
?>
<script>
jQuery(function($) {
var disableddates = ["14-02-2018", "25-12-2018"];
function DisableSpecificDates(date) {
var string = $.datepicker.formatDate("dd-mm-yy", date);
return [disableddates.indexOf(string) == -1];
}
$("#billing_delivery_date").datepicker({
dateFormat: "DD, d MM, yy",
beforeShowDay: DisableSpecificDates,
minDate: new Date()
});
});
</script>
<?php
}
Code goes in functions.php file of your active child theme (or active theme).
It should work now.