I am looking for a drop down of country/state/city. I am getting country state auto populated, but cities are not going through well. By default, I am able to get the countries.
// State-Country additions
/**
* Code goes in functions.php or a custom plugin.
*/
add_filter('woocommerce_states', 'SA_woocommerce_states');
function SA_woocommerce_states($states) {
$states['ZA'] = array(
'EC' => __('Eastern Cape', 'woocommerce'),
);
return $states;
}
// Change "city" checkout billing and shipping fields to a dropdown
add_filter('woocommerce_checkout_fields', 'override_checkout_city_fields');
function override_checkout_city_fields($fields) {
// Define here in the array your desired cities (Here an example of cities)
$option_cities = array(
'' => __('Select your city'),
'a' => 'a',
);
$fields['billing']['billing_city']['type'] = 'select';
$fields['billing']['billing_city']['options'] = $option_cities;
$fields['shipping']['shipping_city']['type'] = 'select';
$fields['shipping']['shipping_city']['options'] = $option_cities;
return $fields;
}
With your actual code you are replacing all existing states of "South Africa" (ZA) by one state. So you are getting something like:
To add this state you should need to change your code a little bit this way:
add_filter('woocommerce_states', 'sa_woocommerce_states');
add_filter('woocommerce_countries_allowed_country_states', 'sa_woocommerce_states');
function SA_woocommerce_states( $states ) {
$states['ZA']['EC'] = __('Eastern Cape', 'woocommerce');
return $states;
}
The code goes in the function.php file of your active child theme (or theme) or also in any plugin file.
Tested and works. You will get that instead this time:
Now to get the cities auto populated you should use this:
add_filter( 'woocommerce_default_address_fields', 'override_checkout_city_fields', 10, 1 );
function override_checkout_city_fields($fields) {
// Define here in the array your desired cities (Here an example of cities)
$option_cities = array(
'' => __( 'Select your city' ),
'a' => 'a',
);
$fields['city']['type'] = 'select';
$fields['city']['options'] = $option_cities;
return $fields;
}
The code goes in the function.php file of your active child theme (or theme) or also in any plugin file.
It was tested ad worked…
But you will not get cities by states as this is a real development and too broad for Stack Overflow
Related
I am building my website. I have a WooCommerce plugin installed and the country I live in it doesn't have postcode or zip. So to calculate the shipping I use districts. I am adding all districts as a dropdown in the cart page in (calculate shipping) area and checkout page. below the code for checkout page
function custom_override_default_postcode_field( $address_fields ) {
// Your postcodes array
$postcode_array = array(
'ALMOHAMMDIAH' => "ALMOHAMMDIAH",
'ALNAEEM' => "ALNAEEM",
'ALZAHRRA' => "ALZAHRRA"
);
$address_fields['postcode']['type'] = 'select';
$address_fields['postcode']['options'] = $postcode_array;
return $address_fields;
}
and adding the district in cart page in (calculate shipping) area code below
'woocommerce_shipping_calculator_enable_postcode', true ) ) : ?>
<p class="form-row form-row-wide" id="calc_shipping_postcode_field">
<?php
// HERE <===== define your array of cities
$postcodes = array('ALMOHAMMDIAH','ALNAEEM','ALZAHRRA');
$current_postcode = esc_attr( WC()->customer->get_shipping_postcode() );
?>
<select name="calc_shipping_postcode" id="calc_shipping_postcode">
<option value=""><?php _e( 'Select a District…', 'woocommerce' ); ?></option>
<?php foreach( $postcodes as $postcode ):
echo '<option value="'.$postcode.'" '.selected( $current_postcode, $postcode ).'>'.$postcode.'</option>';
endforeach; ?>
</select>
</p>
then I change the postcode / ZIP to districts by this core below
function my_text_strings( $translated_text, $text, $domain ) {
switch ( $translated_text ) {
case 'Postcode / ZIP' :
$translated_text = __( 'District', 'woocommerce' );
break;
}
return $translated_text;
}
add_filter( 'gettext', 'my_text_strings', 20, 3 );
All the code above I found them online and changed some text and they are working.
The problem now is that the postcode in WooCommerce backend forces me to use all caps. Some districts must have spaces and I need to do that but I can't figure it out. How can I make the postcode in the backend accept spaces or at least - or _ ?
like ( AL MOHAMMDIAH or AL-MOHAMMDIAH ) instead of (ALMOHAMMDIAH)
btw the codes above I caps all districts so the calculation works. If I added space, _ or - it brock and nothing shows.
There is no easy fix. It would require editing core files and it should never be done if possible. ALL postcode data is sent through the 'cleaning' process, which removes all unwanted data in normal use cases (also made uppercase). There are no filters to stop it.
Now to a solution. There is no simple solution. The best way would be to make a small plugin, which would add field district and remove postcode, but only for your country. Then apply shipping logic to get prices etc. An alternative is to just ignore spaces and live without them, or replace the district names with something else.
What I did to make this work is I changed the state/Country field to be districts and hide the ZIP code. its working fine so far the only downside is the district name comes after the city. I guess its no big deal in the country where I live in
/* district added as state/Country for shipping purposes */
add_filter('woocommerce_states', 'add_custom_states_to_country');
add_filter('woocommerce_countries_allowed_country_states', 'add_custom_states_to_country');
function add_custom_states_to_country( $states ) {
$states['SA'] = array(
'JOR' => __('Abruq-Ar-Rughamah', 'woocommerce'),
'JAL' => __('Al-Adel', 'woocommerce'),
'JAJ' => __('Al-Ajaweed', 'woocommerce'),
'JAD' => __('Al-Ajwad', 'woocommerce'),
'JAW' => __('Al-Amwaj', 'woocommerce'),
'JAS' => __('Al-Andalus', 'woocommerce'),
'JAH' => __('Al-Asalah', 'woocommerce'),
'JZZ' => __('Al-Aziziyah', 'woocommerce'),
'JBH' => __('Al-Baghdadiyah', 'woocommerce'),
);
return $states;
}
and changed the text to districts
add_filter( 'woocommerce_default_address_fields' , 'bbloomer_override_postcode_validation' );
function bbloomer_override_postcode_validation( $address_fields ) {
unset($address_fields['company']); /* remove company */
unset($address_fields['postcode']); /* remove zip */
/*$address_fields['postcode']['required'] = false;*/ /* postcode req */
$address_fields['state']['required'] = true; /* state required */
$address_fields['state']['label'] = __('District'); /* state name to dist */
return $address_fields;
}
I hope this is useful for someone somewhere.
I already have US selected as my default country in the woocommerce checkout. In addition to that, I was asked to move 'US' to the very top of the country list in the checkout form.
I created a new filter and hooked into 'woocommerce_countries' hook like this:
function change_country_order_in_checkout_form($countries)
{
$countries = array('US' => $countries['US']) + $countries;
return $countries;
}
add_filter( 'woocommerce_countries', 'change_country_order_in_checkout_form' );
My list of countries gets modified correctly, but then something in WooCommerce sorts the countries alphabetically and I want to avoid that. I tried adding:
remove_filter('woocommerce_sort_countries', 'wpautop');
but that did not seem to make any difference. Any help is appreciated.
To avoid ordering, you need to use woocommerce_sort_countries filter hook this way:
add_filter('woocommerce_sort_countries', '__return_false');
And to set "US" first, try this instead:
add_filter( 'woocommerce_countries', 'change_country_order_in_checkout_form' );
function change_country_order_in_checkout_form($countries)
{
$usa = $countries['US']; // Store the data for "US" key
unset($countries["US"]); // Remove "US" entry from the array
// Return "US" first in the countries array
return array('US' => $usa ) + $countries;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
So, I was following this example on How to change the city field to a dropdown by Jeroen in my Billing/Shipping section of my site.
/**
* Change the checkout city field to a dropdown field.
*/
function city_to_dropdown( $fields ) {
$city_args = wp_parse_args( array(
'type' => 'select',
'options' => array(
'amsterdam' => 'Amsterdam',
'rotterdam' => 'Rotterdam',
'den-haag' => 'Den Haag',
'utrecht' => 'Utrecht',
'leiden' => 'Leiden',
'groningen' => 'Groningen',
),
), $fields['shipping']['shipping_city'] );
$fields['shipping']['shipping_city'] = $city_args;
$fields['billing']['billing_city'] = $city_args; // Also change for billing field
return $fields;
}
add_filter( 'woocommerce_checkout_fields', 'city_to_dropdown' );
Everything works as expected, but here is what I want to do different.
I want to be able to query all the list of cities from the from shipping rates based on city and display them in the dropdown code above.
So then I wouldn’t have to add the cities manually in multiple places. My list of cities will always be the cities added in using the shipping rates based on city functionality.
What do I need to do to be able to remove the manually entered cities and have something similar to the following :
‘options’ => get_list_cities_from_shipping_rate(),
Question :
What filters or hooks in woocommerce do I have to call to be able to return the list of cities in my function get_list_cities_from_shipping_rate() ?
I'm new to writing these custom codes in wordpress. Any help pointers on how to get this started would be appreciated.
Thank you in advance
Try this:
function get_list_cities_from_shipping_rate( $rate_id ) {
$cities = '';
$key = '_wafs_shipping_method_conditions';
$conditions = get_post_meta( $rate_id, $key, true );
foreach ( (array) $conditions as $group ) {
foreach ( (array) $group as $cond ) {
if ( ! isset( $cond['condition'] ) ) {
continue;
}
if (
'city' === $cond['condition'] &&
'==' === $cond['operator']
) {
$cities .= $cities ? ', ' : '';
$cities .= $cond['value'];
}
}
}
$cities = preg_split( '/, */', $cities );
return array_unique( array_filter( $cities ) );
}
Things to note:
On the WooCommerce → Settings → Advanced Free Shipping page, the $rate_id is the one after the post= as in http://example.com/wp-admin/post.php?post=123&action=edit. Hover on the Free shipping rates table rows and you'd see the Edit URL having that post query.
You must use the city's name and not its slug. E.g. Den Haag instead of den-haag. See the image you provided.
In Woocommerce, I would like to change Town/City text field in a select field option field.
What should i do?
Here is a screenshot:
Thanks
You need first to change the field type from 'text' to 'select' using the dedicated hook woocommerce_default_address_fields. Then you have also to change the label and to and an options argument where you are going to set your towns in an array of key/values.
In this array, you will have a line by town separated by a coma.
Here is the code:
add_filter( 'woocommerce_default_address_fields' , 'customize_checkout_city_field' );
function customize_checkout_city_field( $address_fields ) {
// Set HERE the cities (one line by city)
$towns_cities_arr = array(
'0' => __('Select your city', 'my_theme_slug'),
'paris' => 'Paris',
'versailles' => 'Versailles',
'cannes' => 'Cannes',
);
// Customizing 'billing_city' field
$address_fields['city']['type'] = 'select';
$address_fields['city']['class'] = array('form-row-last', 'my-custom-class'); // your class here
$address_fields['city']['label'] = __('Town / city', 'my_theme_slug');
$address_fields['city']['options'] = $towns_cities_arr;
// Returning Checkout customized fields
return $address_fields;
}
This code goes in function.php file of your active child theme (or theme) or also in any plugin file.
The code is tested and fully functional.
Update: To add your custom class, replace in $address_fields['city']['class']… the class 'my-custom-class' by yours.
References:
Customizing checkout fields using actions and filters - Overriding core fields
You can customize the checkout fields by actions and filters.
Please refer the official documentation here
// Add these code in your theme's function.php
add_filter( 'woocommerce_default_address_fields' , 'custom_override_default_address_fields' );
// Our hooked in function - $address_fields is passed via the filter!
function custom_override_default_address_fields( $fields) {
$fields['billing']['your_field']['options'] = array(
'option_1' => 'Option 1 text',
'option_2' => 'Option 2 text'
);
return $fields;
}
In case you are looking for a plugin you can use checkout field editor from woocommerce team.
I want display the external table value in WooCommerce checkout from company name field. We can create external table and insert some of company name.
When user signup our service in checkout field, customer should select the company name in a custom select options field. This values should be displayed from a custom database table.
How can I achieve this?
Thanks in Advance.
We are going to first unset the field type of company, and then to change it to a type 'select' (selector). Then we will maque a query to get all options key/values from your custom database table (Let's say is called 'wp_companies'):
(ONLY FOR TESTING) NO database query here (with 3 options for companies):
add_filter( 'woocommerce_default_address_fields' , 'set_custom_company_checkout_field' );
function set_custom_company_checkout_field( $address_fields ) {
unset($fields['company']['type']);
$address_fields['company']['type'] = 'select';
$address_fields['company']['options'] = array(
'option_1' => 'Company 1',
'option_2' => 'Company 2',
'option_3' => 'Company 3'
);
// (optional)
// $address_fields['company']['default'] = 'Company 1';
return $address_fields;
}
Paste this code in function.php file located in your active child theme (or theme).
This code is tested and works…
THE REAL CODE: Making the query from database custom table (to be adapted):
add_filter( 'woocommerce_default_address_fields' , 'set_custom_company_checkout_field' );
function set_custom_company_checkout_field( $address_fields ) {
// Unset company field type
unset($fields['company']['type']);
global $wpdb;
$select_options = array();
// ### you will need to replace names table and columns and adapt this !!!
$query = "SELECT id, company FROM table";
$companies_name = $wpdb->get_results($query);
// Storing object $company_name keys/values in $select_options array
foreach ( $companies_name as $company_name )
{
$key = 'option_'. $company_name->ID;
$value = $company_name->custom_column_value;
$select_options[$key] = $value ;
}
$address_fields['company']['type'] = 'select';
$address_fields['company']['options'] = $select_options;
// (optional)
// $address_fields['company']['default'] = $select_options['option_1'];
return $address_fields;
}
Paste this code in function.php file located in your active child theme (or theme).
References:
WooThemes - Customizing checkout fields using actions and filters
WooCommerce - Overriding billing state and post code on existing checkout fields