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

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

HIT

16.10.2016

13618

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(); }
});
[site-socialshare]
  • Похожие записи
  • Комментарии
  • Вложения
Обзор плагинов по созданию скидок

Обзор плагинов по созданию скидок

Рассмотрим различные плагины по созданию функционала скидок. Рассматриваться будут плагины которые предоставляют возможность комплексного формирования скидок на состав корзины. Практически все плагины в обзоре могут в бесплатной версии предоставить простой Читать далее »

Предоплата товара

Предоплата товара

Рассмотрим возможные решения такого аспекта электронной коммерции как предоплата. Речь пойдет не о предзаказе, и именно о предоплате товара в наличии. Это в большей степень применимо к товарам требующим время Читать далее »

Добавление полей при оформлении заказа

Добавление полей при оформлении заказа

Добавляем поля для шаблона Оформление заказа Woocommerce. Стандартные поля Woocommerce делятся на 3 группы: поля оплаты (billing) поля доставки (shipping) поля аккаунта (account) Тезисно о важных моментах добавления поля: Добавляем Читать далее »

/

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

Notice: Функция WP_Styles::add вызвана неправильно. Стиль с дескриптором "editor-buttons" был поставлен в очередь с незарегистрированными зависимостями: dashicons. Дополнительную информацию можно найти на странице «Отладка в WordPress». (Это сообщение было добавлено в версии 6.9.1.) in /home/t/tiberi6w/opttour.ru/public_html/wp-includes/functions.php on line 6131

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 минут.