Magento 2.2.5: explain about how the multi select “available_sort_by” get data

magento.stackexchange https://magento.stackexchange.com/questions/238037

  •  21-01-2021
  •  | 
  •  

سؤال

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;
    }
}
هل كانت مفيدة؟

المحلول

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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى magento.stackexchange
scroll top