1

I want to display all out of stock products in end on category pages, I have tested few solution which is mentioned on Magento stack exchange, But no one is working for me. Anybody can help me regarding how to i can sort out products on base of quantity/stock ? I want to show first Instock product on all category pages, and all out of stock product should be display in end on category pages. I am using Magento 2.4.0.

Thanks

3 Answers 3

0

You can create a before plugin on \Magento\Catalog\Block\Product\ProductList\Toolbar::setCollection()

Create Vendor/Module/etc/di.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <!--  out of stock product at end of list -->
    <type name="Magento\Catalog\Block\Product\ProductList\Toolbar">
        <plugin name="Vendor_Module::OutofstockEnd" type="Vendor\Module\Plugin\Product\ProductList\Toolbar"/>
    </type>
</config>

Then in Vendor\Module\Plugin\Product\ProductList\Toolbar.php add the following:

<?php

namespace Vendor\Module\Plugin\Product\ProductList;
 
class Toolbar
{
    public function beforeSetCollection(
        \Magento\Catalog\Block\Product\ProductList\Toolbar $toolbar,
        $collection
    ) {
        $collection->setOrder('is_salable', 'desc');
        return [$collection];
    }
}
1
  • This is not working properly, showing empty product list page Mar 22, 2021 at 5:15
0

1)First of all you have to create a di.xml and add following code:

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\CatalogWidget\Block\Product\ProductsList" type="vendor\module\Block\Product\ProductsList" />
</config>

2)Then create a block as follows:

<?php
namespace vendor\module\Block\Product;

class ProductsList extends \Magento\CatalogWidget\Block\Product\ProductsList
{

}

3)create templates/product/widget/content/grid.phtml and copy following code:

<?php
use Magento\Framework\App\Action\Action;
/** @var \Magento\CatalogWidget\Block\Product\ProductsList $block */?>
<?php if ($exist = ($block->getProductCollection() && $block->getProductCollection()->getSize())) : ?>
    <?php
    $type = 'widget-product-grid';
    $mode = 'grid';
    $image = 'new_products_content_widget_grid';
    $items = $block->getProductCollection()->getItems();

    $showWishlist = true;
    $showCompare = true;
    $showCart = true;
    $templateType = \Magento\Catalog\Block\Product\ReviewRendererInterface::SHORT_VIEW;
    $description = false;
    ?>
    <div class="block widget block-products-list <?= $mode ?>">
        <?php if ($block->getTitle()) : ?>
            <div class="block-title">
                <strong><?= $block->escapeHtml(__($block->getTitle())) ?></strong>
            </div>
        <?php endif ?>
        <div class="block-content">
            <?= '<!-- ' . $image . '-->' ?>
            <div class="products-<?= $mode ?> <?= $mode ?>">
                <ol class="product-items <?= $type ?>">
                    <?php $iterator = 1; ?>
                    <?php foreach ($items as $_item) : ?>
                        <?= ($iterator++ == 1) ? '<li class="product-item">' : '</li><li class="product-item">' ?>
                        <div class="product-item-info">
                            <a href="<?= $block->escapeUrl($block->getProductUrl($_item)) ?>" class="product-item-photo">
                                <?= $block->getImage($_item, $image)->toHtml() ?>
                            </a>
                            <div class="product-item-details">
                                <strong class="product-item-name">
                                    <a title="<?= $block->escapeHtml($_item->getName()) ?>"
                                       href="<?= $block->escapeUrl($block->getProductUrl($_item)) ?>"
                                       class="product-item-link">
                                        <?= $block->escapeHtml($_item->getName()) ?>
                                    </a>
                                </strong>
                                <?php if ($templateType) : ?>
                                    <?= $block->getReviewsSummaryHtml($_item, $templateType) ?>
                                <?php endif; ?>
                                <?= $block->getProductPriceHtml($_item, $type) ?>
                                <?= $block->getProductDetailsHtml($_item) ?>
                                <?php if ($showWishlist || $showCompare || $showCart) : ?>
                                    <div class="product-item-inner">
                                        <div class="product-item-actions">
                                            <?php if($showCart) : ?>
                                            
                                            <div class="fieldset">
                                                    <label class="label" for="qty"><span><?php echo __('Qty') ?></span></label>
                                                    <div class="control">
                                                    
                                                    <input type="number"
                                                           name="qty"
                                                           id="<?= 'qty_'.$id ?>"
                                                           value="<?php echo $block->getProductDefaultQty() * 1 ?>"
                                                           title="<?php echo __('Qty') ?>"
                                                           class="input-text qty"
                                                           data-validate="<?php echo $block->escapeHtml(json_encode($block->getQuantityValidators())) ?>"
                                                           />
                                                    
                                                <div class="actions-primary">
                                                    <?php if ($_item->isSaleable()) : ?>
                                                        <?php $postParams = $block->getAddToCartPostParams($_item); ?>
                                                        <?php $id = $_item->getId(); ?>
                                                        <form data-role="tocart-form" data-product-sku="<?= $block->escapeHtml($_item->getSku()) ?>" action="<?= $block->escapeUrl($postParams['action']) ?>" method="post">
                                                            <input 
                                                                type="hidden"
                                                                name="product"
                                                                value="<?= $block->escapeHtmlAttr($postParams['data']['product']) ?>"
                                                                >
                                                            <input type="hidden"
                                                                id="<?= $id.'_qty'?>"
                                                                name="qty"
                                                                value="qty"
                                                                >
                                                            <input 
                                                                type="hidden"
                                                                name="<?= Action::PARAM_NAME_URL_ENCODED ?>"
                                                                value="<?= $postParams['data'][Action::PARAM_NAME_URL_ENCODED] ?>"
                                                                >
                                                            <?= $block->getBlockHtml('formkey') ?>
                                                            <button type="submit"
                                                                    title="<?= $block->escapeHtml(__('Add to Cart')) ?>"
                                                                    class="action tocart primary">
                                                                <span><?= $block->escapeHtml(__('Add to Cart')) ?></span>
                                                            </button>
                                                        </form>
                                                    <?php else : ?>
                                                        <?php if ($_item->getIsSalable()) : ?>
                                                            <div class="stock available"><span><?= $block->escapeHtml(__('In stock')) ?></span></div>
                                                        <?php else : ?>
                                                            <div class="stock unavailable"><span><?= $block->escapeHtml(__('Out of stock')) ?></span></div>
                                                        <?php endif; ?>
                                                    <?php endif; ?>
                                                </div>
                                            <?php endif; ?>
                                            <?php if ($showWishlist || $showCompare) : ?>
                                                <div class="actions-secondary" data-role="add-to-links">
                                                    <?php if ($this->helper(\Magento\Wishlist\Helper\Data::class)->isAllow() && $showWishlist) : ?>
                                                        <a href="#"
                                                           data-post='<?= $block->getAddToWishlistParams($_item) ?>' class="action towishlist" data-action="add-to-wishlist" title="<?= $block->escapeHtmlAttr(__('Add to Wish List')) ?>">
                                                            <span><?= $block->escapeHtml(__('Add to Wish List')) ?></span>
                                                        </a>
                                                    <?php endif; ?>
                                                    <?php if ($block->getAddToCompareUrl() && $showCompare) : ?>
                                                        <?php $compareHelper = $this->helper(\Magento\Catalog\Helper\Product\Compare::class);?>
                                                        <a href="#" class="action tocompare" data-post='<?= $compareHelper->getPostDataParams($_item) ?>' title="<?= $block->escapeHtmlAttr(__('Add to Compare')) ?>">
                                                            <span><?= $block->escapeHtml(__('Add to Compare')) ?></span>
                                                        </a>
                                                    <?php endif; ?>
                                                </div>
                                            <?php endif; ?>
                                        </div>
                                    </div>
                                <?php endif; ?>
                            </div>
                        </div>
                        <?= ($iterator == count($items) + 1) ? '</li>' : '' ?>
                    <?php endforeach ?>
                </ol>
            </div>
            <?= $block->getPagerHtml() ?>
        </div>
    </div>
<?php endif;?>
5
  • then you have to get stock quantity based in product ids and add to this template Mar 10, 2021 at 12:47
  • Need to create an extension ? or i just need to create these files and folders ? Kindly explain me little more. Thanks Mar 10, 2021 at 12:52
  • you can try it in existing extension also.just create files and folders Mar 10, 2021 at 12:54
  • i am confusing about 3rd point, where i'll create this template ? Please Mar 10, 2021 at 13:05
  • path is mentioned after step 3 Mar 10, 2021 at 13:06
0

This worked for me on a 2.4.0 store

https://github.com/tuyennn/magento2-outofstockatlast

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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