Reputation: 570
I am creating a WooCommerce plugin and I want to display dynamically Sub Areas according to chosen customer city in checkout page.
Here is my code attempt:
add_filter( 'woocommerce_checkout_fields', 'dvs_city_list' );
function dvs_city_list( $fields ) {
$fields["billing"]["billing_city"]["type"] = 'select';
$fields["billing"]["billing_city"]["input_class"] = array(
'state_select' => 'state_select'
);
$fields["billing"]["billing_city"]["options"] = array(
'Lahore' => 'Lahore',
'Karachi' => 'Karachi'
),
return $fields;
}
add_filter( 'woocommerce_checkout_fields', 'dvs_area_list' );
function dvs_area_list( $fields ) {
$fields['billing']['billing_area']['label'] = 'Area';
$fields['billing']['billing_area']['required'] = 'True';
$fields["billing"]["billing_area"]["type"] = 'select';
$fields["billing"]["billing_area"]["class"][0] = 'form-row-last';
$fields['billing']['billing_area']['priority'] = 50;
$fields["billing"]["billing_area"]["input_class"] = array(
'state_select' => 'state_select'
);
$city = $_REQUEST['billing_city'];
if ($city == 'Lahore') {
$fields["billing"]["billing_area"]["options"] = array(
'Naval Town' => 'Naval Town',
'Bahria Town' => 'Bahria Town',
'Faisal Town' => 'Faisal Town'
);
}
else ($city == 'Karachi') {
$fields["billing"]["billing_area"]["options"] = array(
'Walton Road' => 'Walton Road',
'Zest Road' => 'Zest Road'
);
}
return $fields;
}
But I am getting this error
Notice:
Undefined index: billing_city in …wp-content/plugins/custom-plugin/index.php on line 35
How to fixed this error? What I am doing wrong?
Upvotes: 1
Views: 1844
Reputation: 253886
To synch a custom checkout select field from another select field, it requires to use jQuery.
Also you can merge both functions as they use the same hook.
Below in the first function, we keep your cities / areas settings that we can call everywhere. The last function enable dynamic options changes on the "Billing areas" dropdown depending on the chosen city:
function cities_areas_settings() {
$text_domain = 'woocommerce';
return array(
__('Lahore', $text_domain) => array(
__('Naval Town', $text_domain),
__('Bahria Town', $text_domain),
__('Faisal Town', $text_domain),
),
__('Karachi', $text_domain) => array(
__('Walton Road', $text_domain),
__('Zest Road', $text_domain),
)
);
}
add_filter( 'woocommerce_checkout_fields', 'custom_checkout_fields' );
function custom_checkout_fields( $fields ) {
// Initializing
$text_domain = 'woocommerce';
$option_cities = array();
$lahore_areas = array( '' => __('Choose your area', $text_domain) );
// Load settings and prepare options arrays
foreach( cities_areas_settings() as $city => $areas ) {
$option_cities[$city] = $city;
if( $city === 'Lahore' ) {
foreach( $areas as $area ) {
$lahore_areas[$area] = $area;
}
}
}
// 1. Billing City field
$fields['billing']['billing_city']['type'] = 'select';
$fields['billing']['billing_city']['class'] = array('form-row-first');
$fields['billing']['billing_city']['input_class'] = array('state_select');
$fields['billing']['billing_city']['options'] = $option_cities;
// 2. Billing Area Field
$fields['billing']['billing_area'] = array(
'type' => 'select',
'label' => __('Area', $text_domain),
'class' => array('form-row-last'),
'input_class' => array('state_select'),
'options' => $lahore_areas,
'required' => true,
'default' => '',
'priority' => 50,
);
return $fields;
}
add_action('wp_footer', 'custom_checkout_js_script');
function custom_checkout_js_script() {
if( is_checkout() && ! is_wc_endpoint_url() ) :
// Initializing
$text_domain = 'woocommerce';
$karachi_areas = array( '' => __('Choose your area', $text_domain) );
$settings = cities_areas_settings(); // Load settings
// Prepare 'Karachi' options dropdown
foreach( cities_areas_settings()['Karachi'] as $area ) {
$karachi_areas[$area] = $area;
}
?>
<script language="javascript">
jQuery( function($){
var a = 'select[name="billing_city"]',
b = 'select[name="billing_area"]',
o = <?php echo json_encode($karachi_areas); ?>,
s = $(b).html();
// 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>';
});
$(b).html(options);
}
// On Start (once DOM is loaded)
if ( $(a).val() === 'Karachi' ) {
dynamicSelectOptions( o );
}
console.log($(a).val());
// On billing city change live event
$('form.woocommerce-checkout').on('change', a, function() {
console.log($(this).val());
if ( $(this).val() === 'Karachi' ) {
dynamicSelectOptions( o );
} else {
$(b).html(s);
}
});
});
</script>
<?php
endif;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
Related: Dynamic synched custom checkout select fields in WooCommerce
Upvotes: 2