Keep state field as a dropdown when one allowed country on Woocommerce - php

I thought this would be easy but I'm not getting the results I want. Basically I have 2 countries in woocommerce CA and US. I'm trying to remove one conditionally, and I can do that with the following code below. However, when I go from 2 countries to 1, the dropdown menu still appears. An odd thing I'm noticing with the below code as well, is that if I go into my Woocommerce settings, then the country that is removed with this code is also removed from the "Sell to specific countries" options.... not sure what's going on. Thanks in advance.
add_filter( 'woocommerce_countries', 'custom_woocommerce_countries_limit');
function custom_woocommerce_countries_limit( $countries ) {
/*
will place a conditional here if x then remove country
*/
unset($countries['CA']);
$countries = array(
'US' => __( 'United States', 'woocommerce' )
);
return $countries;
}
EDIT: Using this hook may be close to the answer, but when I use this one, The states don't turn into a dropdown...?
add_filter( 'woocommerce_countries_allowed_countries', 'custom_woocommerce_countries_limit');

You can use woocommerce_countries_allowed_countries filter hook, but you should need some additional code to force the state fields to be a state dropdown (select field):
add_filter( 'woocommerce_countries_allowed_countries', 'filter_allowed_countries_conditionally');
function filter_allowed_countries_conditionally( $countries ) {
// will place a conditional here if x then remove country
if( true ) {
$countries = array( 'US' => __( 'United States', 'woocommerce' ) );
} else {
$countries = array( 'CA' => __( 'Canada', 'woocommerce' ) );
}
return $countries;
}
// Force billing state field type to be a dropdown
add_filter( 'woocommerce_billing_fields', 'filter_billing_state_fields', 100, 1 );
function filter_billing_state_fields( $fields ) {
$fields['billing_state']['type'] = 'state';
return $fields;
}
// Force shipping state field type to be a dropdown
add_filter( 'woocommerce_shipping_fields', 'filter_shipping_state_fields', 100, 1 );
function filter_shipping_state_fields( $fields ) {
$fields['shipping_state']['type'] = 'state';
return $fields;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.

Related

Changing Postcode field in Woocmmerce's checkout page to drop-down

I am having post code based minimum order amount for orders for my Woocommerce shop.
Also I am having postcode based custom error messages to appear once the user type postcode like how much he needs more to checkout.
So preventing the user to type invalid postcodes(which means the postcodes that we do not deliver), i am displaying drop down to pick his valid postcode in Checkout page.
Based on this thread Change postcode shipping field to a dropdown in Woocommerce, i could turn the postcode field to dropdown with the options.
But i am getting the error that the "Postcode is not valid" by Woocommerce when i select any option from the drop down. Also my custom messages also not displaying.
Below is the code I m using from the above thread.
add_filter( 'woocommerce_default_address_fields' , 'customize_postcode_fields' );
function customize_postcode_fields( $adresses_fields ) {
$adresses_fields['postcode']['type'] = 'select';
$adresses_fields['postcode']['options'] = array(
'' => __('Select your postcode', 'woocommerce'),
'option_1' => '000001',
'option_2' => '000002',
'option_3' => '000003'
);
return $adresses_fields;
}
Try to use the following instead:
add_filter( 'woocommerce_default_address_fields' , 'customize_postcode_fields' );
function customize_postcode_fields( $adresses_fields ) {
$adresses_fields['postcode']['type'] = 'select';
$adresses_fields['postcode']['input_class'] = array('state_select');
$adresses_fields['postcode']['options'] = array(
'' => __('Select your postcode', 'woocommerce'),
'000001' => '000001',
'000002' => '000002',
'000003' => '000003'
);
return $adresses_fields;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works on last WooCommerce version 4.5.1 under Storefront theme.

Display custom checkout address field 2 label in Woocommerce

I found a way to change the placeholder but not the label of the checkout input fields in woocommerce.
I would like to change the label for the adress_field_2.
Here is my attempt that did not change anything. I tried [label] and [label_class] but that did not work...
add_filter( 'woocommerce_default_address_fields', 'new_checkout_field_label', 10, 1 );
function new_checkout_field_label( $address_fields ) {
$address_fields['address_2']['placeholder'] = __( '', 'woocommerce' );
$address_fields['address_2']['label'] = __( 'Apt, Unit, Etc (optional)', 'woocommerce' );
return $address_fields;
}
Your code works and the correct related html is there. But it's hidden from the tag class screen-reader-text by a CSS rule.
To make the <label> visible, you need to remove the class from the <label> tag adding this line:
$address_fields['address_2']['label_class'] = array(); // No label class
So in your code:
add_filter( 'woocommerce_default_address_fields', 'custom_override_default_checkout_fields', 10, 1 );
function custom_override_default_checkout_fields( $address_fields ) {
$address_fields['address_2']['placeholder'] = __( '', 'woocommerce' );
$address_fields['address_2']['label'] = __( 'Apt, Unit, Etc (optional)', 'woocommerce' );
$address_fields['address_2']['label_class'] = array(); // No label class
return $address_fields;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.

Add value to custom column on customer's orders page in woocommerce

I was trying to add new column to the orders page of the customer's recent orders table, the new column should show the details of the product like product name & description.
Tried different solution, was fortunate to add column name but not able to add the value to the column.
Here is my code:
add_filter( 'woocommerce_account_orders_columns', 'new_orders_columns' );
function new_orders_columns( $columns = array() ) {
// Hide the columns
if( isset($columns['order-total']) ) {
unset( $columns['order-status'] );
unset( $columns['order-total'] );
unset( $columns['order-actions'] );
}
// Add new columns
//this is my custom column order details
$columns['order-detail'] = __( 'Details', 'woocommerce' );
$columns['order-status'] = __( 'Status', 'woocommerce' );
$columns['order-total'] = __( 'Total', 'woocommerce' );
$columns['order-actions'] = __( ' ');
return $columns;
}
Screenshot of the result:
You are very near…
1) Insert a new column in a specific location (another way):
add_filter( 'woocommerce_account_orders_columns', 'add_custom_account_orders_column', 10, 1 );
function add_custom_account_orders_column( $columns ) {
$ordered_columns = array();
// Inserting a new column in a specific location
$ordered_columns['order-number'] = $columns['order-number'];
$ordered_columns['order-date'] = $columns['order-date'];
$ordered_columns['order-details'] = __( 'Details', 'woocommerce' ); // <== New column
$ordered_columns['order-status'] = $columns['order-status'];
$ordered_columns['order-total'] = $columns['order-total'];
$ordered_columns['order-actions'] = $columns['order-actions'];
return $ordered_columns;
}
Code goes in function.php file of your active child theme (or active theme).
tested and works.
2) Display data in this new column (editing myaccount/orders.php template):
You will need to override through your active child theme, the myaccount/orders.php WooCommerce template.
At line 56 (just after 'order-number' code) you will insert the following and you will be able to add some specific content:
<?php elseif ( 'order-details' === $column_id ) : ?>
<?php
// HERE GOES YOUR CUSTOM CODE (DISPLAYED CONTENT)
?>
You can use the available WC_Order object $order…
How to get WooCommerce order details
Accepted answer is only partially correct. Adding the column via filter is fine, but populating the column is better done via a action hook. This is clean and matches best with column being added via filter. While editing the orders.php page via child theme works, it will lead to future effort to maintain after updates to woocommerce change this page making child theme version out of date.
To add your content to the column create an action hook along side the filter in functions.php. (or better yet in a plugin!)
add_action( 'woocommerce_my_account_my_orders_column_order-detail' , 'your_function_name2',10,1 );
//'woocommerce_my_account_my_orders_column_<column_id>'
function your_function_name2( $order ) {
// do stuff, ex: get_post_meta( $post->ID, 'key', true );
}
add_filter( 'woocommerce_account_orders_columns', 'new_orders_columns',10,1 );
function new_orders_columns( $columns) {
// Add new column. Kept simple to play nice with other filters.
$columns['order-detail'] = __( 'Details', 'woocommerce' );
return $columns;
}
see this similar question, best answer by Misha
Try to use this code
<?php
// ------------------
// 1. Register new endpoint to use for My Account page
// Note: Resave Permalinks or it will give 404 error
function bbloomer_add_premium_support_endpoint() {
add_rewrite_endpoint( 'premium-support', EP_ROOT | EP_PAGES );
}
add_action( 'init', 'bbloomer_add_premium_support_endpoint' );
// ------------------
// 2. Add new query var
function bbloomer_premium_support_query_vars( $vars ) {
$vars[] = 'premium-support';
return $vars;
}
add_filter( 'query_vars', 'bbloomer_premium_support_query_vars', 0 );
// ------------------
// 3. Insert the new endpoint into the My Account menu
function bbloomer_add_premium_support_link_my_account( $items ) {
$items['premium-support'] = 'Premium Support';
return $items;
}
add_filter( 'woocommerce_account_menu_items', 'bbloomer_add_premium_support_link_my_account' );
// ------------------
// 4. Add content to the new endpoint
function bbloomer_premium_support_content() {
echo '<h3>Premium WooCommerce Support</h3><p>Welcome to the WooCommerce support area. As a premium customer, you can submit a ticket should you have any WooCommerce issues with your website, snippets or customization. <i>Please contact your theme/plugin developer for theme/plugin-related support.</i></p>';
echo do_shortcode( ' /* your shortcode here */ ' );
}
add_action( 'woocommerce_account_premium-support_endpoint', 'bbloomer_premium_support_content' );

WooCommerce: Pre-select and restrict to one state and city on checkout

I'm setting up a store that only sells to one city. I'm trying to figure out how I can restrict the city option to a pre-filled field.
I've already limited the country and using the following code in my functions.php:
add_filter( 'default_checkout_country', 'change_default_checkout_country' );
add_filter( 'default_checkout_state', 'change_default_checkout_state' );
function change_default_checkout_country() {
return 'PK'; // country code
}
function change_default_checkout_state() {
return 'SD'; // state code
}
And I've pre-selected the state using the following:
add_filter( 'woocommerce_states', 'bbloomer_custom_woocommerce_states' );
function bbloomer_custom_woocommerce_states( $states ) {
$states['PK'] = array(
'SD' => 'Sindh',
);
return $states;
}
But... Now comes the city and I am lost. I've tried using $fields['billing']['billing_city'] as well as $fields['billing']['billing_city']['value'] to no avail.
I want the customer to be limited to Karachi. I am not very familiar with WooCommerce filters, so I need help on achieving this.
Since woocommerce 3, default_checkout_country and default_checkout_state filter hooks are now deprecated and replaced.
Also in your last function, if you want to restrict just to one city, you should not include your city in the array of states. Instead you should return only one possible value.
So this will be your code:
// default checkout country
add_filter( 'default_checkout_billing_country', 'change_default_checkout_country' );
add_filter( 'default_checkout_shipping_country', 'change_default_checkout_country' );
function change_default_checkout_country() {
return 'PK'; // country code
}
// default checkout state
add_filter( 'default_checkout_billing_state', 'change_default_checkout_state' );
add_filter( 'default_checkout_shipping_state', 'change_default_checkout_state' );
function change_default_checkout_state() {
return 'SD'; // state code
}
// Setting one state only
add_filter( 'woocommerce_states', 'custom_woocommerce_state', 10, 1 );
function custom_woocommerce_state( $states ) {
// Returning a unique state
return array('PK' => array('SD' => 'Sindh'));
}
// Only one city at checkout
add_filter( 'woocommerce_checkout_fields', 'custom_checkout_fields', 10, 1 );
function custom_checkout_fields( $fields ) {
$fields['billing']['billing_city']['type'] = 'select';
$fields['billing']['billing_city']['options'] = array('Karachi' => 'Karachi');
$fields['shipping']['shipping_city']['type'] = 'select';
$fields['shipping']['shipping_city']['options'] = array('Karachi' => 'Karachi');
return $fields;
}
The Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works for wooCommerce versions 3+
Once added the code above and saved, you will need in WooCommerce > Settings > General to set locations this way:
Then you will get something like this on checkout:
Both dropdown have only one value… So you get what you are expecting.

Force WooCommerce to sell and ship to ONLY one state

How do I force WooCommerce to sell and ship to only one state?
I can select a country but I can't find any way to allow selling and shipping only to one state/region.
Let's say I've selected only Canada and I want to sell only in Ontario. How can I achieve that? I probably have to add something to function.php to filter the states, but I don't know where to look for it...
Thanks!
I've found this solution, but probably it's not the "cleanest" way to achieve this.
Any suggestion?
add_filter( 'default_checkout_country', 'change_default_checkout_country' );
add_filter( 'default_checkout_state', 'change_default_checkout_state' );
function change_default_checkout_country() {
return 'CA'; // country code
}
function change_default_checkout_state() {
return 'ON'; // state code
}
add_filter( 'woocommerce_states', 'custom_woocommerce_states' );
function custom_woocommerce_states( $states ) {
$states['CA'] = array(
'ON' => 'Ontario',
);
return $states;
}

Categories