I want to add category tree structure in my custom module like Product Edit/Add.
2 Answers
You can add Category tree if you use UI form.
<field name="parent">
<argument name="data" xsi:type="array">
<item name="options" xsi:type="object">Magento\Catalog\Ui\Component\Product\Form\Categories\Options</item>
<item name="config" xsi:type="array">
<item name="label" xsi:type="string" translate="true">Parent Category</item>
<item name="componentType" xsi:type="string">field</item>
<item name="formElement" xsi:type="string">select</item>
<item name="component" xsi:type="string">Magento_Catalog/js/components/new-category</item>
<item name="elementTmpl" xsi:type="string">ui/grid/filters/elements/ui-select</item>
<item name="dataScope" xsi:type="string">data.parent</item>
<item name="filterOptions" xsi:type="boolean">true</item>
<item name="showCheckbox" xsi:type="boolean">false</item>
<item name="disableLabel" xsi:type="boolean">true</item>
<item name="multiple" xsi:type="boolean">false</item>
<item name="levelsVisibility" xsi:type="number">1</item>
<item name="sortOrder" xsi:type="number">20</item>
<item name="required" xsi:type="boolean">true</item>
<item name="validation" xsi:type="array">
<item name="required-entry" xsi:type="boolean">true</item>
</item>
<item name="listens" xsi:type="array">
<item name="${ $.namespace }.${ $.namespace }:responseData" xsi:type="string">setParsed</item>
</item>
</item>
</argument>
</field>
-
Hello @SaurabhJain, I have also added category tree , but how to save and get in edit form of category values? Commented Jul 13, 2017 at 6:34
-
you can save category in save controller like implode(',', $data['categoryfieldname']); and in edit mode you can explode in DataProvider file like $page->setCategoryfieldname(explode(',', $page->getCategoryfieldname())); Commented Jul 14, 2017 at 6:30
-
can we select multiple category at a one time in this category tree– AshnaCommented Aug 7, 2018 at 10:42
-
Yes you can select multiple category just pass “multiple “ is true. Ex. <item name=“multiple” >true<item> Commented Aug 8, 2018 at 16:36
-
Hello @SaurabhTaletiya, Is there anyway, we can use this in system configuration. Commented Aug 21, 2018 at 13:50
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!