Well, turns out this behavior is a feature, not a bug.
In the multiselect attribute's Storefront Properties is a setting "Use in Layered Navigation". Two two choices cause the attribute to be used in layered navigation. These are:
- Filterable (with results)
- Filterable (no results)
Evidently, selecting "with results", means that in Navigation this attribute's filter only shows attribute values which, if selected as a filter, would change the list of products shown. So Magento hides that value if there are zero items having that value. But Magento also hides that value if all the currently shown products have that value.
So that may make it easier for the user to choose filter values which will definitely whittle down the list. However it hides from the user the attribute values that the shown items have, suggesting that the filtered items lack those attribute values.
In the example I gave in the question statement, the user would think that the two products have only Blue or Green color schemes, and be unaware that these are Red-Green and Red-Blue schemes.
At any rate, the "Filterable (no results)" option will result in the corresponding Layered Nav filter showing all allowed values and their product counts, whether the value corresponds to zero, some, or all currently shown items.
I have not discovered a happy medium setting where Magento would hide filter values with zero hits, but show all other values.
You should extend \Magento\Catalog\Model\Layer\Category or \Magento\Catalog\Model\Layer\Search class, like this:
In your etc/di.xml add:
...
<preference for="Magento\Catalog\Model\Layer\Category" type="[Vendor]\[Your_Extension]\Model\Override\Layer\Category" />
<type name="[Vendor]\[Your_Extension]\Model\Override\Layer\Category">
<arguments>
<argument name="context" xsi:type="object">Magento\Catalog\Model\Layer\Category\Context</argument>
</arguments>
</type>
...
Create your model with your new or overrided functions in [Vendor][Your_Extension]\Model\Override\Layer\Category:
<?php
namespace [Vendor]\[Your_Extension]\Model\Override\Layer;
use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Catalog\Model\ResourceModel;
class Category extends \Magento\Catalog\Model\Layer
{
/**
* @param $context
* @param StateFactory $layerStateFactory
* @param \Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory $attributeCollectionFactory
* @param \Magento\Catalog\Model\ResourceModel\Product $catalogProduct
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Magento\Framework\Registry $registry
* @param CategoryRepositoryInterface $categoryRepository
* @param array $data
*/
public function __construct(
\Magento\Catalog\Model\Layer\ContextInterface $context,
\Magento\Catalog\Model\Layer\StateFactory $layerStateFactory,
\Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory $attributeCollectionFactory,
\Magento\Catalog\Model\ResourceModel\Product $catalogProduct,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\Registry $registry,
CategoryRepositoryInterface $categoryRepository,
array $data = []
) {
parent::__construct(
$context,
$layerStateFactory,
$attributeCollectionFactory,
$catalogProduct,
$storeManager,
$registry,
$categoryRepository,
$data
);
}
public function newFunction($param1){
//Your code here
return $this;
}
}
Best Answer
First of all you need to create you own/custom theme.. inside your theme directory create folder Magento_LayeredNavigation (if not available already) inside this folder copy the all template file from core module
Magento\LayeredNavigation\view\frontend\templates
intoMagento_LayeredNavigation\template
.now you can override the layered navigation design and codes..
for multi-select you need to write the url, Sample url re-write method given as below you can customize it as per you requirement.
sample helper function given below..
where
$params = $this->getRequest()->getParams();
AND $filter is new/ old parameter name which you want make multiselect/select.
AND $value is the value you want for the parameter you passed..
AND $currentCatUrl current category url which you will get from registory.
call the above helper method in Magento_LayeredNavigation\template\view.phtml. Magento_LayeredNavigation\template\view.phtml is the file where you make the changes for layered navigation..
this will return the filter URL for both multiselect & sigle select.
update 1: formate example