Дано: Интернет-магазин на WordPress+WooCommerce
Задача: На странице оформления заказа в поле для ввода номера телефона задать предустановленную схему номера в формате пригодному для русскоязычного сегмента
+7 xxx-xxx-xx-xx (или вариант через 8-ку)
Решение: Выполнять поставленную задачу мы будем на JavaScript, в первом случае — на базе библиотеки jQuery, которая поставляется с WordPress и доступна «из коробки» и во-втором — решение на нативном JS (то есть без зависимостей от сторонних библиотек, в частности jQuery)
Мне встретилось в интернете уже готовое решение, поэтому придерживаясь принципа: «Зачем писать то, что уже написано», я взял его за пример. Единственное, нужно проинспектировать нашу форму отправления заказа и выяснить идентификатор нашего «инпута» для указания номера телефона.
Давайте взглянем на форму при оформлении заказа в WooCommerce.
Если требуется добавить в поле подсказку какой формат ввода номера телефона мы ожидаем от пользователя, то поможет нам в этом специальный фильтр, который отвечает за возможность изменения информации в полях. В документации есть подходящий для решения нашей под-задачи пример
// Hook in
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
// Our hooked in function - $fields is passed via the filter!
function custom_override_checkout_fields( $fields ) {
$fields['order']['order_comments']['placeholder'] = 'My new placeholder';
$fields['order']['order_comments']['label'] = 'My new label';
return $fields;
}
В примерах из документации можно найти все названия полей. В нашем случае идентификатор нашего поля billing_phone (смотреть рисунок выше, с исследованием элемента) и он относится к группе Billing (эта информация получена тут). Поэтому наш код будет выглядеть следующим образом:
// Hook in
add_filter( 'woocommerce_checkout_fields', 'poet_override_checkout_fields' );
function poet_override_checkout_fields( $fields ) {
$fields['billing']['billing_phone']['placeholder'] = '+7 (123) 456-78-90';
$fields['billing']['billing_phone']['maxlength'] = 10; // ожидаем ввода 10 основных символов номера телефона
return $fields;
}
Выполнение данного кода привнесло в поле нашей формы подсказку-заполнитель
Естественно, мы не можем ручаться что именно так будет осуществлён ввод данных пользователем. Поэтому напишем вторую функцию, которая будет задавать правильное форматирование при вводе благодаря шаблону, который мы реализуем.
В WooCommerce для этого есть удобная функция wc_enqueue_js(), которая добавляет пользовательский код в вывод в нижней части сайта перед закрывающим тегом </body>. Вывод справедлив если страница каким то образом относится к WooCommerce. То есть на одиночной странице записи этого вывода не будет.
Найти функцию можно от корня вашего сайта в wp-contents/plugins/woocommerce/includes/wc-core-functions.php
Она позволяет добавлять в глобальную переменную (global $wc_queued_js) произвольный код. А её вызов можно увидеть чуть ниже по коду:
Обратите внимание, что обёртка для jQuery уже присутствует и можно просто пользоваться её методами. И вот изящное решение, от Rodolfo Melogli можно увидеть ниже.
/**
* @snippet Phone Mask @ WooCommerce Checkout
* @how-to Get CustomizeWoo.com FREE
* @author Rodolfo Melogli
* @compatible WooCommerce 5
* @community https://businessbloomer.com/club/
*/
add_filter( 'woocommerce_checkout_fields', 'bbloomer_checkout_phone_us_format' );
function bbloomer_checkout_phone_us_format( $fields ) {
$fields['billing']['billing_phone']['placeholder'] = '123-456-7890';
$fields['billing']['billing_phone']['maxlength'] = 12; // 123-456-7890 is 12 chars long
return $fields;
}
add_action( 'woocommerce_after_checkout_form', 'bbloomer_phone_mask_us' );
function bbloomer_phone_mask_us() {
wc_enqueue_js( "
$('#billing_phone')
.keydown(function(e) {
var key = e.which || e.charCode || e.keyCode || 0;
var phone = $(this);
if (key !== 8 && key !== 9) {
if (phone.val().length === 3) {
phone.val(phone.val() + '-'); // add dash after char #3
}
if (phone.val().length === 7) {
phone.val(phone.val() + '-'); // add dash after char #7
}
}
return (key == 8 ||
key == 9 ||
key == 46 ||
(key >= 48 && key <= 57) ||
(key >= 96 && key <= 105));
});
" );
}
Оно рабочее. Но зависит от библиотеки jQuery и «заточено» под американский стандарт, так сказать. Так же данное решение не сработает на страницах, которые не относятся к WooCommerce (справедливо для данного кода выше). Ещё мне не нравится пример заполнителя, пользовательский опыт говорит об обратном, вряд ли все будут придерживаться строгого заполнения.
Можно конечно доработать и всё исправить (в случае с примером выше основанным на jQuery), но мне больше понравилась библиотека Cleave.js и её аддон, который заточен под русские стандарты при вводе номера телефона, учитывая с «восьмёрки» или с «плюс, семёрки» начинает набирать пользователь номер.
Поэтому в данном примере мы подключим саму библиотеку и её аддон для страны с кодом RU (в целях уменьшения размера подключаемого кода) и проверим его работу в действии.
К тому же, подключать мы будет стандартной функцией WP для того чтобы решение было универсальным и могло использоваться на разных страницах к разным формам, в том числе популярного плагина Contact Form 7.
Важное примечание! Библиотека с минувшей осени (обращение автора от 25.11.23г) уже не поддерживается по ряду причин, которые описаны в обращении. Она переписана автором на TypeScript и ES6. Пример в статье просто иллюстрирует решение задачи. В целом рекомендуется эта библиотека.
Первым делом задействуем старую добрую функцию WP wp_enqueue_script(), которая будет подключать скрипт библиотеки Cleave.js и её аддон ориентированный на RU. Проверка ! is_checkout() гарантирует подключение только на странице оформления заказа и исключает подключение на прочих страницах
/**
* Подключаем библиотеку Cleave.js
* для форматирования содержимого <input/> при вводе текста
*/
function poet_load_scripts() {
if ( ! is_checkout() ) {
return;
}
wp_enqueue_script(
'cleave',
'https://cdn.jsdelivr.net/npm/cleave.js@1.6.0/dist/cleave.min.js',
array(),
'1.6.0',
array(
'strategy' => 'defer',
'in_footer' => true
)
);
wp_enqueue_script(
'cleave-phone',
'https://cdn.jsdelivr.net/npm/cleave.js@1.6.0/dist/addons/cleave-phone.ru.js',
array( 'cleave' ),
'1.6.0',
array(
'strategy' => 'defer',
'in_footer' => true
)
);
wp_add_inline_script( 'cleave-phone', "
const cleave = new Cleave('#billing_phone', {
phone: true,
phoneRegionCode: 'ru',
delimiter: '-'
});
" );
}
add_action( 'wp_enqueue_scripts', 'poet_load_scripts' );
wp_add_inline_script( ‘cleave-phone’… инициализирует (вызывает функционал) на нужном нам поле с нужными параметрами, а частности разделителем в виде чёрточки.
Результатом выполнения кода будет предопределённая маска, которая не позволит пользователю вводит через чур много символов и будет учитывать начало ввода «+7» или «8»
Как подключить маску на других страницах, к другим формам?
Всё очень просто. Решение универсальное в пределах WP.
- У нужной формы необходимо понять, как «зацепиться» за нужное поле, или «по айди» или «по классу»
- Узнать «айди» страницы, для того чтобы добавить её в условие проверки, дабы не вызывать где не попадя 🙂
Например, у нас есть форма для обратной связи на странице контактов. Первым делом исследуем нужное поле:
Видим подходящий класс. Следовательно, понимаем, как будем делать «селект» — по классу. Далее, узнаем «айдишник» страницы на которой наша форма. В итоге наш код может выглядеть так:
/**
* Подключаем библиотеку Cleave.js
* для форматирования содержимого <input/> при вводе текста
*/
function poet_load_scripts() {
if ( ! is_checkout() && ! is_page( 53 ) ) {
return;
}
wp_enqueue_script(
'cleave',
'https://cdn.jsdelivr.net/npm/cleave.js@1.6.0/dist/cleave.min.js',
array(),
'1.6.0',
array(
'strategy' => 'defer',
'in_footer' => true
)
);
wp_enqueue_script(
'cleave-phone',
'https://cdn.jsdelivr.net/npm/cleave.js@1.6.0/dist/addons/cleave-phone.ru.js',
array( 'cleave' ),
'1.6.0',
array(
'strategy' => 'defer',
'in_footer' => true
)
);
wp_add_inline_script( 'cleave-phone', "
const cleave = new Cleave('#billing_phone, .wpcf7-tel', {
phone: true,
phoneRegionCode: 'ru',
delimiter: '-'
});
" );
}
add_action( 'wp_enqueue_scripts', 'poet_load_scripts' );
Из примера видно, что мы просто, через запятую, добавили новый селектор по CSS классу. Теперь наша маска применяется к полу телефона созданной плагином Contact Form 7
Рекомендация. Старейтесь всегда проверять исходный код страницы и убеждаться, что нужный скрипт присутствует на ней.