0

I need a help ASAP related to sort by functionality in magento 2

1] I need to remove default sort by options.

2] I need to add my own sorting options.

I tried a custom module in which I have override the block file

vendor/magento/module-catalog/Block/Product/ProductList/Toolbar.php

In which I have override the setCollection() function

I have define custom options like:

class Toolbar extends \Magento\Catalog\Block\Product\ProductList\Toolbar {
  public function setCollection($collection) {
    $this->_collection = $collection;
    $this->_collection->setCurPage($this->getCurrentPage());
    $limit = (int) $this->getLimit();
    if ($limit) {
        $this->_collection->setPageSize($limit);
    }
    if ($this->getCurrentOrder()) {
        switch ($this->getCurrentOrder()) {
            case 'created_at_desc':                
                    $this->_collection
                            ->addAttributeToSort('name');
                            //->order('e.created_at ASC');
                break;
        case 'created_at_asc':
                    $this->_collection
                            ->addAttributeToSort('name');
                            //->order('e.created_at DESC');                
                break;
        case 'price_low_to_high':
                $this->_collection
                        ->addAttributeToSort('price');
                        //->order('price_index.price ASC');
                break;
        case 'price_high_to_low'://need to change
                $this->_collection
                        ->addAttributeToSort('price');                       
                break;
        case 'model'://need to change
                $this->_collection
                        ->getSelect()
                        ->joinLeft(
                                ['admin' => $collection->getTable('cataloginventory_stock_status')], 'e.entity_id = admin.product_id')->where('admin.stock_status = 1');
                break;
            case 'new_to_old':
                $this->_collection
                            ->getSelect()
                            ->order('e.created_at DESC');
                break;
            case 'old_to_new':
                $this->_collection
                            ->getSelect()
                            ->order('e.created_at ASC'); 
                break;
            default:
                $this->_collection->setOrder($this->getCurrentOrder(), $this->getCurrentDirection());
                break;
        }
    }
    return $this;
  }
}

I get the 'old_to_new' and 'new_to_old' code and its working fine, but need the other remaining following options too. I tries all possible options but can't get the result.

This are the following remaining options I need :

-created_at_desc--- name by asc(A-Z)

-created_at_asc--- name by desc(Z-A)

-price_low_to_high--- price low to high

-price_high_to_low--- price high to low

Thanks

2 Answers 2

8

You need to a custom extension with plugins, I followed this

app/code/Company/CustomSort/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">
  <type name="Magento\Catalog\Model\Config">
   <plugin name="Company_CustomSort::addCustomOptions" type="Company\CustomSort\Plugin\Model\Config" />
  </type>
  <type name="Magento\Catalog\Block\Product\ProductList\Toolbar">
   <plugin name="Company_CustomSort::addPriceDecendingFilterInToolbar" type="Company\CustomSort\Plugin\Product\ProductList\Toolbar" />
  </type>
</config>

Now we need to define our config labels and new options.

app/code/Company/CustomSort/Plugin/Model/Config.php

<?php
namespace Company\CustomSort\Plugin\Model;

class Config
{

/**
* Adding custom options and changing labels
*
* @param \Magento\Catalog\Model\Config $catalogConfig
* @param [] $options
* @return []
*/
public function afterGetAttributeUsedForSortByArray(\Magento\Catalog\Model\Config $catalogConfig, $options)
{

 //Remove specific default sorting options(if require)
 unset($options['position']);
 unset($options['name']);
 unset($options['price']);

 //Changing label(if require)
 $newOption['position'] = __('Any Thing');

 //New sorting options
 $newOption['price_desc'] = __('High to Low');
 $newOption['price_asc'] = __('Low to High');
 $newOption['created_at'] = __('New');

 //Merge default sorting options with new options
 $options = array_merge($newOption, $options);

 return $options;
 }
}

We declared all required options, now we need to implement these options and overwrite Magento default sorting method.

app/code/Company/CustomSort/Plugin/Product/ProductList/Toolbar.php

<?php
 namespace Company\CustomSort\Plugin\Product\ProductList;
 class Toolbar
 {
 /**
  * Plugin
  *
  * @param \Magento\Catalog\Block\Product\ProductList\Toolbar $subject
  * @param \Closure $proceed
  * @param \Magento\Framework\Data\Collection $collection
  * @return \Magento\Catalog\Block\Product\ProductList\Toolbar
  */
  public function aroundSetCollection(
    \Magento\Catalog\Block\Product\ProductList\Toolbar $toolbar,
    \Closure $proceed,
    $collection
  ) {
    $currentOrder = $toolbar->getCurrentOrder();
    $result = $proceed($collection);

    if ($currentOrder) {
        switch ($this->getCurrentOrder()) {

        case 'created_at':

            if ( $this->getCurrentDirection() == 'asc' ) {

                $this->_collection
                    ->getSelect()
                    ->order('e.created_at DESC');


            } elseif ( $this->getCurrentDirection() == 'desc' ) {

                $this->_collection
                    ->getSelect()
                    ->order('e.created_at ASC');

            }

            break;
        case 'price_desc':
                $this->_collection
                     ->getSelect()
                     ->setOrder('price', 'desc');
        case 'price_asc':
                $this->_collection
                     ->getSelect()
                     ->setOrder('price', 'asc');

        default:

            $this->_collection->setOrder($this->getCurrentOrder(), $this->getCurrentDirection());
            break;

    }
    }

    return $this;
 }
}

Now you need to run

php bin/magento setup:upgrade
and it should work like charm.

Happy coding.

3
  • I cannot seem to get this to work with 2.1.9 - is there somewhere it needs to be enabled in the backend? I've updated/dompiled/deployed, but not seeing anything.
    – dawhoo
    Oct 30, 2017 at 19:37
  • @dawhoo you need to setup module registration file too, for registering your module in system. Nov 1, 2017 at 8:20
  • Not working. Front end shows blank page. Mar 1, 2019 at 5:26
0

Paste the follwing code inside plugin/config.php

<?php
namespace ModuleName\VenderName\Plugin;

class Config
{

    const NEWEST_SORT_BY = 'newest';
    const OLDEST_SORT_BY = 'oldest';

    /**
     * Adding new sort option
     *
     * @param \Magento\Catalog\Model\Config $catalogConfig
     * @param [] $result
     * @return []
     */
    public function afterGetAttributeUsedForSortByArray(
        \Magento\Catalog\Model\Config $subject, 
        $result
    ) {
        unset($result['position']);
        unset($result['name']);
        unset($result['price']); 

        return array_merge(
            $result, 
            [
                self::NEWEST_SORT_BY => __('Newest'),
                self::OLDEST_SORT_BY => __('Oldest'),
                'position' => __('Position'),
                'name' => __('Name'),
                'price' => __('Price')
            ]
        );
    }
}

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.