In Woocommerce I have been able to add 2 custom dropdowns list in checkout page:
add_action('woocommerce_before_order_notes', 'wps_add_select_checkout_field');
function wps_add_select_checkout_field( $checkout) {
echo '<h2>'.__('Next Day Delivery').'</h2>';
woocommerce_form_field( 'City', array(
'type' => 'select',
'class' => array( 'wps-drop' ),
'label' => __( 'Delivery options' ),
'options' => array(
'blank' => __( 'Select a day part', 'wps' ),
'A' => __( 'A', 'wps' ),
'B' => __( 'B', 'wps' ),
'C' => __( 'C', 'wps' )
)
),
$checkout->get_value( 'City' ));
}
add_action('woocommerce_before_order_notes', 'wps_add_select_checkout1_field');
function wps_add_select_checkout1_field( $checkout1) {
//echo '<h2>'.__('Next Day Delivery').'</h2>';
woocommerce_form_field( 'Dis', array(
'type' => 'select',
'class' => array( 'wps-drop' ),
'label' => __( 'Delivery options' ),
'options' => array(
'blank' => __( 'Select a day part', 'wps' ),
'A' => __( 'ro', 'wps' ),
'B' => __( 'wa', 'wps' ),
'C' => __( 'da', 'wps' )
)
),
$checkout1->get_value( 'Dis' ));
}
//* Process the checkout
add_action('woocommerce_checkout_process', 'wps_select_checkout_field_process');
function wps_select_checkout_field_process() {
global $woocommerce;
// Check if set, if its not set add an error.
if ($_POST['City'] == "blank")
wc_add_notice( '<strong>Please select a day part under Delivery options</strong>', 'error' );
}
I would like to generate dynamically the options of the second dropdown list, based on the selected <option> from the first dropdown list.
Example of what I need:
If <option> "A" is selected in the 1st dropdown list, The 2nd dropdown list will show dynamically a specific set of options.
If <option> "C" is selected in the 1st dropdown list, The 2nd dropdown list will show dynamically a different set of options.
And so on …
Is that possible? Where do I have to start?
Any help is appreciated.
I have merged your 2 first functions as they use the same hook.
In this merged function I have added:
The "required" option to both fields.
Changed the slugs for both fields as for example "City" throw a woocommerce error.
different sets of "options" arrays that I pass to javascript (one for each available <option> in the first select field).
Some jQuery code that create dynamically the set of options in the 2nd select field, based on the selected <option> of the first select field.
I have change a bit the condition for the If statement in the last function.
Here is the revisited code:
// Add checkout custom select fields
add_action( 'woocommerce_before_order_notes', 'add_checkout_custom_fields', 20, 1 );
function add_checkout_custom_fields( $checkout) {
$domain = 'woocommerce'; // The domain slug
echo '<h2>'.__( 'Next Day Delivery', $domain ).'</h2>';
// First Select field (Master)
woocommerce_form_field( 'delivery_one', array(
'type' => 'select',
'label' => __( 'Delivery options one' , $domain),
'class' => array( 'form-row-wide' ),
'required' => true,
'options' => array(
'' => __( 'Please select a value', $domain ),
'A' => __( 'A', $domain ),
'B' => __( 'B', $domain ),
'C' => __( 'C', $domain ),
),
),
$checkout->get_value( 'delivery_one' ) );
// Default option value
$default_option2 = __( 'Please select a value', $domain );
// Dynamic select field options for Javascript/jQuery
$options_0 = array( '' => $default_option2 );
$options_a = array(
'' => $default_option2,
'D' => __( 'D', $domain ),
'E' => __( 'E', $domain ),
'F' => __( 'F', $domain ),
'G' => __( 'G', $domain ),
);
$options_b = array(
'' => $default_option2,
'H' => __( 'H', $domain ),
'I' => __( 'I', $domain ),
'J' => __( 'J', $domain ),
);
$options_c = array(
'' => $default_option2,
'K' => __( 'K', $domain ),
'L' => __( 'L', $domain ),
'M' => __( 'M', $domain ),
);
// Second Select field (Dynamic Slave)
woocommerce_form_field( 'delivery_two', array(
'type' => 'select',
'label' => __( 'Delivery options two', $domain ),
'class' => array( 'form-row-wide' ),
'required' => true,
'options' => $options_0,
),
$checkout->get_value( 'delivery_two' ) );
$required = esc_attr__( 'required', 'woocommerce' );
// jQuery code
?>
<script>
jQuery(function($){
var op0 = <?php echo json_encode($options_0); ?>,
opa = <?php echo json_encode($options_a); ?>,
opb = <?php echo json_encode($options_b); ?>,
opc = <?php echo json_encode($options_c); ?>,
select1 = 'select[name="delivery_one"]',
select2 = 'select[name="delivery_two"]';
// Utility function to fill dynamically the select field options
function dynamicSelectOptions( opt ){
var options = '';
$.each( opt, function( key, value ){
options += '<option value="'+key+'">'+value+'</option>';
});
$(select2).html(options);
}
// 1. When dom is loaded we add the select field option for "A" value
// => Disabled (optional) — Uncomment below to enable
// dynamicSelectOptions( opa );
// 2. On live selection event on the first dropdown
$(select1).change(function(){
if( $(this).val() == 'A' )
dynamicSelectOptions( opa );
else if( $(this).val() == 'B' )
dynamicSelectOptions( opb );
else if( $(this).val() == 'C' )
dynamicSelectOptions( opc );
else
dynamicSelectOptions( op0 ); // Reset to default
});
});
</script>
<?php
}
// Check checkout custom fields
add_action( 'woocommerce_checkout_process', 'wps_check_checkout_custom_fields', 20 ) ;
function wps_check_checkout_custom_fields() {
// if custom fields are empty stop checkout process displaying an error notice.
if ( empty($_POST['delivery_one']) || empty($_POST['delivery_two']) ){
$notice = __( 'Please select a day part under Delivery options' );
wc_add_notice( '<strong>' . $notice . '</strong>', 'error' );
}
}
Code goes in function.php file of your active child theme (active theme).
This is a fully working and tested example.
Related
I am trying to add a city dropdown in my Woocommerce store's admin order edit area. I have tried this code.
add_filter( 'woocommerce_admin_billing_fields' , 'admin_billing_city_select_field' );
function admin_billing_city_select_field( $fields ) {
global $pagenow;
// Only for new order creation
if( $pagenow != 'post-new.php' ) return $fields;
$fields['city'] = array(
'label' => __( 'City', 'woocommerce' ),
'show' => false,
'class' => 'js_field-city select short',
'type' => 'select',
'options' => array(
'' => __( 'Select a city…', 'woocommerce' ),
'Los Angeles' => __( 'Los Angeles', 'woocommerce' ),
'San Antonio' => __( 'San Antonio', 'woocommerce' ),
),
);
return $fields;
}
It's working like this
But I want to add some condition If the state matches then it will show a specific city list. And it should revel the city list after selecting the state. How can I do this?
Edit 1
I have added places as an array. And here is the full code in Github.
global $places;
$places['BD'] = array(
'dhaka' => array(
__('Aam Bagan', 'woocommerce'),
__('12 Tala', 'woocommerce'),
__('Keraniganj Upazila Sadar', 'woocommerce'),
),
'faridpur' => array(
__('Alfadanga', 'woocommerce'),
),
'gazipur' => array(
__('Gazipur Sadar', 'woocommerce'),
__('Kaliakair', 'woocommerce'),
),
'gopalganj' => array(
__('Gopalganj Sadar', 'woocommerce'),
__('Kashiani', 'woocommerce'),
),
'jamalpur' => array(
__('Bakshiganj', 'woocommerce'),
__('Dewanganj', 'woocommerce'),
),
);
function enqueue_scripts()
{
wp_enqueue_script('jquery');
wp_enqueue_script('select2', 'https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js', array('jquery'), '4.0.13', true);
wp_enqueue_script('place-select-js', plugin_dir_url(__FILE__) . 'js/place-select.js', array('jquery', 'select2'), '0.1', true);
}
add_action('admin_enqueue_scripts', 'enqueue_scripts');
add_filter('woocommerce_admin_billing_fields', 'admin_billing_city_select_field');
function admin_billing_city_select_field($fields)
{
global $pagenow, $places;
// Only for new order creation
if ($pagenow != 'post-new.php') return $fields;
$options = array('' => __('Select a city…', 'woocommerce'));
if (isset($places)) {
foreach ($places as $state => $cities) {
foreach ($cities as $city => $city_name) {
$options[$city] = $city_name[0];
}
}
}
$fields['city'] = array(
'label' => __('City', 'woocommerce'),
'show' => false,
'class' => 'js_field-city select short',
'type' => 'select',
'options' => $options,
);
return $fields;
}
The imported jquery file is from #Aurelien - AK Digital's answer. But it's returning only the first item of the array.
If I change $options[$city] = $city_name[0]; to $options[$city] = $city_name; it's returning a string text instead of cities "Array" How can I fix it?
First, for a better user experience, I recommend to move the "State field" before the "City" & "Postcode" fields.
You also may have to think about the amount of data you'll want to load. Will you propose every single US city and town or only a few ? This will conditionned the way data will be load.
But let's assume you will create you're own [short] list.
(All of this code has been tested WP 6.1.1 & WC 7.3.0)
First you need to store that list of cities, including state prefixes, in a WordPress option (ex.: '_wc_cities_by_states') like so :
$state_city_options = array(
'CA-los-angeles' => __( 'Los Angeles', 'woocommerce' ),
'CA-san-antonio' => __( 'San Antonio', 'woocommerce' ),
'WA-seattle' => __( 'Seattle', 'woocommerce' ),
'WA-olympia' => __( 'Olympia', 'woocommerce' ),
);
set_option('_wc_cities_by_states', $state_city_options);
Then, get this custom option to build your city select option list :
add_filter( 'woocommerce_admin_billing_fields' , 'admin_billing_city_select_field' );
function admin_billing_city_select_field( $fields ) {
global $pagenow;
// Get the array of cities by state from WP option
$cities_by_states = get_option('_wc_cities_by_states', )
// Only for new order creation
if( $pagenow != 'post-new.php' || !$cities_by_states ) return $fields;
// Add it to WC city fields
$fields['city'] = array(
'label' => __( 'City', 'woocommerce' ),
'show' => false,
'class' => 'js_field-city select short',
'type' => 'select',
'options' => $cities_by_states;
);
return $fields;
}
Finally, this is the Javascript (jQuery) that will do the trick (NB: Woocommerce use the select2 lib) :
jQuery(document).ready(function ($) {
$(".js_field-city option").hide();
//Required to biding after billing-edit click
$(".edit_address").one("click", function () {
filterCities();
});
//Required to avoid unbiding after Country change
$(".js_field-country").on("select2:select", function (evt) {
filterCities();
});
filterCities = () => {
$(".js_field-state").on("select2:select", function (evt) {
var state = $(this).select2("data")[0].id;
$(".js_field-city option").hide();
$(".js_field-city option[value^='" + state + "']").show();
$(".js_field-city").val(null);
});
};
});
That code works for me, I hope it will work for you as well.
Thanks to let me know !
I'm trying to add a custom settings tab to the WooCommerce settings screen. Basically I want to achieve a similar thing to the Products settings tab, with the subsections/subtabs:
I haven't been able to find any decent documentation on how to do this but I've been able to add a custom tab using this snippet:
class WC_Settings_Tab_Demo {
public static function init() {
add_filter( 'woocommerce_settings_tabs_array', __CLASS__ . '::add_settings_tab', 50 );
}
public static function add_settings_tab( $settings_tabs ) {
$settings_tabs['test'] = __( 'Settings Demo Tab', 'woocommerce-settings-tab-demo' );
return $settings_tabs;
}
}
WC_Settings_Tab_Demo::init();
Based on what I've dug up from various threads/tutorials, I've been trying to add the sections/subtabs to the new settings tab something like this:
// creating a new sub tab in API settings
add_filter( 'woocommerce_get_sections_test','add_subtab' );
function add_subtab( $sections ) {
$sections['custom_settings'] = __( 'Custom Settings', 'woocommerce-custom-settings-tab' );
$sections['more_settings'] = __( 'More Settings', 'woocommerce-custom-settings-tab' );
return $sections;
}
// adding settings (HTML Form)
add_filter( 'woocommerce_get_settings_test', 'add_subtab_settings', 10, 2 );
function add_subtab_settings( $settings, $current_section ) {
// $current_section = (isset($_GET['section']) && !empty($_GET['section']))? $_GET['section']:'';
if ( $current_section == 'custom_settings' ) {
$custom_settings = array();
$custom_settings[] = array( 'name' => __( 'Custom Settings', 'text-domain' ),
'type' => 'title',
'desc' => __( 'The following options are used to ...', 'text-domain' ),
'id' => 'custom_settings'
);
$custom_settings[] = array(
'name' => __( 'Field 1', 'text-domain' ),
'id' => 'field_one',
'type' => 'text',
'default' => get_option('field_one'),
);
$custom_settings[] = array( 'type' => 'sectionend', 'id' => 'test-options' );
return $custom_settings;
} else {
// If not, return the standard settings
return $settings;
}
}
I've been able to add new subsections to the Products tab using similar code to the above, but it isn't working for my new custom tab. Where am I going wrong here?
1) To add a setting tab with sections, you can firstly use the woocommerce_settings_tabs_array filter hook:
// Add the tab to the tabs array
function filter_woocommerce_settings_tabs_array( $settings_tabs ) {
$settings_tabs['my-custom-tab'] = __( 'My custom tab', 'woocommerce' );
return $settings_tabs;
}
add_filter( 'woocommerce_settings_tabs_array', 'filter_woocommerce_settings_tabs_array', 99 );
2) To add new sections to the page, you can use the woocommerce_sections_{$current_tab} composite hook where {$current_tab} need to be replaced by the key slug that is set in the first function:
// Add new sections to the page
function action_woocommerce_sections_my_custom_tab() {
global $current_section;
$tab_id = 'my-custom-tab';
// Must contain more than one section to display the links
// Make first element's key empty ('')
$sections = array(
'' => __( 'Overview', 'woocommerce' ),
'my-section-1' => __( 'My section 1', 'woocommerce' ),
'my-section-2' => __( 'My section 2', 'woocommerce' )
);
echo '<ul class="subsubsub">';
$array_keys = array_keys( $sections );
foreach ( $sections as $id => $label ) {
echo '<li>' . $label . ' ' . ( end( $array_keys ) == $id ? '' : '|' ) . ' </li>';
}
echo '</ul><br class="clear" />';
}
add_action( 'woocommerce_sections_my-custom-tab', 'action_woocommerce_sections_my_custom_tab', 10 );
3) For adding the settings, as well as for processing/saving, we will use a custom function, which we will then call:
// Settings function
function get_custom_settings() {
global $current_section;
$settings = array();
if ( $current_section == 'my-section-1' ) {
// My section 1
$settings = array(
// Title
array(
'title' => __( 'Your title 1', 'woocommerce' ),
'type' => 'title',
'id' => 'custom_settings_1'
),
// Text
array(
'title' => __( 'Your title 1.1', 'text-domain' ),
'type' => 'text',
'desc' => __( 'Your description 1.1', 'woocommerce' ),
'desc_tip' => true,
'id' => 'custom_settings_1_text',
'css' => 'min-width:300px;'
),
// Select
array(
'title' => __( 'Your title 1.2', 'woocommerce' ),
'desc' => __( 'Your description 1.2', 'woocommerce' ),
'id' => 'custom_settings_1_select',
'class' => 'wc-enhanced-select',
'css' => 'min-width:300px;',
'default' => 'aa',
'type' => 'select',
'options' => array(
'aa' => __( 'aa', 'woocommerce' ),
'bb' => __( 'bb', 'woocommerce' ),
'cc' => __( 'cc', 'woocommerce' ),
'dd' => __( 'dd', 'woocommerce' ),
),
'desc_tip' => true,
),
// Section end
array(
'type' => 'sectionend',
'id' => 'custom_settings_1'
),
);
} elseif ( $current_section == 'my-section-2' ) {
// My section 2
$settings = array(
// Title
array(
'title' => __( 'Your title 2', 'woocommerce' ),
'type' => 'title',
'id' => 'custom_settings_2'
),
// Text
array(
'title' => __( 'Your title 2.2', 'text-domain' ),
'type' => 'text',
'desc' => __( 'Your description 2.1', 'woocommerce' ),
'desc_tip' => true,
'id' => 'custom_settings_2_text',
'css' => 'min-width:300px;'
),
// Section end
array(
'type' => 'sectionend',
'id' => 'custom_settings_2'
),
);
} else {
// Overview
$settings = array(
// Title
array(
'title' => __( 'Overview', 'woocommerce' ),
'type' => 'title',
'id' => 'custom_settings_overview'
),
// Section end
array(
'type' => 'sectionend',
'id' => 'custom_settings_overview'
),
);
}
return $settings;
}
3.1) Add settings, via the woocommerce_settings_{$current_tab} composite hook:
// Add settings
function action_woocommerce_settings_my_custom_tab() {
// Call settings function
$settings = get_custom_settings();
WC_Admin_Settings::output_fields( $settings );
}
add_action( 'woocommerce_settings_my-custom-tab', 'action_woocommerce_settings_my_custom_tab', 10 );
3.2) Process/save the settings, via the woocommerce_settings_save_{$current_tab} composite hook:
// Process/save the settings
function action_woocommerce_settings_save_my_custom_tab() {
global $current_section;
$tab_id = 'my-custom-tab';
// Call settings function
$settings = get_custom_settings();
WC_Admin_Settings::save_fields( $settings );
if ( $current_section ) {
do_action( 'woocommerce_update_options_' . $tab_id . '_' . $current_section );
}
}
add_action( 'woocommerce_settings_save_my-custom-tab', 'action_woocommerce_settings_save_my_custom_tab', 10 );
Result:
Based on:
Implement a custom WooCommerce settings page, including page sections
woocommerce/includes/admin/settings/
I've added a new field for phone number in WooCommerce checkout form.
Everything is working perfectly except the maxlength = "10". After adding the snippet it shows maxlength = 10 when I inspect element, but the phone field allows me to type n number of characters.
Am I doing anything wrong?
Here is the snippet i used in functions.php
add_action('woocommerce_after_checkout_billing_form', 'custom_checkout_field');
function custom_checkout_field($checkout)
{
woocommerce_form_field('billing_phone_2', array(
'type' => 'number',
'maxlength' => "10",
'id' => 'billing_phone_2',
'class' => array(
'input-text form-row-wide'
) ,
'required' => 'required' === get_option( 'woocommerce_checkout_phone_field', 'required' ),
'label' => __('Phone 2') ,
'placeholder' => __('') ,
) ,
$checkout->get_value('billing_phone_2'));
}
For the type you could use tel, and for the maxlength it is not necessary to put the number between quotes
So you get:
// Display a custom checkout field after billing form
function action_woocommerce_after_checkout_billing_form( $checkout ) {
woocommerce_form_field( 'billing_phone_2', array(
'type' => 'tel',
'maxlength' => 10,
'class' => array( 'form-row-wide' ),
'required' => true,
'label' => __( 'Phone 2', 'woocommerce' ),
'placeholder' => __( 'My placeholder', 'woocommerce' ),
), $checkout->get_value( 'billing_phone_2' ));
}
add_action( 'woocommerce_after_checkout_billing_form', 'action_woocommerce_after_checkout_billing_form', 10, 1 );
Optional: some validation for the custom (required) field
// Custom checkout field validation
function action_woocommerce_checkout_process() {
// Isset
if ( isset( $_POST['billing_phone_2'] ) ) {
$domain = 'woocommerce';
$phone = $_POST['billing_phone_2'];
// Empty
if ( empty ( $phone ) ) {
wc_add_notice( __( 'Please enter a phone number to complete this order', $domain ), 'error' );
}
// Validates a phone number using a regular expression.
if ( 0 < strlen( trim( preg_replace( '/[\s\#0-9_\-\+\/\(\)\.]/', '', $phone ) ) ) ) {
wc_add_notice( __( 'Please enter a valid phone number', $domain ), 'error' );
}
}
}
add_action( 'woocommerce_checkout_process', 'action_woocommerce_checkout_process', 10, 0 );
If type = number, you can use the min and max attributes
// Display a custom checkout field after billing form
function action_woocommerce_after_checkout_billing_form( $checkout ) {
woocommerce_form_field( 'billing_phone_2', array(
'type' => 'number',
'custom_attributes' => array(
'min' => 0,
'max' => 9999999999,
),
'class' => array( 'form-row-wide' ),
'placeholder' => __( 'Phone 2', 'woocommerce' ),
), $checkout->get_value( 'billing_phone_2' ));
}
add_action( 'woocommerce_after_checkout_billing_form', 'action_woocommerce_after_checkout_billing_form', 10, 1 );
Although I wouldn't recommend it for a phone number, there is a reason that the type 'tel' exists, as used in other phonefields in WooCommerce
In WooCommerce, based on "Dynamic synched custom checkout select fields in WooCommerce" answer code, I am adding some custom fields on checkout which will be displayed under the billing section on the e-mail confirmation
Here is my actual code:
add_action( 'woocommerce_after_checkout_billing_form', 'add_checkout_custom_fields', 20, 1 );
function add_checkout_custom_fields( $checkout) {
$domain = 'woocommerce'; // The domain slug
// First Select field (Master)
woocommerce_form_field( 'delivery_one', array(
'type' => 'select',
'label' => __( 'Art der Lieferung' , $domain),
'class' => array( 'form-row-first' ),
'required' => true,
'options' => array(
'' => __( 'Wählen Art der Lieferung.', $domain ),
'A' => __( 'Hauszustellung', $domain ),
'B' => __( 'Selbst Abholung', $domain ),
),
), $checkout->get_value( 'delivery_one' ) );
// Default option value
$default_option2 = __( 'Wählen Sie Zeitbereich.', $domain );
// Dynamic select field options for Javascript/jQuery
$options_0 = array( '' => $default_option2 );
$options_a = array(
'' => $default_option2,
'1' => __( '09:00-11:00', $domain ),
'2' => __( '10:00-12:00', $domain ),
'3' => __( '11:00-13:00', $domain ),
'4' => __( '12:00-14:00', $domain ),
'5' => __( '13:00-15:00', $domain ),
'6' => __( '14:00-16:00', $domain ),
'7' => __( '15:00-17:00', $domain ),
);
$options_b = array(
'' => $default_option2,
'1' => __( '01:00', $domain ),
'2' => __( '02:00', $domain ),
'3' => __( '03:00', $domain ),
'4' => __( '04:00', $domain ),
'5' => __( '05:00', $domain ),
'6' => __( '06:00', $domain ),
'7' => __( '07:00', $domain ),
'8' => __( '08:00', $domain ),
'9' => __( '09:00', $domain ),
'10' => __( '10:00', $domain ),
'11' => __( '11:00', $domain ),
'12' => __( '12:00', $domain ),
'13' => __( '13:00', $domain ),
'14' => __( '14:00', $domain ),
'15' => __( '15:00', $domain ),
'16' => __( '16:00', $domain ),
'17' => __( '17:00', $domain ),
'18' => __( '18:00', $domain ),
'19' => __( '19:00', $domain ),
'20' => __( '20:00', $domain ),
'21' => __( '21:00', $domain ),
'22' => __( '22:00', $domain ),
'23' => __( '23:00', $domain ),
'24' => __( '24:00', $domain ),
);
// Second Select field (Dynamic Slave)
woocommerce_form_field( 'delivery_two', array(
'type' => 'select',
'label' => __( 'Zeitspanne', $domain ),
'class' => array( 'form-row-last' ),
'required' => true,
'options' => $options_0,
), $checkout->get_value( 'delivery_two' ) );
$required = esc_attr__( 'required', 'woocommerce' );
// jQuery code
?>
<script>
jQuery(function($){
var op0 = <?php echo json_encode($options_0); ?>,
opa = <?php echo json_encode($options_a); ?>,
opb = <?php echo json_encode($options_b); ?>,
select1 = 'select[name="delivery_one"]',
select2 = 'select[name="delivery_two"]';
// Utility function to fill dynamically the select field options
function dynamicSelectOptions( opt ){
var options = '';
$.each( opt, function( key, value ){
options += '<option value="'+key+'">'+value+'</option>';
});
$(select2).html(options);
}
// 1. When dom is loaded we add the select field option for "A" value
// => Disabled (optional) — Uncomment below to enable
// dynamicSelectOptions( opa );
// 2. On live selection event on the first dropdown
$(select1).change(function(){
if( $(this).val() == 'A' )
dynamicSelectOptions( opa );
else if( $(this).val() == 'B' )
dynamicSelectOptions( opb );
else
dynamicSelectOptions( op0 ); // Reset to default
});
});
</script>
<?php
}
// Check checkout custom fields
add_action( 'woocommerce_checkout_process', 'wps_check_checkout_custom_fields', 20 ) ;
function wps_check_checkout_custom_fields() {
// if custom fields are empty stop checkout process displaying an error notice.
if ( empty($_POST['delivery_one']) || empty($_POST['delivery_two']) ){
$notice = __( 'Bitte wählen Sie die Versandart oder den Stundenbereich' );
wc_add_notice( '<strong>' . $notice . '</strong>', 'error' );
}
}
My custom fields and their values, are shown on the checkout form and on the order pages on back end. So far everything works great.
But the problem is that the e-mail that I receive does not contain the custom fields and their values.
How can I display that custom checkout billing fields on email notifications?
Is this code correct?
add_filter( 'woocommerce_email_format_string' , 'add_custom_email_format_string', 20, 2 );
function add_custom_email_format_string( $string, $email ) {
// The post meta key used to save the value in the order post meta data
$meta_key = '_delivery_one';
// Get the instance of the WC_Order object
$order = $email->object;
// Get the value
$value = $order->get_meta($meta_key) ? $order->get_meta($meta_key) : '';
// Additional subject placeholder
$new_placeholders = array( '{delivery_one}' => $value );
return str_replace( array_keys( $additional_placeholders ), array_values( $additional_placeholders ), $string );
}
You have to define a new placeholder that can be parsed.
add_filter( 'woocommerce_email_format_string' , 'add_custom_email_format_string', 20, 2 );
function add_custom_email_format_string( $string, $email ) {
// The post meta key used to save the value in the order post meta data
$meta_key = '_billing_field_newfield';
// Get the instance of the WC_Order object
$order = $email->object;
// Get the value
$value = $order->get_meta($meta_key) ? $order->get_meta($meta_key) : '';
// Additional subject placeholder
$new_placeholders = array( '{billing_field_newfield}' => $value );
// Return the clean replacement value string for "{billing_field_newfield}" placeholder
return str_replace( array_keys( $additional_placeholders ), array_values( $additional_placeholders ), $string );
}
Code goes in function.php file of your active child theme (or active theme). It will works.
Then in Woocommerce > Settings > Emails > "New Order" notification, you will be able to use the dynamic placeholder {billing_field_newfield}…
You should first save input value at the database as an order meta see here and then you can get the meta value in email template. All the email template of woocommerce is customizable and located at plugins/woocommerce/emails/
You can use this hook to store custom input field at order meta
do_action( 'woocommerce_checkout_order_processed', $order_id, $posted_data, $order );
Thanks
Hello guys i have a trouble!
i would like to ask you how can i make 1 condition code for each option of the bellow function field_cliente :
function field_cliente( $fields) {
$fields['billing']['billing_cliente'] = array (
'label' => __('Tipo di Cliente', 'woocommerce'),
'id' => '_select',
'type' => 'select',
'options' => array (
'default' => __( 'Seleziona', 'woocommerce' ),
'one' => __( 'Privato', 'woocommerce' ),
'two' => __( 'Azienda', 'woocommerce' ),
'three' => __( 'Impresa Individuale', 'woocommerce' )
)
);
return $fields;
}
For example:
If "One" {
add_filter(' ..');
etc...
}
if "Two" {
add_filter(' ..');
}
I need to know the way of do it because i'm trying to make a show off of filters for each condition choose by the client in the web page checkout