11

Added category selector in admin form using ui component. The category ids are saved into the db as comma separated values. Now I want to display that categories in my edit form. enter image description here

enter image description here This is my example_example_edit.xml file:

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="content">
            <uiComponent name="example_form"/>
        </referenceContainer>
    </body>
</page>

This is my example_form.xml

<?xml version="1.0" encoding="UTF-8"?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <argument name="data" xsi:type="array">
        <item name="js_config" xsi:type="array">
            <item name="provider" xsi:type="string">example_form.example_form_data_source</item>
            <item name="deps" xsi:type="string">example_form.example_form_data_source</item>
        </item>
        <item name="label" xsi:type="string" translate="true">example Information</item>
        <item name="config" xsi:type="array">
            <item name="dataScope" xsi:type="string">data</item>
            <item name="namespace" xsi:type="string">example_form</item>
        </item>
        <item name="template" xsi:type="string">templates/form/collapsible</item>
        <item name="buttons" xsi:type="array">
            <item name="save" xsi:type="string">Company\Module\Block\Adminhtml\Example\Edit\Button\Save</item>
            <item name="delete" xsi:type="string">Company\Module\Block\Adminhtml\Example\Edit\Button\Delete</item>
            <item name="back" xsi:type="string">Company\Module\Block\Adminhtml\Example\Edit\Button\Back</item>        
        </item>
    </argument>

    <dataSource name="example_form_data_source">
        <argument name="dataProvider" xsi:type="configurableObject">
            <argument name="class" xsi:type="string">Company\Module\Model\ResourceModel\Example\DataProvider</argument>
            <argument name="name" xsi:type="string">example_form_data_source</argument>
            <argument name="primaryFieldName" xsi:type="string">example_id</argument>
            <argument name="requestFieldName" xsi:type="string">example_id</argument>
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="submit_url" xsi:type="url" path="module/example/save"/>
                </item>
            </argument>
        </argument> 
        <argument name="data" xsi:type="array">
            <item name="js_config" xsi:type="array">
                <item name="component" xsi:type="string">Magento_Ui/js/form/provider</item>
            </item>
        </argument>
    </dataSource>

    <fieldset name="example_details">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="collapsible" xsi:type="boolean">true</item>
                <item name="label" xsi:type="string" translate="true">example [General]</item>
                <item name="sortOrder" xsi:type="number">10</item>
                <item name="openOnShow" xsi:type="boolean">true</item>
            </item>
        </argument>
        <field name="example_id">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="visible" xsi:type="boolean">false</item>
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="formElement" xsi:type="string">input</item>
                    <item name="source" xsi:type="string">label_id</item>
                </item>
            </argument>
        </field>
        <field name="title">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="label" xsi:type="string">Title</item>
                    <item name="visible" xsi:type="boolean">true</item>
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="disabled" xsi:type="boolean">false</item>
                    <item name="formElement" xsi:type="string">input</item>
                    <item name="source" xsi:type="string">title</item>
                    <item name="validation" xsi:type="array">
                        <item name="required-entry" xsi:type="boolean">true</item>
                    </item>
                </item>
            </argument>
        </field>
        <field name="status">
            <argument name="data" xsi:type="array">
                <item name="options" xsi:type="object">Company\Module\Model\Config\Source\Status</item>
                <item name="config" xsi:type="array">
                    <item name="label" xsi:type="string" translate="true">Status</item>
                    <item name="visible" xsi:type="boolean">true</item>
                    <item name="dataType" xsi:type="string">number</item>
                    <item name="formElement" xsi:type="string">select</item>
                    <item name="source" xsi:type="string">status</item>
                    <item name="dataScope" xsi:type="string">status</item>
                    <item name="validation" xsi:type="array">
                        <item name="required-entry" xsi:type="boolean">true</item>
                    </item>
                </item>
            </argument>
        </field>
<field name="category_ids">
            <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">Category</item>
                    <item name="componentType" xsi:type="string">field</item>
                    <item name="formElement" xsi:type="string">select</item>
                    <item name="visible" xsi:type="boolean">true</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="filterOptions" xsi:type="boolean">true</item>
                    <item name="showCheckbox" xsi:type="boolean">true</item>
                    <item name="disableLabel" xsi:type="boolean">true</item>
                    <item name="multiple" xsi:type="boolean">true</item>
                    <item name="levelsVisibility" xsi:type="number">1</item>
                    <item name="required" xsi:type="boolean">false</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>
    </fieldset> 

</form>

This is my DataProvider.php

<?php
namespace Company\Module\Model\ResourceModel\Example;

use Company\Module\Model\ResourceModel\Example\CollectionFactory;;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;  

class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider
{
    /**
     * @var array
     */
    protected $_loadedData;

    protected $storeManager;

    protected $scopeConfig;

    public function __construct(
        $name,
        $primaryFieldName,
        $requestFieldName,
        CollectionFactory $exampleCollectionFactory,
        StoreManagerInterface $storeManager,
        ScopeConfigInterface $scopeConfig,
        array $meta = [],
        array $data = []
    ) {
        $this->storeManager = $storeManager;
        $this->scopeConfig = $scopeConfig;
        $this->collection = $exampleCollectionFactory->create();
        parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
    }


    /**
    * Get data
    *
    * @return array
    */
    public function getData()
    {
        if (isset($this->_loadedData)) {
            return $this->_loadedData;
        }

    return $this->_loadedData;
    }
}
3

6 Answers 6

7
+50

In that case you need to modify getData function.

For edit category_ids value must be an array.Suppose category_ids value save in db as comma separated that means '7,9,22'. So when you edit this value should be [7,9,22].

/**
 * Get data
 *
 * @return array
 */
public function getData()
{
    if (isset($this->loadedData)) {
        return $this->loadedData;
    }

    $items = $this->collection->getItems();

    foreach ($items as $item) {
        $data = $item->getData();
        $data['category_ids'] = explode(',', $data['category_ids']);
        $result['example_details'] = $data;
        $this->loadedData[$item->getId()] = $result;
    }
    return $this->loadedData;
}
1
2

In Your example_form.xml for field category_ids

Change this

<item name="formElement" xsi:type="string">select</item>

To

<item name="formElement" xsi:type="string">multiselect</item>

Make sure you are getting values for field category_ids comma separated values magento will do the rest.

3
  • I have changed the code from 'select' to 'multiselect'. Still it is not working. Also the category ids are saved as comma separated values.
    – E.B
    Commented Jan 2, 2017 at 10:38
  • Possible that category_ids does not have a value. Please check if you are getting value for that field. Is the field name same in your db ?
    – Priyank
    Commented Jan 2, 2017 at 10:40
  • Yes,the value for the field is getting. The categories are selected in the dropdown as well. But the values are not displaying in the text field.
    – E.B
    Commented Jan 2, 2017 at 12:08
1

Do you have getSelected() method in your component js file

Magento_Catalog/js/components/new-category

If not then you will need to create it and return array with the labels.

getSelected: function () {
    var selected = this.value();
    if (selected && selected.indexOf(',') > -1) // split if contains comma only
        selected = selected.split(',');

    return this.cacheOptions.plain.filter(function (opt) {
        return _.isArray(selected) ?
            _.contains(selected, opt.value) :
        selected == opt.value;
    });
},

See vendor/magento/module-ui/view/base/web/js/form/element/ui-select.js

7
0

We need to convert the string to array using explode function, like below:

/* Get data
 * @return array
 */

public function getData()
{
    if (isset($this->loadedData)) {
        return $this->loadedData;
    }

    $items = $this->collection->getItems();

    foreach ($items as $item) {
        $data = $item->getData();
        $data['category_ids'] = explode(',', $data['category_ids']);
        $final_data['details'] = $data;
        $this->loadedData[$item->getId()] = $final_data['details'];
    }
    return $this->loadedData;
}
0

In latest this need some modification. I have also need the same but end of i found below solutions, So it will help to other which are looking for the same.

your xml file(ie.) :

view->adminhtml->ui_component->module_module_form.xml

<dataSource name="module_module_form_data_source">
        <argument name="dataProvider" xsi:type="configurableObject">
            <argument name="class" xsi:type="string">Company\Module\Model\Name\DataProvider</argument>
            <argument name="name" xsi:type="string">crossell_crossell_form_data_source</argument>
            <argument name="primaryFieldName" xsi:type="string">id</argument>
            <argument name="requestFieldName" xsi:type="string">id</argument>
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="submit_url" xsi:type="url" path="crossell/crossell/save"/>
                </item>
            </argument>
        </argument>
        <argument name="data" xsi:type="array">
            <item name="js_config" xsi:type="array">
                <item name="component" xsi:type="string">Magento_Ui/js/form/provider</item>
            </item>
        </argument>
    </dataSource>

<field name="category">
            <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">Co-related Category</item>
                    <item name="componentType" xsi:type="string">field</item>
                    <item name="formElement" xsi:type="string">select</item>
                    <item name="visible" xsi:type="boolean">true</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="filterOptions" xsi:type="boolean">true</item>
                    <item name="showCheckbox" xsi:type="boolean">true</item>
                    <item name="disableLabel" xsi:type="boolean">true</item>
                    <item name="multiple" xsi:type="boolean">true</item>
                    <item name="levelsVisibility" xsi:type="number">1</item>
                    <item name="required" xsi:type="boolean">false</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>

Now, Your DataProvider will be in:

Model->Name->DataProvider.php

<?php

namespace Company\Module\Model\Name;

use Magento\Framework\Api\Filter;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Ui\DataProvider\AbstractDataProvider;
use Magento\Ui\DataProvider\Modifier\PoolInterface;
use Company\Module\Model\ResourceModel\Name\CollectionFactory;

class DataProvider extends AbstractDataProvider
{
    /**
     * @var PoolInterface
     */
    protected $pool;
    /**
     * @var CollectionFactory
     */
    private $collectionFactory;
    /**
     * @var DataPersistorInterface
     */
    private $dataPersistor;

    /**
     * @param string $name
     * @param string $primaryFieldName
     * @param string $requestFieldName
     * @param CollectionFactory $collectionFactory
     * @param PoolInterface $pool
     * @param array $meta
     * @param array $data
     * @throws LocalizedException
     */
    public function __construct(
        $name,
        $primaryFieldName,
        $requestFieldName,
        CollectionFactory $collectionFactory,
        DataPersistorInterface $dataPersistor,
        PoolInterface $pool,
        array $meta = [],
        array $data = []
    ) {
        parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
        $this->collectionFactory = $collectionFactory->create();
        $this->pool         = $pool;
        $this->meta         = $this->prepareMeta($this->meta);
        $this->dataPersistor = $dataPersistor;
    }

    /**
     * Prepares Meta
     *
     * @param array $meta
     * @return array
     * @throws LocalizedException
     */
    public function prepareMeta(array $meta)
    {
        $meta = parent::getMeta();

        foreach ($this->pool->getModifiersInstances() as $modifier) {
            $meta = $modifier->modifyMeta($meta);
        }
        return $meta;
    }

    public function addFilter(Filter $filter){
        return null;
    }


    /**
     * @return array
     */
    public function getData()
    {
        if (isset($this->loadedData)) {
            return $this->loadedData;
        }
        $items = $this->collectionFactory->getItems();
        foreach ($items as $item) {
            $data = $item->getData();
            $data['category'] = explode(',', $data['category']);
            $this->loadedData[$item->getId()] = $data;
        }
        $data = $this->dataPersistor->get('name');
        if (!empty($data)) {
            $block = $this->collection->getNewEmptyItem();
            $block->setData($data);
            $this->loadedData[$block->getId()] = $block->getData();
            $this->dataPersistor->clear('crossell');
        }
        return $this->loadedData;
    }

}

Wokring fine for me & It looks like :

enter image description here

-1

You have to get the ids from Db and put selected when creating options

$selectedCat = explode(',', $categoryFromDb)
foreach ($category as $opt) {
    $sel = '';
    if (in_array($opt, $selectedCat)) {
    $sel = ' selected="selected" ';
    }
    echo '<option ' . $sel . ' value="' . $opt . '">' . $opt . '</option>';
}
3
  • The category field is created using ui component.
    – E.B
    Commented Jan 2, 2017 at 10:02
  • @E.B Please put your code to get proper answer according to your code. Commented Jan 2, 2017 at 10:05
  • Please see the updated code.
    – E.B
    Commented Jan 2, 2017 at 10:27

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.