Question

I am looking solution to get a Category tree on a custom page and parallel a text box, where the admin user could add some text and in parallel, he can select multiple categories. After adding text and selecting categories, there should be a save button so he can save this data in a custom table.

Please suggest how this can I do, I am not getting any solution for the category tree.

If anybody has an idea, please share me to implement it.

Was it helpful?

Solution

You need to add this below code in your ui form XML file for add multi-select dropdown of category :

<!--
/**
 * Code standard by : RH
 */
-->
<field name="category_id">
    <argument name="data" xsi:type="array">
        <item name="options" xsi:type="object">Namespace\VendorName\Model\Source\CategoryTree</item>
        <item name="config" xsi:type="array">
            <item name="label" xsi:type="string" translate="true">Category Tree</item>
            <item name="componentType" xsi:type="string">field</item>
            <item name="formElement" xsi:type="string">multiselect</item>
            <item name="component" xsi:type="string">Magento_Ui/js/form/element/ui-select</item>
            <item name="elementTmpl" xsi:type="string">ui/grid/filters/elements/ui-select</item>
            <item name="dataScope" xsi:type="string">category_id</item>
            <item name="filterOptions" xsi:type="boolean">true</item>
            <item name="showCheckbox" xsi:type="boolean">true</item>
            <item name="disableLabel" xsi:type="boolean">true</item>
            <item name="sortOrder" xsi:type="number">70</item>
            <item name="multiple" xsi:type="boolean">true</item>
            <item name="levelsVisibility" xsi:type="number">0</item>
            <item name="required" xsi:type="boolean">true</item>
            <item name="source" xsi:type="string">sourceName</item>
            <item name="validation" xsi:type="array">
                <item name="required-entry" xsi:type="boolean">false</item>
            </item>
            <item name="listens" xsi:type="array">
                <item name="${ $.namespace }.${ $.namespace }:responseData" xsi:type="string">setParsed</item>
            </item>
        </item>
    </argument>
</field>

Then, Create CategoryTree.php file for set category tree options

app/code/Namespace/VendorName/Model/Source/CategoryTree.php

<?php

namespace Namespace\VendorName\Model\Source;

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

/**
 * Category Tree
 */
class CategoryTree implements OptionSourceInterface
{
    /**
     * @var CategoryCollectionFactory
     */
    protected $categoryCollectionFactory;

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

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

    /**
     * @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->getCategoriesTree();
    }

    /**
     * Get categories tree
     *
     * @return array
     */
    protected function getCategoriesTree()
    {
        if ($this->categoriesTree === null) {
            $storeId = $this->request->getParam('store');
            /* @var $categoryCollectionFactory \Magento\Catalog\Model\ResourceModel\Category\Collection */
            $categoryCollectionFactory = $this->categoryCollectionFactory->create();

            $categoryCollectionFactory->addAttributeToSelect('path')
                ->addAttributeToFilter('entity_id', ['neq' => CategoryModel::TREE_ROOT_ID])
                ->setStoreId($storeId);

            $shownCategoriesIds = [];

            /** @var \Magento\Catalog\Model\Category $category */
            foreach ($categoryCollectionFactory as $category) {
                foreach (explode('/', $category->getPath()) as $parentId) {
                    $shownCategoriesIds[$parentId] = 1;
                }
            }

            /* @var $collection \Magento\Catalog\Model\ResourceModel\Category\Collection */
            $collection = $this->categoryCollectionFactory->create();

            $collection->addAttributeToFilter('entity_id', ['in' => array_keys($shownCategoriesIds)])
                ->addAttributeToSelect(['name', 'is_active', 'parent_id'])
                ->setStoreId($storeId);

            $categoryById = [
                CategoryModel::TREE_ROOT_ID => [
                    'value' => CategoryModel::TREE_ROOT_ID
                ],
            ];
            foreach ($collection as $category) {
                if ( $category->getData('level') <= 2 ) {
                    foreach ([$category->getId(), $category->getParentId()] as $categoryId) {
                        if ( !isset($categoryById[$categoryId]) ) {
                            $categoryById[$categoryId] = ['value' => $categoryId];
                        }
                    }
                    $categoryById[$category->getId()]['is_active'] = $category->getIsActive();
                    $categoryById[$category->getId()]['label'] = $category->getName();
                    $categoryById[$category->getParentId()]['optgroup'][] = &$categoryById[$category->getId()];
                }
            }
            $this->categoriesTree = $categoryById[CategoryModel::TREE_ROOT_ID]['optgroup'];
        }

        return $this->categoriesTree;
    }
}

For more reference : Click Here

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top