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

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.

| improve this answer | |
  • 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 '17 at 19:37
  • @dawhoo you need to setup module registration file too, for registering your module in system. – Akhilesh Singh Nov 1 '17 at 8:20
  • Not working. Front end shows blank page. – Shoaib Saleem Mar 1 '19 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')
            ]
        );
    }
}
| improve this answer | |

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.