Сен
11
4

Выполнение jQuery скриптов при выборе вариаций товаров в WooCommerce

jQuery и вариации товаровНедавно я постил разбор задачи по всплывающей форме подписки Contact Form 7 с передачей параметра через JavaScript, а сегодня будет еще одна практичная заметка. Она пригодится для создания WordPress-магазина с вариативными товарами WooCommerce, когда при заказе продукции допускается выбор определенных ее параметров (цвет, размер). Мы научимся “перехватывать” разные события для данного типа товаров (отображение на сайте, изменение параметра) и посмотрим, как “на лету” вносить изменения в единичную страницу продукта.

На самом деле сегодня будет не какой-то один конкретный кейс, я просто собрал для вас три полезных сниппета по теме. Кто-то может сказать, что достаточно было бы просто скинуть ссылку на них, но я решил проделать чуть более объемную работу — в статье дополню код некоторыми пояснениями и своими впечатлениями о результатах, т.к. я уже успел затестить их в деле.

Сегодняшние примеры я специально расположил отдельно от общих хаков для вариаций т.к. здесь идет акцент на срабатывание событий и использование jQuery библиотеки. Хотя прошлый пост также советую глянуть. Обязательно(!) дочитайте статью до конца, в 4-том пункте делюсь весьма полезным опытом по решению одной задачи.

1. Получение данных о вариации при переключении

Автор этого сниппета рассказал, что в одном из проектов ему нужно было выводить сообщения при выборе тех или иных параметров продукции на странице. В ходе изучения вопроса он обнаружил парочку jQuery-событий для плагина WooCommerce в файле add-to-cart-variation.js. Триггеры из этого файла позволяют перехватывать разные event’ы в магазине, например:

$( ".single_variation_wrap" ).on( "show_variation", function ( event, variation ) {
	alert( variation.variation_id );
	console.log( variation );
} );
 
$( document ).on( "found_variation.first", function ( e, v ) {
	alert( v.variation_id );
	console.log( v );
} );

Данные события и действия в них выполняются после появления/отображения страницы с вариативным товаром. По крайней мере первая часть кода точно этим занимался, а вот по второй, если честно, не совсем понял – то ли она срабатывать только при выборе значения «по умолчанию», то ли хз – нужно тестить и смотреть информацию в консоле.

Кстати, там же в консоли (в инструментах разработчика Chrome Devtools и др. браузеров) вы можете увидеть, что почти вся важная инфа по вариативному товару доступна в виде объекта (то есть с ней можно работать).

Еще одно событие, представленное ниже (woocommerce_variation_select_change), куда интереснее – оно выполняется при переключении вариаций:

$( ".variations_form" ).on( "woocommerce_variation_select_change", function () {
	alert( "Options changed" );
} );

В функцию вставляете любые действия, которые вам нужно выполнять.

2. Изменение заголовка товара в зависимости от вариации

Этот хак позволяет при смене атрибута цвета продукции в магазине добавлять соответствующее значение в заголовок на странице. Здесь используются jQuery, PHP и функции/переменные WooCommerce.

add_filter( 'wp_footer','custom_product_title_script' );
function custom_product_title_script(){
    global $post;
 
    // Only single product pages
    if( ! is_product() ) return;
 
    // get an instance of the WC_Product Object
    $product = wc_get_product($post->ID);
 
    // Only for variable products
    if( ! $product->is_type( 'variable' ) ) return;
 
    // Here set your specific product attributes in this array (coma separated):
    $attributes = array('pa_color');
 
    // The 1st loop for variations IDs
    foreach($product->get_visible_children( ) as $variation_id ) {
 
        // The 2nd loop for attribute(s)/value
        foreach($product->get_available_variation( $variation_id )['attributes'] as $key => $value_id ){
            $taxonomy = str_replace( 'attribute_', '', $key ); // Get the taxonomy of the product attribute
 
            // Just for defined attributes
            if( in_array( $taxonomy, $attributes) ){
                // Set and structure data in an array( variation ID => product attribute => term name )
                $data[ $variation_id ][$taxonomy] = get_term_by( 'slug', $value_id, $taxonomy )->name;
            }
        }
    }
 
    ?>
        <script type="text/javascript">
            (function($){
                // variables initialization
                var variationsData = <?php echo json_encode($data); ?>,
                    productTitle = $('.product_title').text(),
                    color = 'pa_color';
                console.log(variationsData);
 
                // function that get the selected variation and change title
                function update_the_title( productTitle, variationsData, color ){
                    $.each( variationsData, function( index, value ){
                        if( index == $('input.variation_id').val() ){
                            $('.product_title').text(productTitle+' - '+value[color]);
                            console.log('TITLE UPDATED');
                            return false;
                        } else {
                            $('.product_title').text(productTitle);
                        }
                    });
                }
 
                // Once all loaded
                setTimeout(function(){
                    update_the_title( productTitle, variationsData, color );
                }, 300);
 
                // On live event: select fields
                $('select').blur( function(){
                    update_the_title( productTitle, variationsData, color );
                });
            })(jQuery);
        </script>
    <?php
}

Вот как в итоге будет выглядеть результат сниппета:

Изменение заголовка вариативного товара

Я тестировал метод, все отлично работает. Какие нюансы могу сказать:

  • Не смотря на слова автора предыдущего хака о том, что jQuery передает всю инфу вариации в виде объекта, мне больше нравится считывание данных в этом случае – последовательное, с проверками (IF), похожее на код полноценного WP-плагина.
  • С другой стороны представленный метод определения события (через setTimeout, blur) как-то не особо зашел, прошлый лучше.
  • Важно! Параметр вариации считывается в строке $attributes = array(‘pa_color’), куда вы можете поставить абсолютно любое значение (pa_ здесь – просто приставка, атрибут = color).

3. Определяем текущую выделенную вариацию

Третий сниппет использует, в принципе, те же PHP/jQuery фишки, о которых говорилось выше, поэтому будет как бонус. Однако и здесь есть полезная информация – при выборе вариации WooCommerce создает скрытое поле с значением variation_id. Не знаю почему, но у меня на нескольких сайтах вот так (а должен быть ID):

Переменная variation_id

Возможно он равен нулю, потому что я использую отображение вариативных значений в виде чекбоксов, а не выпадающего списка (Select), что идет по умолчанию. Хотя, даже не смотря на это, параметр variation_id, который также используется и в первых двух хаках выше, у меня нормально выводился через alert и не равнялся нулю.

В общем, как бы там ни было, третий сниппет выглядит так:

add_action( 'woocommerce_before_add_to_cart_quantity', 'bbloomer_display_dropdown_variation_add_cart' );
 
function bbloomer_display_dropdown_variation_add_cart() {
 
   global $product;
 
   if ( $product->is_type('variable') ) {
 
      ?>
      <script>
      jQuery(document).ready(function($) {
 
         $('input.variation_id').change( function(){
            if( '' != $('input.variation_id').val() ) {
 
               var var_id = $('input.variation_id').val();
               alert('You just selected variation #' + var_id);
 
            }
         });
 
      });
      </script>
      <?php
 
   }
 
}

Его из всех трех я не тестировал, но по коду все выглядит вполне рабочим: вставка хука woocommerce_before_add_to_cart_quantity, проверка вариативного продукта $product, использование jQuery. Однако (!) как я уже сказал выше, у меня variation_id, почему-то всегда = 0, и в таком случае никакого события «change» для этой переменной может просто не произойти. Нужно разбираться.

4. Подмена скрипта add-to-cart-variation.js для вариаций

Во время работы над одним сайтом выяснил достаточно интересную закономерность в работе вариативных товаров, которая может вам пригодиться. Если вкратце по задаче – нужно было сделать наложение 2х картинок для товара, одна из которых считывалась из вариации, вторая – просто изображение.

Изначально в шаблоне единичного просмотра продукции я пытался подменить стандартный процесс генерирования превью с wc_get_gallery_image_html на свой, где и делал «склейку» двух фоток, однако при переключении параметров продукта (размер, цвет и т.п.) эта затея переставала работать.

Оказывается функция wc_get_gallery_image_html срабатывает только при первой «прорисовке» страницы, а дальше за все переключения картинок отвечают JS-скрипты, что находятся в assets/js/frontend/add-to-cart-variation.js. В него то вам и нужно вносить изменения, если хотите полностью управлять сменой картинок для вариаций.

В магазине этот файл подключается через функцию woocommerce_variable_add_to_cart(), и самое классное, что она является «pluggable», то есть вы можеет создать функцию с таким же именем functions.php, после чего она будет срабатывать вместо базовой. Копируете ее исходный код + заменяете вызов классического скрипта на свой.

function woocommerce_variable_add_to_cart() {
	global $product;
 
	// Enqueue variation scripts.
	// wp_enqueue_script( 'wc-add-to-cart-variation' );
 
    // Добавляем новый скрипт для обработки вариаций
    wp_deregister_script( 'wc-add-to-cart-variation' );
    wp_register_script( 'wc-add-to-cart-variation', get_stylesheet_directory_uri().'/js/my-add-to-cart-variation.js', array( 'jquery' ), WC_VERSION, true );
    wp_enqueue_script( 'wc-add-to-cart-variation' );
 
	// Get Available variations?
	$get_variations = count( $product->get_children() ) <= apply_filters( 'woocommerce_ajax_variation_threshold', 30, $product );
 
	// Load the template.
	wc_get_template(
		'single-product/add-to-cart/variable.php',
		array(
			'available_variations' => $get_variations ? $product->get_available_variations() : false,
			'attributes'           => $product->get_variation_attributes(),
			'selected_attributes'  => $product->get_default_attributes(),
		)
	);
}

Здесь ваш новый файл заливается в директорию с шаблоном по адресу путь_к_теме/js/my-add-to-cart-variation.js (работает с дочерними), а дальше в нем редактируете скрипты как угодно.

В моем случае, повторюсь, надо было работать с превьюшками продукции, поэтому я нашел и отредактировал функцию $.fn.wc_variations_image_update, которая как раз отвечает за “обновление” изображений.

Итого. Все сниппеты вручную добавляются в файл функций либо установите плагин Code Snippets. Изначально в работе я использовал второй метод для считывания значения вариаций и данных из базы, но совместил его с первым способом срабатывания jQuery-событий.

Однако, учитывая опыт и находки, изложенные в последнем четвертом пункте, есть вероятность, что вам даже не придется создавать какие-то дополнительные сниппеты для перехвата JS-событий, а достаточно будет покопаться в файле add-to-cart-variation.js. Как минимум, моя исходная подмена функции wc_get_gallery_image_html для генерирования превью, по сути, оказалась не нужной.

Вообще, если вы неплохо разбираетесь в JavaScript, то сегодняшний пост представит вам массу возможностей для редактирования страницы продукции и не только – сможете менять картинки, цены и др. Если есть что интересного дополнить, пишем в комментариях.

рейтинг Оцените статью:
Ужасная статьяНичего интересногоТак себеНормальноХорошоКлассный постВ закладки!
(голосов - 26, средний балл: 3,96 из 7)
Загрузка...

категория Категории: WooCommerce; Хаки и секреты;
теги Теги: , , , , , .

комментария 4 к статье “Выполнение jQuery скриптов при выборе вариаций товаров в WooCommerce”

  • Mark   05.10.2019

    Привет.
    Я только знакомлюсь с WP, и не совсем может разбираюсь еще.

    У меня вопрос. На странице вариативного товара, У меня цена отображается в двух местах. Есть верхняя (там раньше был диапазон, благодаря твоему хуку отображается минимальная) и есть внизу под выбором вариативного товара.
    Допустим у меня есть товар в двух фасовках 1л и 5л. Я хотел бы. на странице товара цена отображалась только в одном месте. То есть изменялась основная цена, а не добавлялась еще одна.
    Как мне это реализовать? Казалось бы столь очевидная штука, но не нашел решения в сети.

  • Tod   05.10.2019

    Mark, посмотрите статью-сборник хаков для вариаций — там была парочка решений с ценами. В шаблоне магазина многое реализованое через hook(хуки), которые в каком-то из файлов вызываются с помощью функции add_action, поэтому если смотреть php-файл шаблона, то там нет вставки тех или иных блоков, но по факту они выводятся на сайте. Тут, в общем, надо вникать в структуру woocommerce и искать соответствующие сниппеты/хаки в англоязычном интернете.

  • Николай   23.06.2020

    Хорошая статья . Как раз мне такое и надо .
    Но я не программист , Сможете помочь реализовать на моём сайте ?
    не бесплатно конечно
    Спасибо

  • Tod   24.06.2020

    Николай, сейчас отпишусь на почту.

Оставить комментарий


Блог Wordpress Inside поможет вам научиться работать в вордпресс, закрепить и расширить имеющиеся знания. Плагины и шаблоны, разные хаки и функции wp, оптимизация и безопасность системы – все это и намного больше вы сможете найти на страницах нашего проекта!

Если хотите быстро и оперативно получать последние новости и статьи, то рекомендуем подписаться на обновления блога:

Поиск:
Последние посты
Лучшее в категории

Облако тегов
Скажи свое мнение!

В чем основные плюсы Wordpress?

Посмотреть результаты

Загрузка ... Загрузка ...
Друзья проекта
Последние новости