/ Сайтостроение / Плагины / Количество товара

Количество товара

HIT

16.10.2016

2864

3

Количество товара (quantity) — один важнейших элементов функционала интернет-магазина (woocommerce в частности). Есть множество нюансов связанных с количеством товара, рассмотрим их.

Вывод количества в категориях товаров

По-умолчанию в шаблоне вывода товаров параметр количество товара не выводится. Включить его можно функцией:

add_filter( 'woocommerce_loop_add_to_cart_link', 'quantity_inputs_for_woocommerce_loop_add_to_cart_link', 10, 2 );
function quantity_inputs_for_woocommerce_loop_add_to_cart_link( $html, $product ) {
 if ( $product && $product->is_type( 'simple' ) && $product->is_purchasable() && $product->is_in_stock() && ! $product->is_sold_individually() ) {
 $html = '<form action="' . esc_url( $product->add_to_cart_url() ) . '" class="cart" method="post" enctype="multipart/form-data">';
 $html .= woocommerce_quantity_input( array(), $product, false );
 $html .= '<button type="submit" class="button alt">' . esc_html( $product->add_to_cart_text() ) . '</button>';
 $html .= '</form>';
 }
 return $html;
}

При данной функции перестает работать мини-корзина ajax

Поле Количество в шаблоне архива (Ajax)

Отличное решение на Ajax, работает с мини-корзиной.

function custom_quantity_field_archive() {
	$product = wc_get_product( get_the_ID() );
	if ( ! $product->is_sold_individually() && 'variable' != $product->product_type && $product->is_purchasable() && $product->is_in_stock() ) {
		woocommerce_quantity_input( array( 'min_value' => 1, 'max_value' => $product->backorders_allowed() ? '' : $product->get_stock_quantity() ) );
	}
}
add_action( 'woocommerce_after_shop_loop_item', 'custom_quantity_field_archive', 9 );


function custom_add_to_cart_quantity_handler() {
	wc_enqueue_js( '

		jQuery( ".product-type-simple" ).on( "click", ".quantity input", function() {
			return false;
		});

		jQuery( ".product-type-simple" ).on( "change input", ".quantity .qty", function() {
			var add_to_cart_button = jQuery( this ).parents( ".product" ).find( ".add_to_cart_button" );
			// For AJAX add-to-cart actions
			add_to_cart_button.data( "quantity", jQuery( this ).val() );
			// For non-AJAX add-to-cart actions
			add_to_cart_button.attr( "href", "?add-to-cart=" + add_to_cart_button.attr( "data-product_id" ) + "&quantity=" + jQuery( this ).val() );
		});

	' );
}
add_action( 'init', 'custom_add_to_cart_quantity_handler' );

Устанавливаем минимум и максимум

//Min and Max quantity

// Simple products
add_filter( 'woocommerce_quantity_input_args', 'jk_woocommerce_quantity_input_args', 10, 2 );

function jk_woocommerce_quantity_input_args( $args, $product ) {
	if ( is_singular( 'product' ) ) {
		$args['input_value'] 	= 1;	// Starting value (we only want to affect product pages, not cart)
	}
	$args['max_value'] 	= 100; 	// Maximum value
	$args['min_value'] 	= 1;   	// Minimum value
	$args['step'] 		= 1;    // Quantity steps
	return $args;
}

// Variations
add_filter( 'woocommerce_available_variation', 'jk_woocommerce_available_variation' );

function jk_woocommerce_available_variation( $args ) {
	$args['max_qty'] = 100; 		// Maximum value (variations)
	$args['min_qty'] = 1;   	// Minimum value (variations)
	return $args;
}

При ручном вводе можно ввести любое количество

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

Если необходимо корректировать количество (+ -) товара в мини-корзине, то нужно сделать следующее:

1. Вставляем в шаблоне мини-корзины (cart/mini-cart.php) кнопки + и —

<a rel="nofollow" href="/?wc-ajax=add_to_cart&amp;add-to-cart=<?php echo $cart_item['product_id'];?>" data-quantity="1" data-product_id="<?php echo $cart_item['product_id'];?>" data-product_sku="" class="button product_type_simple add_to_cart_button ajax_add_to_cart btnPlus">+</a>

<?php echo '<a class="button btnMinus" onClick="updateQty(\''.$cart_item_key.'\','.($cart_item['quantity']-1).')">–</a>'; ?>

2. Создаем шаблон php c названием template-setquantity.php и содержимым:

<?php
// Template Name: Request template for Set Quantity
?>
<?php
//the cart key stores information about cart
$cartKeySanitized = filter_var($_POST['cart_item_key'], FILTER_SANITIZE_STRING);

//the new qty you want for the product in cart
$cartQtySanitized = filter_var($_POST['cart_item_qty'], FILTER_SANITIZE_STRING);

//update the quantity
global $woocommerce;
ob_start();

$woocommerce->cart->set_quantity($cartKeySanitized,$cartQtySanitized);
ob_get_clean();
?>

3. Создаем новую страницу с названием Updatecart и выбираем шаблон Request template for Set Quantity

4. Добавляем скрипт (в файл с другими скриптами сайта)

function updateQty(key,qty){
 url = 'https://bazabirs.ru/updatecart/';
 data = "cart_item_key="+key+"&cart_item_qty="+qty;

 jQuery.post( url, data ) .done(function( data ) {
  //function updateCartFragment 
  updateCartFragment();
 });
}

function updateCartFragment() {
 $fragment_refresh = {
  url: woocommerce_params.ajax_url,
  type: 'POST',
  data: { action: 'woocommerce_get_refreshed_fragments' },
  success: function( data ) {
    if ( data && data.fragments ) {          
        jQuery.each( data.fragments, function( key, value ) {
            jQuery(key).replaceWith(value);
        });

        if ( $supports_html5_storage ) {
            sessionStorage.setItem( "wc_fragments", JSON.stringify( data.fragments ) );
            sessionStorage.setItem( "wc_cart_hash", data.cart_hash );
        }                
        jQuery('body').trigger( 'wc_fragments_refreshed' );
    }
  }
 };

 //Always perform fragment refresh
 jQuery.ajax( $fragment_refresh );  
}

CSS стили кнопок + и —

.btnPlus {
    background-color: #01a7e5;
    padding: 7px;
    width: 10px;
    color: #fff;
}
.btnMinus {
    background-color: #ff5722;
    padding: 7px;
    width: 10px;
    color: #fff;
    cursor: pointer;
}

Изменить вид quantity

Стандартный вид количества woocmmerce не очень удобен, доработаем его.

Изменим шаблон woocommerce global/quantity-input.php:

if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
?>
<div class="quantity">
<input class="minus" type="button" value="-">
<input type="number" step="<?php echo esc_attr( $step ); ?>" min="<?php echo esc_attr( $min_value ); ?>" max="<?php echo esc_attr( $max_value ); ?>" name="<?php echo esc_attr( $input_name ); ?>" value="<?php echo esc_attr( $input_value ); ?>" title="<?php echo esc_attr_x( 'Qty', 'Product quantity input tooltip', 'woocommerce' ) ?>" class="input-text qty text" size="4" />
<input class="plus" type="button" value="+">
</div>

CSS

/* Количество */

input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
    /* display: none; <- Crashes Chrome on hover */
    -webkit-appearance: none;
    margin: 0; /* <-- Apparently some margin are still there even though it's hidden */
}

input[type="number"] { -moz-appearance: textfield;}

.quantity {margin: 0 auto; display: table;}

.minus {
    border: none;
    color: #fff;
    background-color: rgba(140,215,32,0.7);
    height: 30px;
    width: 30px;
    /*display: table-cell;*/
    cursor: pointer;
}

.plus {
    border: none;
    color: #fff;
    background-color: rgba(140,215,32,0.7);
    height: 30px;
    width: 30px;
    /*display: table-cell;*/
    cursor: pointer;
}

.minus:hover, .plus:hover {background-color: rgba(140,215,32,1);}

.qty {
    border: none;
    color: #111;
    /* font-weight: bold; */
    height: 30px;
    display: table-cell;
    box-sizing: border-box;
    width: 20% !important;
}

И добавляем скрипт

// Скрипт для кнопок + и -

    $(document).ready(function(){
        $('.quantity').on('click', '.plus', function(e) {
            $input = $(this).prev('input.qty');
            var val = parseInt($input.val());
            $input.val( val+1 ).change();
        });
 
        $('.quantity').on('click', '.minus', function(e) {
            $input = $(this).next('input.qty');
            var val = parseInt($input.val());
            if (val > 1) {
                $input.val( val-1 ).change();
            } 
        });
    });

В шаблоне архивов товаров, в карточке товаров, сопутствующих — метод работает отлично. В корзине не работает из-за обновления ajax.

Чтобы работал в корзине надо изменить .quantity на body. Но с body не работает в шаблоне архивов товаров.

// Скрипт для кнопок + и -

    $(document).ready(function(){
        $('body').on('click', '.plus', function(e) {
            $input = $(this).prev('input.qty');
            var val = parseInt($input.val());
            $input.val( val+1 ).change();
        });
 
        $('body').on('click', '.minus', function(e) {
            $input = $(this).next('input.qty');
            var val = parseInt($input.val());
            if (val > 1) {
                $input.val( val-1 ).change();
            } 
        });
    });

В шаблоне корзины форма обновляется ajax'ом, но мы используем селектор body и поэтому клики на .plus и .minus продолжают срабатывать и после обновления

if (val > 1) { — если это сравнение снизить до ноля, то можно в корзине, с помощью кнопки минус, фактически удалять товары.

Еще один важный момент! Если корзина обновляется автоматически, то при нажатии + или - минус в первый раз обновление срабатывает, а кнопка update_cart только становится активной (изначально у этого input стоит атрибут disabled), и только после второго нажатия срабатывает обновление. Исправляем это так — изначально "взводим" кнопку обновления, при этом изначально и при последующих обновлениях ajax.

 $(document).bind('ready ajaxComplete', function(){	
		$('[name="update_cart"]').attr("disabled",false);
    });	

Надо разделить вывод скрипта в корзине от скрипта в архивах.

При нажатии + или - происходит перезагрузка ajax, но пользователь, который хочет изменить количество на десятки единиц может этого не понять. Чтобы этот момент сгладить, надо в скрипте автоматического обновления корзины (при обновлении количества) добавить небольшую задержку:

setTimeout(function () {  jQuery("[name='update_cart']").trigger("click"); }, 1000);

Тэги:

Поделится информацией с друзьями

  • Похожие записи
  • Комментарии
  • Вложения
Upgrade WC

Upgrade WC

Очередная серия улучшений (upgrade) плагина WC. Буду добавлять по мере изучения новые решения. Поиск по SKU (артикулу) Из коробки WC не ищет по артикулам (SKU). Но достаточно установить плагин Search Читать далее »

/
Цены в зависимости от группы пользователей

Цены в зависимости от группы пользователей

Попробуем разобраться в вопросе цен для определенных групп пользователей. Либо это должно быть реализовано специальной колонкой цен, либо скидкой на все товары. WC Role Based Price Плагин WC Role Based Читать далее »

/ /
Атрибуты товара WC

Атрибуты товара WC

В интернет-магазине Woocommerce есть функционал атрибутов. Атрибуты товара — это дополнительные поля для различных значений. Атрибуты бывают 2-х типов: текстовый (text) и с выбором значения (select). Архив значения атрибута Для Читать далее »

/

Добавить комментарий

3 комментария

  1. Дмитрий

    При нажатии на кнопку «добавить в корзину» все-равно добавляется в кол-ве 1 штука, а не столько, сколько было введено на карточке товара.

  2. Дмитрий

    Кнопка «-» не работает в мини корзине

    1. Alexandr
      Alexandr

      Когда вставляешь сами кнопки в шаблон WC миникорзины нужно кнопку «—» поставить перед полем количество, а кнопку «+» после.
      У меня сделано так:


      <td style="width: 20px;">
      <?php echo '<a class="minus" onClick="updateQty(\''.$cart_item_key.'\','.($cart_item['quantity']-1).')">–</a>'; ?>
      </td>

      <td class="product-quantity">
      <?php echo apply_filters( 'woocommerce_checkout_cart_item_quantity', ' <strong class="product-quantity">' . sprintf( '&times; %s', $cart_item['quantity'] ) . '</strong>', $cart_item, $cart_item_key ); ?>
      </td>

      <td style="width: 20px;">
      <a rel="nofollow" href="/?wc-ajax=add_to_cart&amp;add-to-cart=<?php echo $cart_item['product_id'];?>" data-quantity="1" data-product_id="<?php echo $cart_item['product_id'];?>" data-product_sku="" class="product_type_simple add_to_cart_button ajax_add_to_cart plus">+</a>
      </td>

Количество товара
Настройки сайта с theme customizer
Рекомендации для васНастройки сайта с theme customizerOpttour.ru
Спасибо! Наш менеджер свяжется с Вами в течении 5 минут.