I'm trying to create some type of search method for customers where they select the product's brand they want to search and then, if they want, they can also select the category they want (if there are products from that brand in that category).
As you can see in the above image first we select brand, then we get that category dropdownlist all the categories (which have products), for that brand.
I'm doing this with 2 DropDownLists:
<div style="padding:30px 0 15px;">
<div class="container">
<div class="slider-with-side" style="margin: 0 -15px;">
<div class="slider-area" style="padding:0 15px;">
<div id="banner-slider-demo-7" class="owl-carousel owl-bottom-narrow owl-banner-carousel">
<div class="item">
<img src="" alt="" style="width: 100%;" />
</div>
<div class="item">
<img src="" alt="" style="width: 100%;" />
</div>
</div>
</div>
<div class="side-area" style="padding:0 15px;">
<div class="form-find-area theme-border-color">
<h3 class="form-title">Pesquisar</h3>
<form action="#" class="form-find">
<select name="home_manufacturers">
<option value="">Brand</option>
<option value="44" data-href="/catalogo?manufacturer=44">Dell</option>
<option value="51" data-href="/catalogo?manufacturer=51">Fujitsu-Siemens</option>
<option value="43" data-href="/catalogo?manufacturer=43">HP</option>
<option value="45" data-href="/catalogo?manufacturer=45">Lenovo</option>
</select>
<select name="home_categories" disabled="">
<option value="">Category</option>
</select>
<button type="button" id="form-find-submit" data-href="" disabled="">Submeter</button>
</form>
</div>
</div>
</div>
</div>
</div>
The method I want to use is an Ajax Post to the controller, which will retrieve the data I need. I'm using this script to handle and request the data:
<script>
require(['jquery', 'jquery/ui'], function($){
$("select[name=home_manufacturers]").change(function () {
$("#form-find-submit").attr('disabled', 'disabled');
$("select[name=home_categories]").attr('disabled', 'disabled');
var manufacturer = this.value;
var data_href = $('select[name=home_manufacturers] option:selected').data('href');
$.ajax({
showLoader: true,
url: '',
data: {
manufacturer: manufacturer
},
type: "POST",
dataType: 'json'
}).done(function (data) {
var html = '';
html += '<option value="">Por Categoria</option>';
for (var key in data) {
html += '<option value="' + key + '">' + data[key] + '</option>';
}
$("select[name=home_categories]").html(html);
$("select[name=home_categories]").removeAttr('disabled');
$("#form-find-submit").attr('data-href', data_href);
$("#form-find-submit").removeAttr('disabled');
});
});
$("select[name=home_categories]").change(function () {
$("#form-find-submit").attr('disabled', 'disabled');
var category = this.value;
var manufacturer = $("select[name=home_manufacturers]").val();
var manufacturer_name = $("select[name=home_manufacturers] option:selected").text();
manufacturer_name = manufacturer_name.split('-').join('');
manufacturer_name = manufacturer_name.split(' ').join('');
manufacturer_name = manufacturer_name.split('_').join('');
$.ajax({
showLoader: true,
url: '',
data: {
getUrl: 1,
category: category,
manufacturer: manufacturer
},
type: "POST",
dataType: 'json'
}).done(function (data) {
$("#form-find-submit").attr('data-href', data + '/' + manufacturer_name.toLowerCase() + '.html');
$("#form-find-submit").removeAttr('disabled');
});
});
$("#form-find-submit").click(function () {
window.location.href = $(this).data('href');
});
});
</script>
Controller:
<?php
namespace Tiago\Pronet\Controller\Home;
use \Magento\Framework\App\Action\Action;
use \Magento\Framework\Controller\ResultFactory;
use \Magento\Framework\App\Action\Context;
class Display extends \Magento\Framework\App\Action\Action
{
//protected $_pageFactory;
private $layerResolver;
protected $request;
protected $collectionFactory;
protected $_categoryFactory;
protected $_categoryCollectionFactory;
protected $_productRepository;
protected $resultJsonFactory;
public function __construct(
\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $collectionFactory,
\Magento\Catalog\Model\ProductFactory $productFactory,
\Magento\Framework\App\Action\Context $context,
\Magento\Catalog\Model\Layer\Resolver $layerResolver,
\Magento\Framework\Controller\ResultFactory $resultJsonFactory,
\Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory,
\Magento\Catalog\Model\CategoryFactory $categoryFactory,
\Magento\Catalog\Model\ProductRepository $productRepository)
{
$this->collectionFactory = $collectionFactory;
$this->layerResolver = $layerResolver;
$this->_categoryCollectionFactory = $categoryCollectionFactory;
$this->_productRepository = $productRepository;
//$this->_pageFactory = $pageFactory;
$this->resultJsonFactory = $resultJsonFactory;
$this->_categoryFactory = $categoryFactory;
$this->_productFactory = $productFactory;
parent::__construct($context);
}
public function execute()
{
$response = array();
//$brand = $this->getRequest()->getParam('manufacturer');
$brand = $this->getRequest()->getPost('manufacturer');
$resultJson = $this->resultJsonFactory->create(ResultFactory::TYPE_JSON);
$productCollection = $this->getProductCollection($brand);
$categoryCollection = $this->getCategoryCollection();
foreach($productCollection as $product){
$cats = $this->getProductCategoriesId($product->getData('entity_id')); //gets products cats id
foreach($categoryCollection as $category){
foreach($cats as $catstring){
if(strcmp($category->getData('entity_id'), $catstring) == 0){
$name = $this->getCategoryName($category->getData('entity_id'));
$response += array($category->getData('entity_id') => $name);
}
}
}
}
if($this->getRequest()->getPost('getUrl') == 1){
$usedCategory = $this->getRequest()->getPost('category');
$filtered_colection = $this->getFilteredCollection($usedCategory);
$badCategories = $this->getBadCategories();
$categories = $this->getCategories($filtered_colection, $badCategories);
$categories = substr($categories, 0, -5);
return $resultJson->setData($categories);
}
$response = array_unique($response);
asort($response);
//json_encode($response);
return $resultJson->setData($response);
}
public function getBadCategories()
{
$bad_categories = "2";
return explode(',', str_replace(' ', '', $bad_categories));
}
public function getFilteredCollection($categoryIds)
{
$collection = $this->_categoryCollectionFactory->create();
$filtered_colection = $collection
->addFieldToSelect('*')
->addFieldToFilter(
'entity_id',
['in' => $categoryIds]
)
->setOrder('level', 'ASC')
->load();
return $filtered_colection;
}
public function getCategories($filtered_colection, $badCategories)
{
$categories = '';
foreach ($filtered_colection as $categoriesData) {
if (!in_array($categoriesData->getId(), $badCategories)) {
$categories .= $categoriesData->getUrl();
}
}
return $categories;
}
public function getProductCategoriesId($pid)
{
$product = $this->_productFactory->create()->load($pid); // $pid = Product_ID
$cats = $product->getCategoryIds();
return $cats;
}
public function getCategoryName($categoryId)
{
$category = $this->_categoryFactory->create()->load($categoryId);
$categoryName = $category->getName();
return $categoryName;
}
public function getCategoryUrl()
{
$category = $this->_categoryFactory->create()->load($categoryId);
$categoryName = $category->getName();
return $categoryName;
}
public function getProductCollection($brand)
{
// Use factory to create a new product collection
$productCollection = $this->collectionFactory->create();
/** Apply filters here */
$productCollection->addAttributeToSelect('*');
$productCollection->addAttributeToFilter('manufacturer', $brand);
return $productCollection;
}
public function getCategoryCollection($isActive = true, $level = false, $sortBy = false, $pageSize = false)
{
$collection = $this->_categoryCollectionFactory->create();
$collection->addAttributeToSelect('*');
$collection->addAttributeToFilter('level',3);
// select only active categories
if ($isActive) {
$collection->addIsActiveFilter();
}
// select categories of certain level
//$collection->addLevelFilter(3);
// sort categories by some value
if ($sortBy) {
$collection->addOrderField($sortBy);
}
// select certain number of categories
if ($pageSize) {
$collection->setPageSize($pageSize);
}
return $collection;
}
}
Edit: Working solution