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

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

HIT

16.10.2016

12107

4

Количество товара (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.

//Кнопка Обновить в Корзине изначально активна	
jQuery(document).bind('ready ajaxComplete', function(){	
	jQuery('[name="update_cart"]').attr("disabled",false);
});

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

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

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

Возможные ошибки

В одном из проектов, при добавлении плагина с кнопками +/- они не работали по причине того что ранее я внедрил сам функционал в файл site-scripts.js, т.е. он дублировался и из-за этого работал не корректно.

Кнопка + может не работать из-за того что в input не прописывается значение max. В этом случае, нужно немного изменить скрипт:

jQuery('body').on('click', '.plus', function() {
	var input = jQuery(this).prev('input.qty');
	var val = parseFloat(input.val());
	var step = parseFloat(input.attr('step'));
	var max = parseFloat(input.attr('max'));
	if (isNaN(max)) { var max = 999999; }
	if (val < max) { input.val( val+step ).change(); }
});

Поделиться в соц. сетях:

  • Похожие записи
  • Комментарии
  • Вложения
Настройка полей заказчика

Настройка полей заказчика

При заказе товара необходимо заполнить данные покупателя (имя, телефон, адрес доставки и т.д.). В стандартном варианте поля эти несколько «раздуты», много лишнего, требуется некоторое оформление. Можно использовать плагин Saphali Woocommerce Читать далее »

/
WooCommerce AJAX Products Filter

WooCommerce AJAX Products Filter

Раннее данный фильтр участвовал в общем обзоре, в котором я приводил основные особенности. Рассмотрим подробнее работу с фильтром WooCommerce AJAX Products Filter (также он называется Advanced AJAX Product Filters). Работа Читать далее »

/
Купон на следующий заказ

Купон на следующий заказ

Проработаем функционал по отправке купона на следующий заказ. Дополнительные условия: Купон должен отправлять только при наличии в текущем заказе товара из определенной категории Номинал купона либо 30% если сумма следующей Читать далее »

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

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

  1. Дмитрий

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

  2. Дмитрий

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

    1. 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>

  3. Dan Zakirov

    Какой то костыль получился по мини-корзине. Вот более наверное правильное решение https://gist.github.com/ashokmhrj/fda5a23f7bdfc55749bd2bd53c64a8ca 

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