4

I'm looking for an explanation about how the multi-select "available_sort_by" get data.

Like you can see in the image below, they are using UI component to render this multi-select. And I don't understand how did they get the data.

I think they use "available_sort_by" column in somewhere. But I couldn't find them.

enter image description here

So here is the code:

C:\xampp\htdocs\magento\vendor\magento\module-catalog\view\adminhtml\ui_component\category_form.xml

<container name="available_sort_by_group" 

component="Magento_Ui/js/form/components/group" sortOrder="90">
            <argument name="data" xsi:type="array">
                <item name="type" xsi:type="string">group</item>
                <item name="config" xsi:type="array">
                    <item name="breakLine" xsi:type="boolean">true</item>
                    <item name="required" xsi:type="boolean">true</item>
                </item>
            </argument>
            <field name="available_sort_by" formElement="multiselect">
                <!--<argument name="data" xsi:type="array">-->
                    <!--<item name="config" xsi:type="array">-->
                        <!--<item name="source" xsi:type="string">category</item>-->
                    <!--</item>-->
                <!--</argument>-->
                <settings>
                    <additionalClasses>
                        <class name="admin__field-default">true</class>
                    </additionalClasses>
                    <label translate="true">Available Product Listing Sort By</label>
                </settings>
            </field>
            <field name="use_config.available_sort_by" formElement="checkbox">
                <settings>
                    <dataType>boolean</dataType>
                    <exports>
                        <link name="checked">ns = ${ $.ns }, index = available_sort_by :disabled</link>
                    </exports>
                </settings>
                <formElements>
                    <checkbox>
                        <settings>
                            <description translate="true">Use All</description>
                            <valueMap>
                                <map name="false" xsi:type="boolean">false</map>
                                <map name="true" xsi:type="boolean">true</map>
                            </valueMap>
                        </settings>
                    </checkbox>
                </formElements>
            </field>
        </container>



Thanks for reading. Have a good day :)

EDIT 1:

So i've try this query in mysql to search which table contain column "available_sort_by", but it return empty.

Here is the query:

SELECT DISTINCT TABLE_NAME 
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME IN ('available_sort_by')
AND TABLE_SCHEMA='magento';

My table named "magento".
And this is the correct query to find which table contain column "X". Because i've try it with my column named "banner_id", and it work perfectly.

EDIT 2:

So i have found some answer and related to it, i'm doing my multi select.
But i dont know why its not run into the toOptionArray() function. But it can go to the __construct() function.

So here is the code:

C:\xampp\htdocs\magento\app\code\Aht\BannerSlider\view\adminhtml\ui_component\banner_form.xml

<container name="banner_page_group" component="Magento_Ui/js/form/components/group" sortOrder="40">
        <argument name="data" xsi:type="array">
            <item name="type" xsi:type="string">group</item>
            <item name="options" xsi:type="object">Aht\BannerSlider\Model\Page\PageSource</item>
            <item name="config" xsi:type="array">
                <item name="breakLine" xsi:type="boolean">true</item>
                <item name="required" xsi:type="boolean">true</item>
            </item>
        </argument>
        <field name="banner_page" formElement="multiselect">
            <settings>
                <additionalClasses>
                    <class name="admin__field-default">true</class>
                </additionalClasses>
                <label translate="true">Banner Page</label>
            </settings>
        </field>
        <field name="use_config.banner_page" formElement="checkbox">
            <settings>
                <dataType>boolean</dataType>
                <exports>
                    <link name="checked">ns = ${ $.ns }, index = banner_page :disabled</link>
                </exports>
            </settings>
            <formElements>
                <checkbox>
                    <settings>
                        <description translate="true">Use All</description>
                        <valueMap>
                            <map name="false" xsi:type="boolean">false</map>
                            <map name="true" xsi:type="boolean">true</map>
                        </valueMap>
                    </settings>
                </checkbox>
            </formElements>
        </field>
    </container>

C:\xampp\htdocs\magento\app\code\Aht\BannerSlider\Model\Page\PageSource.php

<?php

namespace Aht\BannerSlider\Model\Page;

use Aht\BannerSlider\Model\ResourceModel\Page\CollectionFactory;

class PageSource implements \Magento\Framework\Data\OptionSourceInterface
{
//    protected $pageCollectionFactory;

//    public function __construct(CollectionFactory $pageCollectionFactory)
//    {
//        $this->pageCollectionFactory = $pageCollectionFactory;
//    }

    public function toOptionArray()
    {
        return [
            [
                'value' => '1',
                'label' => 'Default Level',
            ],
            [
                'value' => '2',
                'label' => 'Store Level',
            ],
        ];
    }

//    public function toOptionArray()
//    {
//        $page = $this->pageCollectionFactory->create();
//        $options = [];
//        foreach ($page as $rows) {
//            $options[] = [
//                'label' => $rows->getName(),
//                'value' => $rows->getId()
//            ];
//        }
//        return $options;
//    }
}

I've try both way, and try to debug with xdebug too, but it doesn't go to toOptionArray() function.

EDIT 3:

Solved: I've found the true answer, and this is the perfect code (i thing).

<container name="banner_page_group" component="Magento_Ui/js/form/components/group" sortOrder="40">
        <field name="banner_page">
            <argument name="data" xsi:type="array">
                <item name="type" xsi:type="string">group</item>
                <item name="config" xsi:type="array">
                    <item name="breakLine" xsi:type="boolean">true</item>
                    <item name="required" xsi:type="boolean">true</item>
                    <item name="formElement" xsi:type="string">multiselect</item>
                    <item name="label" xsi:type="string">Banner Page</item>
                    <item name="validation" xsi:type="array">
                        <item name="required-entry" xsi:type="boolean">true</item>
                    </item>
                </item>
                <item name="options" xsi:type="object">Aht\BannerSlider\Model\Page\PageSource</item>
            </argument>
        </field>

        <!--check box "use all"-->
        <field name="use_config.banner_page" formElement="checkbox">
            <settings>
                <dataType>boolean</dataType>
                <exports>
                    <link name="checked">ns = ${ $.ns }, index = banner_page :disabled</link>
                </exports>
            </settings>
            <formElements>
                <checkbox>
                    <settings>
                        <description translate="true">Use All</description>
                        <valueMap>
                            <map name="false" xsi:type="boolean">false</map>
                            <map name="true" xsi:type="boolean">true</map>
                        </valueMap>
                    </settings>
                </checkbox>
            </formElements>
        </field>
    </container>

<?php

namespace Aht\BannerSlider\Model\Page;

use Aht\BannerSlider\Model\ResourceModel\Page\CollectionFactory;

class PageSource implements \Magento\Framework\Option\ArrayInterface
{
    protected $pageCollectionFactory;

    public function __construct(CollectionFactory $pageCollectionFactory)
    {
        $this->pageCollectionFactory = $pageCollectionFactory;
    }

    public function toOptionArray()
    {
        $page = $this->pageCollectionFactory->create()->getData();
        $options = [];
        foreach ($page as $rows) {
            $options[] = [
                'label' => $rows['page_name'],
                'value' => $rows['id']
            ];
        }
        return $options;
    }
}
3

OKe. let me show you how to debug ui_component form. First, you must know what is: dataSource.

class \Magento\Catalog\Model\Category\DataProvider where was define form data to load.

enter image description here

Find out these functions.

1.:

vendor/magento/module-catalog/Model/Category/DataProvider::getMeta

2.: \Magento\Catalog\Model\Category\DataProvider::prepareMeta

3.: \Magento\Catalog\Model\Category\DataProvider::getAttributesMeta

If you want to modify MetaData of DataProvider you must create a plugin (recommend) |Overide (not recommend) to modify data before or after DataProvider send to UiComponentFactory

Then let resolve your problem. available_sort_by that is category attribute based EAV design you can't find the table has a column named available_sort_by. => Get it from eav_attribute => entity_type_id = 3 and attribute_code='available_sort_by'.

For EDIT 1: You are defined options in the container, please use field instead.

  • Thanks for reply, so how can i make a multi select have data like them? they use entity but i dont. I just want to make a simple multi select using my table. – fudu Aug 14 '18 at 4:24
  • Your question related with: magento.stackexchange.com/questions/205830/… – HoangHieu Aug 14 '18 at 5:11
  • Hi, may i ask why its not run into toOptionArray() function? I implements \Magento\Framework\Data\OptionSourceInterface just like what you said. Please help. Thanks you. I've updated the information in edit 2, please check – fudu Aug 14 '18 at 6:39
  • You are defined options in the container, please use field instead. – HoangHieu Aug 14 '18 at 7:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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