Почему не срабатывает js после обновления страницы оформления заказа woocommerce?
В wordpress на страницу оформления добавил 2 поля:
1. Селект
2. Инпут
Когда в селекте выбирают "Написать в telegram", к инпуту добавляется display:block и его можно заполнить.
Проблема: Если перезагрузить страницу, то display:block не добавится.
html:
<p id="billing_contactmethod_field" > <label for="billing_contactmethod" class="true-label">Предпочитаемый метод связи</label> <span class="woocommerce-input-wrapper"> <select name="billing_contactmethod" id="billing_contactmethod" class="select " data-placeholder=""> <option value="Позвонить по номеру телефона">Позвонить по номеру телефона</option> <option value="telegram" selected="selected">Написать в Telegram</option> </select> </span> </p> <p class="form-row true-field form-row-wide tg-billing" id="billing_telegram_field"> <label for="billing_telegram" class="true-label"> Ваш Telegram </label> <input type="text" class="input-text " name="billing_telegram" id="billing_telegram" placeholder="Ссылка или название вашего Telegram" value="https://t.me/Ne4aev019"> </p> |
<p id="billing_contactmethod_field" > <label for="billing_contactmethod" class="true-label">Предпочитаемый метод связи</label> <span class="woocommerce-input-wrapper"> <select name="billing_contactmethod" id="billing_contactmethod" class="select " data-placeholder=""> <option value="Позвонить по номеру телефона">Позвонить по номеру телефона</option> <option value="telegram" selected="selected">Написать в Telegram</option> </select> </span> </p> <p class="form-row true-field form-row-wide tg-billing" id="billing_telegram_field"> <label for="billing_telegram" class="true-label"> Ваш Telegram </label> <input type="text" class="input-text " name="billing_telegram" id="billing_telegram" placeholder="Ссылка или название вашего Telegram" value="https://t.me/Ne4aev019"> </p>
Js:
jQuery(document).ready(function($) { $('#billing_contactmethod').on( 'change', function(){ var selectval= $(this).val(); if( selectval== 'telegram' ) { // Если в селекте выбран "telegram" то показываем поле $('.tg-billing').show(); } else { $('.tg-billing').hide(); } }); }); |
jQuery(document).ready(function($) { $('#billing_contactmethod').on( 'change', function(){ var selectval= $(this).val(); if( selectval== 'telegram' ) { // Если в селекте выбран "telegram" то показываем поле $('.tg-billing').show(); } else { $('.tg-billing').hide(); } }); });
Дополнительно
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
В вашем коде поле показывается только после события change. При перезагрузке страницы событие change не происходит, хотя в select уже может быть выбран вариант telegram. Поэтому функция показа должна запускаться сразу при загрузке страницы. Вторая особенность WooCommerce checkout - блоки оформления заказа могут перерисовываться через AJAX после изменения доставки, страны, купона или способа оплаты. Если элемент заменен в DOM, прямой обработчик на старом select может потеряться.
Сделайте отдельную функцию, которая смотрит текущее значение select и приводит поле Telegram к правильному состоянию. Эту функцию нужно вызвать при загрузке, при изменении select и после события updated_checkout.
jQuery(function ($) { function toggleTelegramField() { var isTelegram = $('#billing_contactmethod').val() === 'telegram'; $('.tg-billing').toggle(isTelegram); if (! isTelegram) { $('#billing_telegram').val(''); } } $(document.body).on('change', '#billing_contactmethod', toggleTelegramField); $(document.body).on('updated_checkout', toggleTelegramField); toggleTelegramField(); });jQuery(function ($) { function toggleTelegramField() { var isTelegram = $('#billing_contactmethod').val() === 'telegram'; $('.tg-billing').toggle(isTelegram); if (! isTelegram) { $('#billing_telegram').val(''); } } $(document.body).on('change', '#billing_contactmethod', toggleTelegramField); $(document.body).on('updated_checkout', toggleTelegramField); toggleTelegramField(); });
Ключевая строка здесь - последний вызов toggleTelegramField. Именно он исправляет ситуацию после перезагрузки: скрипт не ждет ручного изменения select, а сразу проверяет, что уже выбрано в поле. Делегированный обработчик через document.body нужен для надежности на checkout, потому что WooCommerce может заменить часть разметки, а событие change все равно будет поймано.
Скрипт нужно подключать на странице оформления заказа после jQuery и checkout-скриптов WooCommerce. В теме или дочерней теме это можно сделать так:
add_action('wp_enqueue_scripts', function () { if (! function_exists('is_checkout') || ! is_checkout()) { return; } wp_enqueue_script( 'checkout-contact-method', get_stylesheet_directory_uri() . '/js/checkout-contact-method.js', ['jquery', 'wc-checkout'], '1.0.0', true ); });
Итог: проблема не в selected как таковом, а в том, что код реагировал только на изменение поля. На checkout WooCommerce всегда пишите логику как функцию состояния: прочитали текущее значение, показали или скрыли зависимое поле, повторили после AJAX-обновления.