Adding a customization product filter on the product list

Adding a customization product filter on the product list

Some day, you has a request that add a default filter on category & search result page that always filter product match a condition such as “Style Jacket”.

Adding a customization filter on layered navigation of the category and search result page isn’t simple, Today I will provide you with how to do those things with  Default Magento and Customize the module Amasty Layered Navigation..

Part 1: Adding a custom filter on category page/search page with default Magento 2.

Firstly, You have to understand the design pattern filter: the document on TutorialsPoint <https://www.tutorialspoint.com/design_pattern/filter_pattern.htm>

  • Step 1: Create a module that sequence Magento_LayeredNavigation
  • Step 2: Create a plugin for adding a custom filter option.

File: app/code/Hidro/CustomFilter/etc/frontend/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\Layer\FilterList">
        <plugin name="hidro_plugin_layered_navigation_filter_list"
                type="Hidro\CustomFilter\Plugin\Layer\FilterList"
                sortOrder="1000"/>
    </type>
</config>
  • Step 3: Create the plugin class Hidro\CustomFilter\Plugin\Layer\FilterList

File : app/code/Hidro/CustomFilter/Layer/Filter/StyleFilter.php

<?php
namespace Hidro\CustomFilter\Plugin\Layer;

use Magento\Catalog\Model\Layer;
use Magento\Catalog\Model\Layer\Filter\FilterInterface;
use Magento\Framework\ObjectManagerInterface;
use Hidro\CustomFilter\Layer\Filter\StyleFilter;

class FilterList
{

    protected $objectManager;

    protected $customFilters = null;
    public function __construct(
        ObjectManagerInterface $objectManager
    ) {
        $this->objectManager = $objectManager;
    }

    /**
     * @param Layer $layer
     * @return FilterInterface[]
     */
    public function getCustomFilters($layer)
    {
        if(null === $this->customFilters) {
            $this->customFilters = [];
            $filter = $this->objectManager->create(
                StyleFilter::class,
                ['layer' => $layer]
            );
            $this->customFilters[] = $filter;
        }
        return $this->customFilters;
    }

    /**
     * @param \Magento\Catalog\Model\Layer\FilterList $subject
     * @param                                         $result
     * @param Layer                                   $layer
     */
    public function afterGetFilters(\Magento\Catalog\Model\Layer\FilterList $subject, $result, Layer $layer)
    {
        if(!isset($result['my_custom_filter'])) {
            $customFilters = $this->getCustomFilters($layer);
            $result = array_merge_recursive($result, $customFilters);
        }
        return $result;
    }
}
  • Step 4: Create a filter model for the custom filter

File: app/code/Hidro/CustomFilter/Model/Layer/Filter/StyleFilter.php

<?php
namespace Hidro\CustomFilter\Model\Layer\Filter;

use Magento\Catalog\Model\Layer\Filter\AbstractFilter;
use Magento\Framework\App\RequestInterface;

class StyleFilter extends AbstractFilter
{
    public function apply(RequestInterface $request)
    {
        //Always add this filter to product list collection on Category.
        if ($this->canApply($request)) {
            //Add style jacket to filter
            //style_general is Style's attribute code
            //5544 is Style Jacket's option id.
            $this->getLayer()
                ->getProductCollection()
                ->addFieldToFilter('style_general', 5544);

            //Add this filter to state
            //Comment this line remove the this filter on state.
            $this->getLayer()->getState()->addFilter($this->_createItem($this->getOptionText(null), 5544, 0));
        }
        return $this;
    }

    public function getName()
    {
        //Filter name on state
        return __('Filter name');
    }

    public function getOptionText($optionId)
    {
        //Filter value on state
        return 'Option text';
    }

    /**
     * @return int
     */
    public function getItemsCount()
    {
        //Ignore the parent logic
        return 0;
    }

    /**
     * @param RequestInterface $request
     * @return bool
     */
    public function canApply($request)
    {
        //We will ignore the logic, if end-user filter the products by Style
        return !$request->getParam($this->getRequestVar());
    }
}
  • Step 5: Enable module and check the result

Before:

After:

Download Sample Module: https://github.com/hieuhidro/customfilter

Custom the filter with Amasty Navigation to be continued.

Thanks for reading and have a good day.

Leave a Reply

Your email address will not be published.