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

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

HIT

16.10.2016

2550

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);

Тэги:

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

  • Похожие записи
  • Комментарии
  • Вложения
Скидки Woocommerce

Скидки Woocommerce

Добавляем и настраиваем в woocommerce различные системы скидок. Стандартная скидка Woocommerce Можно включить «акционную» цену на товар, к ней можно добавить дату окончания скидки. У товара появляется лэйбл «Распродажа», можно Читать далее »

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

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

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

/
Акции Woocommerce

Акции Woocommerce

В современном интернет-магазине необходимо постоянно проводить стимулирующие мероприятия — акции. Реализуем различные механизмы акций на движке Woocommerce. Акция (скидка) на категорию Если нам необходимо сделать скидку на всю категорию товаров. Читать далее »

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

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>

Количество товара
Фильтры Woocommerce
Рекомендации для васФильтры WoocommerceOpttour.ru
Спасибо! Наш менеджер свяжется с Вами в течении 5 минут.