Ecommerce Shopify WordPress Discussion

Add a select field below Local Pickup Shipping Method in WooCommerce

I am trying to implement a feature in WooCommerce. I have two shipping methods. The default is a Flat rate, and the other one is Local pickup. When the local pickup shipping method is selected, I want to display a select dropdown below it. If the flat rate shipping method is selected again, the select dropdown should be hidden. I have tried the following approach to achieve this functionality, but it hasn't worked: Regardless of whether I choose the local pickup shipping method or not, the select dropdown always displays function add_custom_select_box($method, $index) { if ($method->method_id == 'local_pickup') { echo '<select name="local_pickup_store" id="local_pickup_store" onchange="updateSelectedStore()"> <option value="choose_store">choose store</option> <option value="store1">store1</option> <option value="store2">store2</option> </select>'; echo '<div id="selected_store_info"></div>'; } } add_action('woocommerce_after_shipping_rate', 'add_custom_select_box', 10, 2); function save_local_pickup_store($order) { if (isset($_POST['local_pickup_store'])) { $local_pickup_store = sanitize_text_field($_POST['local_pickup_store']); $order->update_meta_data('_local_pickup_store', $local_pickup_store); } } add_action('woocommerce_checkout_create_order', 'save_local_pickup_store'); function display_local_pickup_store($order) { $local_pickup_store = $order->get_meta('_local_pickup_store'); if ($local_pickup_store) { echo '<p><strong>store:</strong> ' . esc_html($local_pickup_store) . '</p>'; } } add_action('woocommerce_admin_order_data_after_billing_address', 'display_local_pickup_store'); add_action('wp_footer', 'custom_local_pickup_script'); function custom_local_pickup_script() { ?> <script> function updateSelectedStore() { var selectedStore = document.getElementById('local_pickup_store').value; var selectedStoreInfo = document.getElementById('selected_store_info'); if (selectedStore !== 'choose_store') { selectedStoreInfo.innerHTML = '<p><strong>Selected Store:</strong> ' + selectedStore + '</p>'; } else { selectedStoreInfo.innerHTML = ''; } } </script> <?php }
Using dynamic styling will allow you to show hide your select field… I have revised completely your code. It will work only in checkout page. I have added validation to that custom field too. // Displays a select field on Local pickup checkout shipping method add_action('woocommerce_after_shipping_rate', 'display_select_store_field'); function display_select_store_field( $method ) { if (is_checkout() && ! is_wc_endpoint_url() && $method->method_id == 'local_pickup') { echo '<div class="pickup_store"> <select id="local_pickup_store" name="local_pickup_store"> <option value="">'.__('choose store', 'woocommerce').'</option> <option value="'.__('Store 1', 'woocommerce').'">'.__('Store 1 (one)', 'woocommerce').'</option> <option value="'.__('Store 2', 'woocommerce').'">'.__('Store 2 (two)', 'woocommerce').'</option> </select> <div class="selected_store"></div></div>'; } } // Select field validation add_action( 'woocommerce_after_checkout_validation', 'select_store_field_validation', 10, 2 ); function select_store_field_validation( $data, $errors ) { $chosen_shipping_methods = WC()->session->get('chosen_shipping_methods'); $chosen_shipping_method = reset($chosen_shipping_methods); if ( strpos($chosen_shipping_method, 'local_pickup') !== false && isset($_POST['local_pickup_store']) && empty($_POST['local_pickup_store']) ) { $errors->add( 'pickup_store_error', __( 'Please select a Pickup Store.', 'woocommerce' ), 'error' ); } } // Save select field value add_action('woocommerce_checkout_create_order', 'save_select_store_field_value'); function save_select_store_field_value( $order ) { $chosen_shipping_methods = WC()->session->get('chosen_shipping_methods'); $chosen_shipping_method = reset($chosen_shipping_methods); if ( strpos($chosen_shipping_method, 'local_pickup') !== false && isset($_POST['local_pickup_store']) ) { $order->update_meta_data('_local_pickup_store', esc_attr($_POST['local_pickup_store'])); } } // Display select field value in admin orders add_action('woocommerce_admin_order_data_after_billing_address', 'display_local_pickup_store'); function display_local_pickup_store($order) { $local_pickup_store = $order->get_meta('_local_pickup_store'); if ( ! empty($local_pickup_store) ) { echo '<p><strong>Store:</strong> ' . $local_pickup_store . '</p>'; } } // Inline CSS (on checkout page) add_action('wp_head', 'local_pickup_store_inline_css'); function local_pickup_store_inline_css() { if ( is_checkout() && ! is_wc_endpoint_url() ) : ?> <style>body.lp_store_off .pickup_store{display:none;}</style> <?php endif; } // Inline JQuery (on checkout page) add_action('woocommerce_checkout_init', 'local_pickup_store_inline_js'); function local_pickup_store_inline_js() { wc_enqueue_js("const shippingMethodSel = '#shipping_method input[type=radio]'; var chosenSMethodVal = $(shippingMethodSel+':checked').val(); // On start after DOM is loaded if (chosenSMethodVal.indexOf('local_pickup') == -1 && ! $(document.body).hasClass('lp_store_off') ) { $(document.body).addClass('lp_store_off'); } // On Shipping method change $(document.body).on( 'change', shippingMethodSel, function() { chosenSMethodVal = $(this).val(); if (chosenSMethodVal.indexOf('local_pickup') == -1 && ! $(document.body).hasClass('lp_store_off') ) { $(document.body).addClass('lp_store_off'); } else if (chosenSMethodVal.indexOf('local_pickup') != -1 && $(document.body).hasClass('lp_store_off') ) { $(document.body).removeClass('lp_store_off'); } }); // On Pickup Store select change (Displays the selected Store below) $(document.body).on( 'change', '#local_pickup_store', function() { $('div.selected_store').html($(this).val()); });"); } Code goes in functions.php file of your child theme (or in a plugin). Tested and works.

January 7, 2024

TurboCommerce make the better internet purchasing globaly

Turbo Multi-language Translator

Make the better internet purchasing globaly

Turbosify SEO Speed Booster

5.0 (7) Free plan available
Get better conversions by improving store loading speed Installed

Turbo Multi-language Chat - AI Customer service in one hand

TurboCommerce make the better internet purchasing globaly
Our products

The help you need, when you need it

App by Turbo Engine

3 apps • 5.0 average rating

Turbosify Speed Booster

5.0 (7)
Get better conversions by optimizing shopify store Google page speed Installed

Turbosify Translator for Wordpress Woocommerce

5.0 (74) Free Wordpress Woocommerce Plugin
Translate your wordpress website to multiple language within 1 click, no configuration needed, no No technical required

Grow your business here

Whether you want to sell products down the street or around the world, we have all the tools you need.