Как лучше скрывать поля доставки при выборе метода Самовывоз?

Ссылка скопирована
1 ответ

Сейчас ситуация такая: у нас поля типа Адрес доставки, время доставки обязательны, нужно сделать так, чтобы при выборе Самовывоз эти поля скрывались и становились не обязательными соответственно. Ниже пример реализации, но у меня не работает, помогите с решением

Наши поля:

billing_state - город billing_wooccm18 - адрес billing_wooccm20 - дата billing_wooccm21 - Время доставки billing_wooccm19 - Время доставки

Сейчас ситуация такая: получается у нас Самовывоз поле в Санкт-Петербург и Лен обл (shipping_method_0_local_pickup-106 и shipping_method_0_local_pickup-107) и при его выборе весь 2 шаг исчезает, раньше работало, не понимаю в чем дело сейчас, они скрываются, но требуют заполнения

Код

function awoohc_add_update_form_billing( $fragments ) { $checkout = WC()->checkout(); parse_str( $_POST['post_data'], $fields_values ); ob_start(); echo '<div class="woocommerce-billing-fields__field-wrapper">'; $fields = $checkout->get_checkout_fields( 'billing' ); foreach ( $fields as $key => $field ) { $value = $checkout->get_value( $key ); if ( isset( $field['country_field'], $fields[ $field['country_field'] ] ) ) { $field['country'] = $checkout->get_value( $field['country_field'] ); } if ( ! $value && ! empty( $fields_values[ $key ] ) ) { $value = $fields_values[ $key ]; } woocommerce_form_field( $key, $field, $value ); } echo '</div>'; $fragments['.woocommerce-billing-fields__field-wrapper'] = ob_get_clean(); return $fragments; } add_filter( 'woocommerce_update_order_review_fragments', 'awoohc_add_update_form_billing', 99 ); /** * Скрываем поля для бесплатного способа доставки * * @param $fields * * @return mixed * * @sourcecode https://wpruse.ru/woocommerce/hiding-fields-on-chosen-delivery/ * @author Artem Abramovich * @testedwith WC 5.5 */ function awoohc_override_checkout_fields( $fields ) { // получаем выбранные методы доставки. $chosen_methods = WC()->session->get( 'chosen_shipping_methods' ); // проверяем текущий метод и убираем не ненужные поля. if ( false !== strpos( $chosen_methods[0], 'free_shipping' ) ) { unset( $fields['billing']['billing_company'], $fields['billing']['billing_address_1'], $fields['billing']['billing_address_2'], $fields['billing']['billing_city'], $fields['billing']['billing_postcode'], $fields['billing']['billing_state'], $fields['billing']['billing_phone'], $fields['billing']['billing_email'] ); } return $fields; } add_filter( 'woocommerce_checkout_fields', 'awoohc_override_checkout_fields' ); /** * Прелоад при переключении доставки * * @sourcecode https://wpruse.ru/woocommerce/hiding-fields-on-chosen-delivery/ * @author Artem Abramovich * @testedwith WC 5.5 */ function awoohc_add_script_update_shipping_method() { if ( is_checkout() ) { ?> <!--Скроем поле Страна. Если успользуется поле Страна, то следцет убрать скрытие--> <style> #billing_country_field { display: none !important; } </style> <!--Выполняем обновление полей при переключении доставки--> <script> jQuery( document ).ready( function( $ ) { $( document.body ).on( 'updated_checkout updated_shipping_method', function( event, xhr, data ) { $( 'input[name^="shipping_method"]' ).on( 'change', function() { $( '.woocommerce-billing-fields__field-wrapper' ).block( { message: null, overlayCSS: { background: '#fff', 'z-index': 1000000, opacity: 0.3 } } ); } ); } ); } ); </script> <?php } } add_action( 'wp_footer', 'awoohc_add_script_update_shipping_method' );
Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Виктор Sys Ответ

Поля доставки нужно не просто скрыть CSS-ом, а ещё отключить их обязательность на сервере. Иначе пользователь выберет “Самовывоз”, поля исчезнут, но WooCommerce всё равно может ругаться, что адрес или время не заполнены.

На фронте можно скрывать поля при выборе метода доставки:

jQuery(function ($) {
  function togglePickupFields() {
    const method = $('input[name^="shipping_method"]:checked').val() || '';
    const isPickup = method.indexOf('local_pickup') !== -1;
 
    $('#shipping_address_1_field, #shipping_city_field, #shipping_postcode_field, #delivery_time_field')
      .toggle(!isPickup);
  }
 
  $(document.body).on('updated_checkout change', 'input[name^="shipping_method"]', togglePickupFields);
  togglePickupFields();
});

jQuery(function ($) { function togglePickupFields() { const method = $('input[name^="shipping_method"]:checked').val() || ''; const isPickup = method.indexOf('local_pickup') !== -1; $('#shipping_address_1_field, #shipping_city_field, #shipping_postcode_field, #delivery_time_field') .toggle(!isPickup); } $(document.body).on('updated_checkout change', 'input[name^="shipping_method"]', togglePickupFields); togglePickupFields(); });

Но этого мало. Нужно ещё убрать required на сервере через фильтр checkout_fields:

add_filter('woocommerce_checkout_fields', function ($fields) {
    $chosen = WC()-&gt;session ? WC()-&gt;session-&gt;get('chosen_shipping_methods') : [];
    $method = is_array($chosen) &amp;&amp; isset($chosen[0]) ? $chosen[0] : '';
    $is_pickup = strpos($method, 'local_pickup') !== false;
 
    if ($is_pickup) {
        foreach (['address_1', 'city', 'postcode'] as $key) {
            if (isset($fields['shipping']['shipping_' . $key])) {
                $fields['shipping']['shipping_' . $key]['required'] = false;
            }
        }
 
        if (isset($fields['billing']['delivery_time'])) {
            $fields['billing']['delivery_time']['required'] = false;
        }
    }
 
    return $fields;
});

add_filter('woocommerce_checkout_fields', function ($fields) { $chosen = WC()-&gt;session ? WC()-&gt;session-&gt;get('chosen_shipping_methods') : []; $method = is_array($chosen) &amp;&amp; isset($chosen[0]) ? $chosen[0] : ''; $is_pickup = strpos($method, 'local_pickup') !== false; if ($is_pickup) { foreach (['address_1', 'city', 'postcode'] as $key) { if (isset($fields['shipping']['shipping_' . $key])) { $fields['shipping']['shipping_' . $key]['required'] = false; } } if (isset($fields['billing']['delivery_time'])) { $fields['billing']['delivery_time']['required'] = false; } } return $fields; });

Если метод самовывоза у вас не стандартный local_pickup, посмотрите реальный ID в HTML или в настройках доставки. Он может выглядеть как local_pickup:3 или как ID стороннего плагина. Именно его нужно проверять.

Лучший результат: поля скрываются визуально, при смене доставки checkout обновляется, а серверная валидация не требует скрытые поля. Тогда заказ можно оформить без адреса доставки только для самовывоза, а для обычной доставки обязательность остаётся.

После правки обязательно проверьте два сценария: заказ с доставкой и заказ с самовывозом. Для доставки поля должны снова появляться и быть обязательными. Для самовывоза скрытые поля лучше ещё очищать JS-ом, чтобы в заказ случайно не попал старый адрес, который пользователь вводил до переключения метода.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно