Метка: woocommerce

Замена вариаций продукта с Select на Radio buttons для WooCommerce (вариант 2)

В одном из статей был описан метод, как можно заменить стандарный вывод выбора вариаций с помощью select на radio. Эта статья находится тут.

Сегодня же будет показан еще один, альтернативный, вариант решения данной проблемы.

Открываем файл /ваша_тема/woocommerce/single-product/add-to-cart/variable.php (если такого файла нет, то нужно создать его.

В папке /ваша_тема/woocommerce/ находятся шаблоны woocommerce, которые изменяются для темы. Исходники их находятся в папке с плагином woocommerce в папке /templates.

В этом файле мы перед функцией вывода select выбора вариаций товара добавляем

<?foreach($options as $index => $item):?>
<label for="<?=sanitize_title( $attribute_name );?>_<?=$item;?>" <?if($index===0):?>class="active"<?endif;?>><?=$item;?></label>
<?endforeach;?>

и оборачиваем все это (вместе с выводом select) в обертку

<div class="radio-input-container"></div>

В итоге у нас получится следующая конструкция:

<div class="radio-input-container">
<?foreach($options as $index => $item):?>
<label for="<?=sanitize_title( $attribute_name );?>_<?=$item;?>" <?if($index===0):?>class="active"<?endif;?>><?=$item;?></label>
<?endforeach;?>
<?php
wc_dropdown_variation_attribute_options(
array(
'options'   => $options,
'attribute' => $attribute_name,
'product'   => $product,
)
);
?>
</div>

в js файл со скриптами добавляем:

$('.radio-input-container label').on('click', function(){
var Value = $(this).text();
var Label = $(this);
$('.radio-input-container label').removeClass('active');
Label.addClass('active');
Label.parent().find('select').val(Value).change();
});

Я также добавил очистку наших «лейблов» по клику на ссылку «Очистить»:

$('.reset_variations').on('click', function(){
$('.radio-input-container label').removeClass('active');
});

и следующие стили получились:

.radio-input-container {
display: flex;
gap: 10px;
flex-wrap: wrap;
margin-bottom: 15px;
label {
width: 20%;
text-align: center;
border: 1px solid @colorGrey;
border-radius: 5px;
padding: 6px 15px 5px 15px;
cursor: pointer;
font-weight: 500;
&:hover, &.active {
border-color: @colorRed;
background: @colorWhite;
}
}
select {
display: none;
}
}

Select я спрятал намеренно, что не портило дизайн и не путало пользователя.

В итоге получилась такая вот красота:

Замена вариаций продукта с Select на Radio buttons для WooCommerce

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

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

Нашел текущий код тут https://gist.github.com/brendonexus/1def5ec2689b66c2101d969c183042bc

Однако обнаружил, что он не просто заменяет вариации продукта, но и выводит предыдущие значения в select.

Поправил его немного и получилось такое:

// add radio buttons for woocommerce's product
function variation_radio_buttons($html, $args)
{
$args = wp_parse_args(apply_filters('woocommerce_dropdown_variation_attribute_options_args', $args), array(
'options' => false,
'attribute' => false,
'product' => false,
'selected' => false,
'name' => '',
'id' => '',
'class' => '',
'show_option_none' => __('Choose an option', 'woocommerce'),
));

if (false === $args['selected'] && $args['attribute'] && $args['product'] instanceof WC_Product) {
    $selected_key = 'attribute_' . sanitize_title($args['attribute']);
    $args['selected'] = isset($_REQUEST[$selected_key]) ? wc_clean(wp_unslash($_REQUEST[$selected_key])) : $args['product']->get_variation_default_attribute($args['attribute']);
}

$options = $args['options'];
$product = $args['product'];
$attribute = $args['attribute'];
$name = $args['name'] ? $args['name'] : 'attribute_' . sanitize_title($attribute);
$id = $args['id'] ? $args['id'] : sanitize_title($attribute);
$class = $args['class'];
$show_option_none = (bool)$args['show_option_none'];
$show_option_none_text = $args['show_option_none'] ? $args['show_option_none'] : __('Choose an option', 'woocommerce');

if (empty($options) && !empty($product) && !empty($attribute)) {
    $attributes = $product->get_variation_attributes();
    $options = $attributes[$attribute];
}

$radios = '<div class="variation-radios">';

if (!empty($options)) {
    if ($product && taxonomy_exists($attribute)) {
        $terms = wc_get_product_terms($product->get_id(), $attribute, array(
            'fields' => 'all',
        ));

        foreach ($terms as $term) {
            if (in_array($term->slug, $options, true)) {
                $radios .= '<div><input type="radio" name="' . esc_attr($name) . '" value="' . esc_attr($term->slug) . '" ' . checked(sanitize_title($args['selected']), $term->slug, false) . '><label for="' . esc_attr($term->slug) . '">' . esc_html(apply_filters('woocommerce_variation_option_name', $term->name)) . '</label></div>';
            }
        }
    } else {
        foreach ($options as $option) {
            $checked = sanitize_title($args['selected']) === $args['selected'] ? checked($args['selected'], sanitize_title($option), false) : checked($args['selected'], $option, false);
            $radios .= '<div><input type="radio" name="' . esc_attr($name) . '" value="' . esc_attr($option) . '" id="' . sanitize_title($option) . '" ' . $checked . '><label for="' . sanitize_title($option) . '">' . esc_html(apply_filters('woocommerce_variation_option_name', $option)) . '</label></div>';
        }
    }
}

$radios .= '</div>';

return $radios;

}

add_filter('woocommerce_dropdown_variation_attribute_options_html', 'variation_radio_buttons', 20, 2);
// end add radio buttons for woocommerce's product

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

Надеюсь, что эта статья будет полезна вам, также как и код.

Также добавлена статья, где рассказывается еще один метод, как решить эту проблему — тут.