1

I want to display the quantity of each product in cart under the add to cart button in the product tile.

represenation

How can we achieve below Figure ?

2 Answers 2

2

add below code in addtocart.phtml

<?php
$cartItems = $block->getCartQty();
$defaultQty = ($cartItems[$_item->getId()]['qty']) ?? 0;

$defaultQty = ($sellingFormat != 'kg') ? $defaultQty : number_format($defaultQty,2);
?>


<form data-role="tocart-form_<?= $_item->getId() ;?>" data-bind="scope: 'qty_change_<?= $_item->getId() ;?>'" id="frm_<?= /* @escapeNotVerified */ $_item->getId() ?>" data-product-sku="<?= $block->escapeHtml($_item->getSku()) ?>" method="post">

        <input type="hidden" name="product" value="<?= /* @escapeNotVerified */ $_item->getId() ?>">
        <input type="hidden" name="item_id" class="cart-item-id" value="<?= ($cartItems[$_item->getId()]['item_id']) ?? ''; ?>">
        <?= $block->getBlockHtml('formkey') ?>
        <button class="action tocart primary decrease <?php if($defaultQty == $qtyIncrementBy) : echo 'delete-qty'; endif; ?> qty_<?= /* @escapeNotVerified */ $_item->getId() ?>" data-bind="click: decreaseQty"><span class="minus"></span></button>
        <div class="input-text qty">
            <input id="qty_<?= /* @escapeNotVerified */ $_item->getId() ?>"
                   name="qty"
                   readonly
                   data-bind="value: qty()"
                   type="number"
                   value="<?= $defaultQty ?>"
                   readonly
                   size="4"
                   style="width:50px"
                   title="<?= $block->escapeHtml(__('Qty')) ?>"
                   class="input-text"
                   data-validate="<?= $block->escapeHtml(json_encode($block->getQuantityValidators())) ?>"
            />
            <span class="qty-with-tag">
                <span class="selling-format-qty-<?= /* @escapeNotVerified */ $_item->getId() ?>"><?= $defaultQty ?></span><label><?= ($sellingFormat == 'kg') ? $sellingFormatLabel : '' ?></label>
            </span>
        </div>
        <button class="action tocart primary increase" data-bind="click: increaseQty"><span class="Plus"></span></button>

    </form>

create a function getCartQty where it get cart qantities

create qty_change.js

define([
'ko',
'uiComponent',
'jquery',
'Magento_Customer/js/customer-data'

], function (ko, Component,$,customerData) { 'use strict'; return Component.extend({

    minicartSelector: '[data-block="minicart"]',
    addToCartButtonSelector: '.action.tocart',
    messagesSelector: '[data-placeholder="messages"]',
    updateCartUrl : BASE_URL+'ffc_checkout/cart/addToCart',
    ajaxRequest: [],

    initialize: function () {
        //initialize parent Component
        this._super();
        this.qty = ko.observable(this.defaultQty.toFixed(this.decimalPoint));
        var self = this;
    },
    decreaseQty: function() {

        var product_id = this.productId;

        if($('#qty_'+product_id).val() == 0) {
            this.qty($('#qty_'+product_id).val());
        }

        var newQty = parseFloat(this.qty()) - this.qtyIncrement;

        if (newQty < 0)
        {
            newQty = 0;

            return;
        }

        this.abortAjaxRequest(product_id);

        if(newQty < parseFloat(this.minCartQty)) {
            newQty = 0;
        }

        var availableQty = window.atob(this.saleableQty);

        if(availableQty < newQty) {
            newQty = parseFloat(availableQty);
        }

        this.addRemoveDeleteClass(newQty);
        $('.selling-format-qty-'+product_id).text(newQty.toFixed(this.decimalPoint));


        this.qty(newQty.toFixed(this.decimalPoint));
        $.cookie('cart_qty['+product_id+']',newQty);

        this.submitForm();

    },
    increaseQty: function() {
        var product_id = this.productId;
        if($('#qty_'+product_id).val() == 0) {
            this.qty($('#qty_'+product_id).val());
        }

        var availableQty = window.atob(this.saleableQty);

        if(availableQty < parseFloat(this.qty()) + this.qtyIncrement) {
            return;
        }


        this.abortAjaxRequest(product_id);

        var newQty = parseFloat(this.qty()) + this.qtyIncrement;

        if(newQty < this.minCartQty) {
            newQty = this.minCartQty;
        }

        this.addRemoveDeleteClass(newQty);
        $('.selling-format-qty-'+product_id).text(newQty.toFixed(this.decimalPoint));


        this.qty(newQty.toFixed(this.decimalPoint));

        $.cookie('cart_qty['+product_id+']',newQty);

        var self = this;

        this.submitForm();
    },

    submitForm: function() {

        var tmpId = "tocart-form_"+this.productId;

        this.ajaxSubmit($('[data-role='+tmpId+']'));
    },

    /**
     * @param {jQuery} form
     */
    ajaxSubmit: function (form) {
        var  formData;

        //$(this.minicartSelector).trigger('contentLoading');

        var self = this;
        var product_id = this.productId;
        formData = new FormData(form[0]);

        this.ajaxRequest[product_id] = $.ajax({
            url: this.updateCartUrl,
            data: formData,
            type: 'post',
            dataType: 'json',
            cache: false,
            contentType: false,
            processData: false,

            /** @inheritdoc */
            success: function (res) {

                if(form.find('.cart-item-id').val() == '') {
                    form.find('[name="item_id"]').val(res.item_id);
                }

                if(self.qty() ==0) {
                    form.find('.cart-item-id').val('')
                }

                // /** Update tax, discount and save on order */
                // $('#minicart-tax').hide();
                // $('#minicart-discount').hide();
                // $('#save_on_order_text').hide();
                // if(res.tax_amount > 0) {
                //     $('#minicart-tax').show();
                //     $('#minicart-tax-per').html('<span>Tax('+ res.tax_percentage +')</span>');
                //     $('#minicart-tax-amount').html(res.tax);
                // }
                // if(res.discount_amount > 0) {
                //     $('#minicart-discount').show();
                //     $('#minicart-discount-amount').html(res.discount);
                // }
                // if(res.save_on_order > 0) {
                //     $('#save_on_order_text').show();
                //     var saveText = 'You will save AED '+ res.save_on_order +' on this order.';
                //     $('#save_on_order_text').html(saveText);
                // }
            },

            /** @inheritdoc */
            error: function (res) {

            },

            /** @inheritdoc */
            complete: function (res) {
                if (res.state() === 'resolved') {
                    var response = res.responseJSON;
                    if(typeof $('#cart-item-'+response.item_id+'-qty').val() != "undefined"
                        && eval($('#cart-item-'+response.item_id+'-qty').val()) != eval(self.qty()))
                    {
                        self.ajaxSubmit(form);
                    } else {
                        $.cookie('cart_qty['+product_id+']',null);
                    }
                }
            }
        });
    },

    disableAddToCartButton: function () {
        var tmpId = "tocart-form_"+this.productId;
        var form = $('[data-role='+tmpId+']');
        var addToCartButton = form.find('.action.tocart');
        addToCartButton.attr("disabled", true);
    },

    enableAddToCartButton: function () {
        var tmpId = "tocart-form_"+this.productId;
        var form = $('[data-role='+tmpId+']');
        var addToCartButton = form.find('.action.tocart');
        addToCartButton.attr("disabled", false);
    },

    abortAjaxRequest: function (product_id) {
        if(this.ajaxRequest[product_id] != null) {
            this.ajaxRequest[product_id].abort();
            this.ajaxRequest[product_id] = null;
        }
    },

    addRemoveDeleteClass: function (newQty) {
        $('.qty_'+this.productId).removeClass('delete-qty');
        if(newQty == this.qtyIncrement) {
            $('.qty_'+this.productId).addClass('delete-qty');
        }
    }

});

});

Hope it works for you as I have implemented same feature in my website.

1

As I can see, you want to display the quantity of cart products in your product listing page. Hence, to achieve this, you have to override the block Magento\Catalog\Block\Product\ListProduct which is used by the Magento_Catalog::product/list.phtml template.

In the overridden ListProduct class , use the dependency injection way to inject the \Magento\Checkout\Model\Session class in order to get the cart items collection. Do not use the model \Magento\Checkout\Model\Cart as it is deprecated.

In your overridden ListProduct class, write a function to return the quote items ($this->yourCheckoutSessionObject->getQuote()->getAllVisibleItems();) and get the results in your list.phtml file. There in the product collection-loop, provide a condition to check if the current product id is equal to the product id in your cart. If so display the cart item product quantity using getQty() function.

2
  • Thanks for the help. What i have to do for updating the in cart field dynamically when the product is added to cart using ajax cart. Commented Dec 27, 2017 at 11:19
  • For that, you should use a container (for example <div id="any-id">) for displaying the In Cart field. When you use ajaxCart function , return the latest quantity on the success of ajaxCart function and set the innerHtml of your In Cart field container (div) with the latest quantity.
    – MGento
    Commented Dec 27, 2017 at 12:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.