Customized Woocommerce checkout fields reverting to default after page load - php

I have renamed the "shipping_country" label of my woocommerce checkout page successfully using this code:
add_filter( 'woocommerce_checkout_fields', 'rename_woo_checkout_fields' );
function rename_woo_checkout_fields( $fields ) {
$fields['shipping']['shipping_country']['label'] = 'Country';
return $fields;
}
But when I try to add additional labels and placeholders which I want to change, it doesn't work. Well, something strange happens actually. When I refresh the page to apply the changes, it seems to work, but the page is still loading and after a second, reverts back to what it was originally. (the shipping_country field DOES still work, but all of the other fields I add the above happens.
I tried changing the sequence but it does not matter.
The fields I am trying to change which do not work are:
$fields['billing']['billing_address_1']['label'] = 'Address';
$fields['billing']['billing_address_1']['placeholder'] = 'Street and house number';
$fields['billing']['billing_city']['label'] = 'City';
$fields['billing']['billing_postcode']['label'] = 'Postcode';
$fields['shipping']['shipping_postcode']['label'] = 'Postcode';
$fields['shipping']['shipping_city']['label'] = 'City';
$fields['shipping']['shipping_city']['placeholder'] = 'City';
$fields['shipping']['shipping_address_1']['label'] = 'Address';
$fields['shipping']['shipping_address_1']['placeholder'] = 'Street and house number';
$fields['order']['order_comments']['placeholder'] = 'Special notes';
What could it be that is making the page revert the changes before it completes loading the page?

Try the following instead:
// For billing and shipping fields
add_filter( 'woocommerce_default_address_fields', 'custom_default_address_fields' );
function custom_default_address_fields( $address_fields ) {
if ( is_checkout() ) {
$address_fields['address_1']['label'] = __('Address', 'woocommerce');
$address_fields['address_1']['placeholder'] = __('Street and house number', 'woocommerce');
$address_fields['country']['label'] = __('Country', 'woocommerce');
$address_fields['postcode']['label'] = __('Postcode', 'woocommerce');
$address_fields['city']['label'] = __('City', 'woocommerce');
$address_fields['city']['placeholder'] = __('City', 'woocommerce');
}
return $address_fields;
}
add_filter( 'woocommerce_checkout_fields', 'change_checkout_fields' );
function change_checkout_fields( $fields ) {
$fields['order']['order_comments']['placeholder'] = __('Special notes');
return $fields;
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works on last WooCommerce version (5.0.0).

Related

Woocommerce, show/hide added to cart message based on parameters

When adding product to cart user is redirected to cart/payment window and has 'added to cart' notice present. This is the default way I would like to keep, but with addition of my custom method.
My custom button allows customer to stay on shop site while adding another products. However when he enters cart/payment he gets flooded with multiple 'added to cart' messages, which looks just bad:
multiple messages
I want to know if there is option to turn off messages but only if user clicked my custom button.
I've tried attaching get parameter to button and reading it in my code:
add_filter( 'wc_add_to_cart_message_html', 'filter_wc_add_to_cart_message_html', 10, 2 );
function filter_wc_add_to_cart_message_html( $message, $products ) {
$showMSG = get_query_var('show-cmsg');
if ( $showMSG ){
return $message;
}
return null;
}
But the get_query_var always results in null, no matter the get parameters. I've registered it:
function add_custom_query_vars( $vars ){
$vars[] = "show-cmsg";
return $vars;
}
Is there a way to hide the messages depending on which button user pressed?
Or if you can block woocommerce from genereting messages if you pressed custom button?
Or just a way to even limit the messages to 1 most recent instead of showing all at once?
I would also do same for some other error mesasges, but If i would find answer to this then I quess i would manage errors.
You should use session because add_custom_query_vars just add key not value that's why you getting always null.
So for the session first check session_start() or not, then set the value in the session after that you can get anywhere accordingly.
Example:
function woo_register_session() {
if(!session_id() || session_status() == PHP_SESSION_NONE){
session_start();
}
$_SESSION['show_cmsg'] = true;
}
add_action( 'init', 'woo_register_session' );
Then get the session and use it in your function accordingly
add_filter( 'wc_add_to_cart_message_html', 'filter_wc_add_to_cart_message_html', 10, 2 );
function filter_wc_add_to_cart_message_html( $message, $products ) {
$showMSG = $_SESSION['show_cmsg'] ? true : false;
if ( $showMSG ){
return $message;
}
return null;
}
Another alternate function for message
add_filter( 'wc_add_to_cart_message', 'woo_add_to_cart_message' );
function woo_add_to_cart_message() {
$showMSG = $_SESSION['show_cmsg'] ? true : false;
if($showMSG){
if (get_option('woocommerce_cart_redirect_after_add')=='yes') :
$return_to = get_permalink(woocommerce_get_page_id('shop'));
$message = sprintf('%s %s', $return_to, __('Continue Shopping →', 'woocommerce'), __('Product successfully added to your cart.', 'woocommerce') );
else :
$message = sprintf('%s %s', get_permalink(woocommerce_get_page_id('cart')), __('View Cart →', 'woocommerce'), __('Product successfully added to your cart.', 'woocommerce') );
endif;
}else{
$message = null;
}
return $message;
}
I managed to find solution:
function filter_wc_add_to_cart_message_html( $message, $products ) {
$urlp = explode('/', $_SERVER['REQUEST_URI']);
$urlp = $urlp[1];
if ( $urlp == 'potwierdzenie'){
return $message;
}
return null;
}
I just check if user in checkout url when buying product, then I'm showing the notice. If user is still on shop page or any other page, notice won't show. This prevents the multiple 'added to cart' messages in checkout.

Set a default value for shipping city and state in Woocommerce My account

In woocommerce already the shipping country in restricted to IN
On checkout the default value of Country, state & city is set
I want to do that same in my-account/edit-address/ only in shipping address
tried using this code but its not working
add_filter( 'woocommerce_shipping_fields' , 'default_shipping_address' );
function default_shipping_address( $fields ) {
$fields['shipping_city']['default'] = 'Mumbai';
$fields['shipping_state']['default'] = 'Maharashtra';
return $fields;
}
this is not working let me know what's wrong or is there any other way to do this?
You are pretty near… As Shipping State value in WooCommerce is a state code, you need to replace 'Maharashtra' with 'MH' (For India) as follows:
add_filter( 'woocommerce_shipping_fields' , 'set_default_my_account_shipping_city_state_values' );
function set_default_my_account_shipping_city_state_values( $fields ) {
// Targeting My account section
if( is_account_page() ) {
$fields['shipping_city']['default'] = 'Mumbai';
$fields['shipping_state']['default'] = 'MH'; // <== HERE
}
return $fields;
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
Alternative: If it really doesn't work for you, you can try to use the following:
add_action( 'template_redirect' , 'set_default_shipping_city_and_state_values' );
function set_default_shipping_city_and_state_values( $fields ) {
if( is_wc_endpoint_url( 'edit-address' ) ) {
if ( WC()->customer->get_shipping_city() === '' ) {
WC()->customer->Set_shipping_city('Mumbai');
}
if ( WC()->customer->get_shipping_state() === '' ) {
WC()->customer->Set_shipping_state('MH');
}
}
}
You can use the address hook.
add_filter( 'woocommerce_default_address_fields' , 'default_shipping_address' );
function default_shipping_address( $fields ) {
$fields['shipping_city']['value'] = 'Mumbai';
$fields['shipping_state']['value'] = 'Maharashtra';
return $fields;
}

Customize some checkout fields properties in Woocommerce 3+

I have updated the placeholders for basket fields via the WooCommerce settings, as follows:
However on the frontend, the previous placeholders remain:
I have also used the following code, adapted from another StackOverflow thread which aims to override the placeholder content, but the defaults still persist.
add_filter('woocommerce_default_address_fields', 'override_default_address_checkout_fields', 20, 1);
function override_default_address_checkout_fields( $address_fields ) {
$address_fields['state']['placeholder'] = 'State';
$address_fields['postcode']['placeholder'] = 'Postcode';
return $address_fields;
}
Please advise on how I can achieve the desired placeholder text!
In woocommerce default there is no settings like you describe. So you are using a third party plugin, to customize fields. So you need to try multiple ways with a higher hook priority.
So try those one by one:
1). Using woocommerce_default_address_fields filter hook (with a higher priority hook):
add_filter('woocommerce_default_address_fields', 'customize_default_address_fields', 10000, 1 );
function customize_default_address_fields( $address_fields ) {
$address_fields['state']['placeholder'] = __('State', 'woocommerce');
$address_fields['postcode']['placeholder'] = __('Postcode', 'woocommerce');
return $address_fields;
}
2). Using woocommerce_checkout_fields filter hook:
add_filter('woocommerce_checkout_fields', 'customize_checkout_fields', 10000, 1 );
function customize_checkout_fields( $fields ) {
$fields['billing']['billing_state']['placeholder'] = __('State', 'woocommerce');
$fields['shipping']['shipping_state']['placeholder'] = __('State', 'woocommerce');
$fields['billing']['billing_postcode']['placeholder'] = __('Postcode', 'woocommerce');
$fields['shipping']['shipping_postcode']['placeholder'] = __('Postcode', 'woocommerce');
return $fields;
}
3). Using woocommerce_billing_fields and woocommerce_shipping_fields filters hooks:
add_filter('woocommerce_billing_fields', 'customize_billing_fields', 10000, 1 );
function customize_billing_fields( $billing_fields ) {
$billing_fields['billing_state']['placeholder'] = __('State', 'woocommerce');
$billing_fields['billing_postcode']['placeholder'] = __('Postcode', 'woocommerce');
return $billing_fields;
}
add_filter('woocommerce_shipping_fields', 'customize_shipping_fields', 10000, 1 );
function customize_shipping_fields( $shipping_fields ) {
$shipping_fields['shipping_state']['placeholder'] = __('State', 'woocommerce');
$shipping_fields['shipping_postcode']['placeholder'] = __('Postcode', 'woocommerce');
return $shipping_fields;
}
All code goes in function.php file of your active child theme (or active theme).
I hope that one of those will work. Without a third party plugin each of those codes works perfectly.

Add a custom column to My Account Orders table in Woocommerce 3+

Woocommerce 3.5.x has a special page at the user account (My Account) area where it displays the user's previous Orders.
This page is now 5 column displays as default.
Here the screenshot of the woocommerce Orders area with 5 column:
My Orders
I Can't find the way to change this.
How can I add a new column in the default?
This requires 2 functions that will add a new column
The second function hook is a composite hook: woocommerce_my_account_my_orders_column_{$column_id} where {$column_id} need to be replaced by the column key slug that is set in the first function.
That second function manage the displayed row values and you can add for example a custom field to get custom order meta data values.
The code:
add_filter( 'woocommerce_account_orders_columns', 'add_account_orders_column', 10, 1 );
function add_account_orders_column( $columns ){
$columns['custom-column'] = __( 'New Column', 'woocommerce' );
return $columns;
}
add_action( 'woocommerce_my_account_my_orders_column_custom-column', 'add_account_orders_column_rows' );
function add_account_orders_column_rows( $order ) {
// Example with a custom field
if ( $value = $order->get_meta( '_custom_field' ) ) {
echo esc_html( $value );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
You are done and have added a custom column to My account orders table:
If you which to make changes in the table html output, you will have to override the template file: myaccount/orders.php
If you don't wanna change the order template under myaccount page. Here's what you have to do.
First:
function wc_add_myaccount_order_column( $columns ) {
$columns[ 'custom-column' ] = __( 'Custom Column', 'woocommerce' );
}
add_filter( 'woocommerce_my_account_my_orders_columns', 'wc_add_myaccount_order_column' );
Second:
function wc_custom_column_display( $order ) {
// do something here
echo "testing";
}
add_action( 'woocommerce_my_account_my_orders_column_custom-column', 'wc_custom_column_display' );
The code above will display "testing" in each order under "Custom Column" column.
Note: If you actually wanna change the entire template, like the design for example. You can follow the first answer above.
Just to improve the accepted answer I add a line to choose the position of the column (after total):
function sv_wc_add_my_account_orders_column( $columns ) {
$new_columns = array();
foreach ( $columns as $key => $name ) {
$new_columns[ $key ] = $name;
// add ship-to after order status column
if ( 'order-total' === $key ) { //this is the line!
$new_columns['custom-column'] = __( 'Custom Column', 'woocommerce' );
}
}
return $new_columns;
}
add_filter( 'woocommerce_my_account_my_orders_columns', 'sv_wc_add_my_account_orders_column' );
function wc_custom_column_display( $order ) {
// do something here
echo "testing";
}
add_action( 'woocommerce_my_account_my_orders_column_custom-column', 'wc_custom_column_display' );
With WooCommerce 5.9, I couldn't get LiocTheAztect's answer to work. What worked for me was:
add_filter( 'woocommerce_account_orders_columns',
'add_customer_email_column');
function add_customer_email_column( $columns ){
$new_columns = [
"order-number" => $columns["order-number"],
// ...
"customer-email" => __( 'Customer Email', '' ),
// ...
"order-actions" => $columns["order-actions"]
];
return $new_columns;
}
add_action( 'woocommerce_my_account_my_orders_column_customer-email',
'add_customer_email_content' );
function add_customer_email_content($order) {
echo esc_html($order->get_billing_email());
}
Without the if ($value = $order->get_meta( '_custom_field' )) block. Hope it helps.

Make Woocommerce checkout state field required

So this problem may have a easy solution, but I'm stuck for the moment. After the last update (Woocommerce 3.3.5) I have a problem with the state field on the checkout page, because it is not mandatory and people just skip it. I really need this thing to be mandatory, because I have connected my website to the delivery company server through and API to send the order info directly to them.
I tried adding this to my functions.php and the thing is that when I go to the checkout page, the field has an asterisk, but for like one second.
add_filter( 'woocommerce_billing_fields', 'woo_filter_state_billing',
10, 1 );
add_filter( 'woocommerce_shipping_fields',
'woo_filter_state_shipping', 10, 1 );
function woo_filter_state_billing( $address_fields ) {
$address_fields['billing_state']['required'] = true;
return $address_fields;
}
function woo_filter_state_shipping( $address_fields ) {
$address_fields['shipping_state']['required'] = true;
return $address_fields;
}
Any help is appreciated. Thanks!
By default in Last woocommerce version 3.3.5, state field is required… So in your case something is making that field "not" required.
You can try this (work for billing and shipping fields at the same time):
add_filter( 'woocommerce_default_address_fields' , 'make_state_field_required', 90, 1 );
function make_state_field_required( $address_fields ) {
$address_fields['state']['required'] = true;
return $address_fields;
}
Code goes in function.php file of your active child theme (or active theme). It could works.
This worked better for me as of January 2019
add_filter( 'woocommerce_billing_fields', 'woo_filter_state_billing', 10, 1 );
add_filter( 'woocommerce_shipping_fields', 'woo_filter_state_shipping', 10, 1 );
function woo_filter_state_billing( $address_fields ) {
$address_fields['billing_state']['required'] = true;
return $address_fields;
}
function woo_filter_state_shipping( $address_fields ) {
$address_fields['shipping_state']['required'] = true;
return $address_fields;
}
Maybe you mean "country"? I had that problem, being that field inexplicably optional.
In that case, the code would be:
add_filter( 'woocommerce_billing_fields' , 'make_country_field_required', 90, 1 );
function make_country_field_required( $address_fields ) {
$address_fields['billing_country']['required'] = true;
return $address_fields;
}

Categories