4

I need to show category tree, just like in admin section, in my custom page. I viewed this solution in magento.stackexchange.com. It was good but limited to 2 levels of category. I need all the categories. How can it be done?

1

4 Answers 4

9

I searched over internet for solution to this but got nothing useful. Then I diverted my research towards Magento core where I found \Magento\Catalog\Block\Adminhtml\Category\Tree class where I found a function getTree(). Then I tried to observed it's return value in my custom template file. The effort became fruitful as I got the desired result.

I created a block file where I have injected the above class as:

<?php
namespace Vendor\Module\Block;

class CategoriesColle extends \Magento\Framework\View\Element\Template
{

    ...
    protected $adminCategoryTree;

    /**
     * @param \Magento\Framework\View\Element\Template\Context $context
     * @param \Magento\Catalog\Helper\Category $categoryHelper
     * @param array $data
     */
    public function __construct(

       ...
        \Magento\Catalog\Block\Adminhtml\Category\Tree $adminCategoryTree

    )
    {
        ...
        $this->adminCategoryTree = $adminCategoryTree;

    }
    public function getTree()
    {
        return $this->adminCategoryTree->getTree(); 
    }
...

}

The return value of the getTree() is the desired array of the category tree which can be verified by dumping the value in template file.

2
  • how can use it in .phtml file ?
    – HaFiz Umer
    Jul 10, 2019 at 15:54
  • you can use in layout by block class="vendor/module/block/CategoriesColle" template="Vendor_Module:yourcustomphtml.phtml" Jul 19, 2019 at 6:33
0

You can create your own tree with custom collection as follows: Firstly add a field in your ui-form:

<field name="custom" component="Namespce_Modulename/js/select-category" sortOrder="20" formElement="select">
<argument name="data" xsi:type="array">
    <item name="config" xsi:type="array">
        <item name="filterOptions" xsi:type="boolean">true</item>//to add filter in select-ui
        <item name="multiple" xsi:type="boolean">false</item>//select multiple or not
        <item name="showCheckbox" xsi:type="boolean">true</item>//to show checkboxes
        <item name="disableLabel" xsi:type="boolean">true</item>
    </item>
</argument>
<settings>
    <required>true</required>
    <validation>
        <rule name="required-entry" xsi:type="boolean">true</rule>
    </validation>
    <elementTmpl>ui/grid/filters/elements/ui-select</elementTmpl>
    <label translate="true">Select Category</label>//label to Field
    <dataScope>data.custom</dataScope>//To map
    <componentType>field</componentType>
    <listens>
        <link name="${ $.namespace }.${ $.namespace }:responseData">setParsed</link>
    </listens>
</settings>
<formElements>
    <select>
        <settings>
            <options class="Namespace\ModuleName\Ui\Component\Form\Category\Options"/>
        </settings>
    </select>
</formElements>

Now create Js file to map the field's value:

Namespace_Modulename/view/adminhtml/web/js/select-category.js

define([
'Magento_Ui/js/form/element/ui-select'
], function (Select) {
'use strict';
return Select.extend({
    /**
     * Parse data and set it to options.
     *
     * @param {Object} data - Response data object.
     * @returns {Object}
     */
    setParsed: function (data) {
        var option = this.parseData(data);
        if (data.error) {
            return this;
        }
        this.options([]);
        this.setOption(option);
        this.set('newOption', option);
    },
    /**
     * Normalize option object.
     *
     * @param {Object} data - Option object.
     * @returns {Object}
     */
    parseData: function (data) {
        return {
            value: data.category.entity_id,
            label: data.category.name
        };
    }
});
});

Create a file to get options to display:

Namespace\ModuleName\Ui\Component\Form\Category\Options.php

<?php
namespace Namespace\ModuleName\Ui\Component\Form\Category;

use Magento\Framework\Data\OptionSourceInterface;
use Magento\Category\Model\ResourceModel\Category\CollectionFactory as      CategoryCollectionFactory;
use Magento\Framework\App\RequestInterface;

/**
* Options tree for "Categories" field
*/
class Options implements OptionSourceInterface
{

protected $categoryCollectionFactory;

/**
 * @var RequestInterface
 */
protected $request;

/**
 * @var array
 */
protected $categoryTree;

/**
 * @param CategoryCollectionFactory $categoryCollectionFactory
 * @param RequestInterface $request
 */
public function __construct(
    CategoryCollectionFactory $categoryCollectionFactory,
    RequestInterface $request
) {
    $this->categoryCollectionFactory = $categoryCollectionFactory;
    $this->request = $request;
}

/**
 * {@inheritdoc}
 */
public function toOptionArray()
{
    return $this->getCategoryTree();
}

/**
 * Retrieve categories tree
 *
 * @return array
 */
protected function getCategoryTree()
{
    if ($this->categoryTree === null) {
        $collection = $this->categoryCollectionFactory->create();

        $collection->addNameToSelect();

        foreach ($collection as $category) {
            $categoryId = $category->getEntityId();
            if (!isset($categoryById[$categoryId])) {
                $categoryById[$categoryId] = [
                    'value' => $categoryId
                ];
            }
            $categoryById[$categoryId]['label'] = $category->getName();
        }
        $this->categoryTree = $categoryById;
    }
    return $this->categoryTree;
}

}

Hope it helps!

3
0
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
                //$category = $objectManager->create('Magento\Catalog\Model\Category')
                //Magento\Customer\Model\ResourceModel\Customer\CollectionFactory
                $category = $objectManager->create('Magento\Catalog\Model\ResourceModel\Category\CollectionFactory')->create()
                    ->addAttributeToSelect('entity_id')
                    ->addAttributeToSelect('name')
                    ->addAttributeToSelect('parent_id')
                    ->addAttributeToSelect('url_path')
                    ->addAttributeToSelect('request_path')
                    ->addAttributeToSelect('include_in_menu')
                    //->addAttributeToSelect('*')
                    ->addAttributeToFilter('level',array('nin' => array(1)))
                    ->addAttributeToFilter('path',array('like' => '%'.$rootCategoryId.'%'))
                    ->addAttributeToSort('parent_id', 'ASC')
                    ->addAttributeToSort('position', 'ASC')
                    ->addAttributeToSort('path', 'ASC');
            
                // print_r($category->getData());
                $catArray = [];
                foreach ($category as $cat){
                    $catArray[$cat->getID()]['id']= $cat->getID();
                    $catArray[$cat->getID()]['name'] = $cat->getName();
                    $catArray[$cat->getID()]['parent_id'] = $cat->getParentId();
                    $catArray[$cat->getID()]['position'] = $cat->getPosition();
                    $catArray[$cat->getID()]['path'] = $cat->getPath();
                }
                print_r($catArray);
0
// Get all the children categories of given category collection factory
foreach ($collection as $key => $value) {
            $temp = $value->getData();
            $categoryObj = $this->_repository->get($temp['entity_id']);
            $subcategories = $categoryObj->getChildrenCategories();
            foreach($subcategories as $key2 => $subcategory) {
                if($subcategory->hasChildren()) {
                    $childCategoryObj = $this->_repository->get($subcategory->getId());
                    $childSubcategories = $childCategoryObj->getChildrenCategories();
                    foreach($childSubcategories as $childSubcategory) {
                        $temp2 = $childSubcategory->getData();
                        $temp1['children'][] = $temp2;
                    }
                    $temp['children'][] = $temp1;
                }
            }
            $item[$key][] = $temp;
        }
// Here you can get all the children upto 2 level in "item" variable
echo "<pre>";
print_r($item);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.