Magento 2 – Applying Sorting and Sort Direction Together

magento2sorting

Is it possible to apply sorting option and direction at the same time, using sorting select box?

The sorting select box could have options like:

  • Price Asc
  • Price Desc
  • Position Asc
  • Position Desc
  • ..

Best Answer

You can follow the steps describe below to achieve this customization task.

I assume you are using a custom theme "Vendor_theme" .

step 1) create the file sorter.phtml

under

/app/design/frontend/Vendor/theme/Magento_Catalog/templates/product/list/toolbar

File : sorter.phtml

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

// @codingStandardsIgnoreFile

?>
<?php
/**
 * Product list toolbar
 *
 * @var $block \Magento\Catalog\Block\Product\ProductList\Toolbar
 */
use Magento\Catalog\Model\Product\ProductList\Toolbar;
$currentDirection = $block->getCurrentDirection();
?>
<div class="toolbar-sorter sorter">
    <label class="sorter-label" for="sorter"><?= /* @escapeNotVerified */ __('Sort By') ?></label>
    <select id="sorter" data-role="sorter" class="sorter-options">
        <?php foreach ($block->getAvailableOrders() as $_key => $_order): ?>
            <option value="<?= /* @escapeNotVerified */ $_key ?>&asc"
                <?php if ($block->isOrderCurrent($_key) && ($block->getCurrentDirection()=='asc' || $block->getCurrentDirection()=='' )): ?>
                    selected="selected"
                <?php endif; ?>
                >
                <?= $block->escapeHtml(__($_order)) ?> [ Asc ]
            </option>

            <option value="<?= /* @escapeNotVerified */ $_key ?>&desc"
                <?php if ($block->isOrderCurrent($_key) && $block->getCurrentDirection()=='desc'): ?>
                    selected="selected"
                <?php endif; ?>
                >
                <?= $block->escapeHtml(__($_order)) ?> [ Desc ]
            </option>


        <?php endforeach; ?>
    </select>
    <?php if ($block->getCurrentDirection() == 'desc'): ?>
        <a title="<?= /* @escapeNotVerified */ __('Set Ascending Direction') ?>" href="#" class="action sorter-action sort-desc" data-role="direction-switcher" data-value="asc">
            <span><?= /* @escapeNotVerified */ __('Set Ascending Direction') ?></span>
        </a>
    <?php else: ?>
        <a title="<?= /* @escapeNotVerified */ __('Set Descending Direction') ?>" href="#" class="action sorter-action sort-asc" data-role="direction-switcher" data-value="desc">
            <span><?= /* @escapeNotVerified */ __('Set Descending Direction') ?></span>
        </a>
    <?php endif; ?>
</div>

step 2: create the file requirejs-config.js

under

/app/design/frontend/Vendor/theme/Magento_Catalog

File : requirejs-config.js

var config = {
    config: {    
        mixins: {            
            'Magento_Catalog/js/product/list/toolbar': {'Magento_Catalog/js/product/list/toolbar-mixin': true},
        },        
    }
};

step 3: create the file toolbar-mixin.js under /app/design/frontend/Vendor/theme/Magento_Catalog/web/js/product/list

File: toolbar-mixin.js

define([
    'jquery',    
    'uiComponent'
], function($, Component) {
    'use strict'; 
    return function(target) {
    return $.widget('mage.productListToolbarForm', $.mage.productListToolbarForm, {        
        _processSelect: function (event) {
            var optionvalue =  event.currentTarget.options[event.currentTarget.selectedIndex].value;
            var optionvalueParts = optionvalue.split("&");
            this.mychangeUrl(
                event.data.paramName,
                optionvalueParts[0],
                event.data.default,
                optionvalueParts[1]
            );
          },
          mychangeUrl: function (paramName, paramValue, defaultValue,listdir) {
            var decode = window.decodeURIComponent,
                urlPaths = this.options.url.split('?'),
                baseUrl = urlPaths[0],
                urlParams = urlPaths[1] ? urlPaths[1].split('&') : [],
                paramData = {},
                parameters, i;

            for (i = 0; i < urlParams.length; i++) {
                parameters = urlParams[i].split('=');
                paramData[decode(parameters[0])] = parameters[1] !== undefined ?
                    decode(parameters[1].replace(/\+/g, '%20')) :
                    '';
            }
            paramData[paramName] = paramValue;
            console.log(paramData);

            if (paramValue == defaultValue) { //eslint-disable-line eqeqeq
                delete paramData[paramName];
            }            
            delete paramData['product_list_dir'];
            paramData = $.param(paramData);
            baseUrl = baseUrl + (paramData.length ? '?' + paramData : '');                        
            baseUrl = baseUrl + (paramData.length ? '&' + 'product_list_dir='+listdir : '?' + 'product_list_dir='+listdir);
            baseUrl= decodeURIComponent( baseUrl.replace(/\+/g, '%20'));            
            location.href = baseUrl;
        },         

    });
  }
});

step 4:: Run below commadn from Magento root to remove static files and cache.

sudo rm -rf var/view_preprocessed/*
sudo rm -rf var/pub/static/*
sudo rm -rf var/cache/*
sudo rm -rf var/generated
sudo rm -rf var/composer_home
sudo rm -rf var/page_cache
sudo rm -rf var/view_preprocessed
sudo rm -rf pub/static/frontend/*

enter image description here

Related Topic