Back to Top

Magento 2 Development 16: uiComponent and di.xml

Updated 7 March 2024

Magento uses grids to show tabular data, such as products, and customer lists. So we will use a similar admin grid to show our blogs list. Which will be created with the help of uiComponent.

As you know to manipulate the content of a page we use layout files in the front-end, similarly here also we need to create the layout file, which will be as view/adminhtml/layout/blogmanager_manage_index.xml

Code for view/adminhtml/layout/blogmanager_manage_index.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="blogmanager_blog_listing"/>
        </referenceContainer>
    </body>
</page>

Please note that we are creating the adminhtml folder inside the view folder. Here in the content container, we are inserting an uiComponent. If you recall on front-end we use to insert phtml file.

uiComponent

Basically with uiComponent, Magento allows us to create a nice user interface for lists, forms, etc. In laymen terms, we need to specify the structure of the component (that means form fields or table columns, etc) with xml and provide data for that component (prefill edit form or add rows to the list) with PHP. And Magento will take care of HTML, javascript required for that component.

Searching for an experienced
Magento 2 Company ?
Find out More

For the uiComponent, we need to create the ui_component folder inside the view/adminhtml folder. So our uiComponent file should be created as view/adminhtml/ui_component/blogmanager_blog_listing.xml

Code for view/adminhtml/ui_component/blogmanager_blog_listing.xml file

<?xml version="1.0" encoding="UTF-8"?>
<listing 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">blogmanager_blog_listing.blogmanager_blog_listing_data_source</item>
            <item name="deps" xsi:type="string">blogmanager_blog_listing.blogmanager_blog_listing_data_source</item>
        </item>
        <item name="spinner" xsi:type="string">blogmanager_blog_columns</item>
    </argument>
    <dataSource name="blogmanager_blog_listing_data_source">
        <argument name="dataProvider" xsi:type="configurableObject">
            <argument name="class" xsi:type="string">Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider</argument>
            <argument name="name" xsi:type="string">blogmanager_blog_listing_data_source</argument>
            <argument name="primaryFieldName" xsi:type="string">entity_id</argument>
            <argument name="requestFieldName" xsi:type="string">entity_id</argument>
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                <item name="update_url" xsi:type="url" path="mui/index/render"/>
                <item name="storageConfig" xsi:type="array">
                    <item name="indexField" xsi:type="string">entity_id</item>
                </item>
                </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/grid/provider</item>
            </item>
        </argument>
    </dataSource>
    <listingToolbar name="listing_top">
        <bookmark name="bookmarks"/>
        <columnsControls name="columns_controls"/>
        <filters name="listing_filters">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="templates" xsi:type="array">
                            <item name="filters" xsi:type="array">
                                <item name="select" xsi:type="array">
                                    <item name="component" xsi:type="string">Magento_Ui/js/form/element/ui-select</item>
                                    <item name="template" xsi:type="string">ui/grid/filters/elements/ui-select</item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
        </filters>
        <paging name="listing_paging"/>
    </listingToolbar>
    <columns name="blogmanager_blog_columns">
        <column name="entity_id">
            <settings>
                <filter>textRange</filter>
                <label translate="true">ID</label>
                <resizeDefaultWidth>25</resizeDefaultWidth>
            </settings>
        </column>
        <column name="user_id">
            <settings>
                <filter>text</filter>
                <label translate="true">User</label>
            </settings>
        </column>
        <column name="title">
            <settings>
                <filter>text</filter>
                <label translate="true">Title</label>
            </settings>
        </column>
        <column name="status">
            <settings>
                <filter>text</filter>
                <label translate="true">Status</label>
            </settings>
        </column>
        <column name="updated_at" component="Magento_Ui/js/grid/columns/date">
            <settings>
                <filter>dateRange</filter>
                <dataType>date</dataType>
                <label translate="true">Updated</label>
            </settings>
        </column>
        <column name="created_at" component="Magento_Ui/js/grid/columns/date">
            <settings>
                <filter>dateRange</filter>
                <dataType>date</dataType>
                <label translate="true">Created</label>
            </settings>
        </column>
    </columns>
</listing>

Do not get overwhelmed, we do not have to remember every line. Also, we will not cover what each line is doing because in most cases you will end up copy-pasting and changing the names according to your uiComponent name. Later when you need to do some customization in the grid then you can always check Magento’s dev doc to know about each tag and what they are doing.

The dataSource tag is to specify the data provider. The data provider is a class that is responsible for providing the data for the uiComponent. This tag has a name so that we can uniquely identify it and manipulate it. Here if you notice we have given Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider as the data provider class. It is the base or default data provider class. We will change the class with the help of a file called di.xml file.

listingToolbar tag

The listingToolbar tag is used to manage the toolbar you see at the top of the admin grid, which allows you to apply the filter, show or hide some columns and provide pagination. bookmark means that the applied filter, sorting, etc will be saved even if you reload or log out.

columns tag

The columns tag is used to manage the columns. To add a column we use the column tag. And we need to mention the table column name (that we used in the db_schema.xml file) in the name attribute. For each column, we can configure various things. Here we have configured whether the column is filterable and what type of filter it support (that means text search, range search for numeric fields, etc). By default, every column can be sorted but we can explicitly set sortable to false as shown in the status column. One thing you may have noticed is that for the updated_at and created_at columns I have provided a component attribute and the value for that attribute is a js file which will convert the date to a nice readable format.

Note that in some places in earlier versions, we used slightly different syntax, especially in the column tag. You will easily be able to interpret them when you see them because they are very similar.

di.xml

The di.xml file has many functionalities such as,

  • we can use it to rewrite/override a class.
  • we can use it to send new or replace the existing class arguments.
  • we can use it to create plugins to do some stuff before, after, and around a function.
  • we can use it to create a virtual sub-class.

We will see all of these as we move along this series. In this blog, I will teach you about type and virtualType. The type is used for changing the arguments of a class or to pass new arguments to that class. Whereas virtualType is used to create a virtual sub-class (which means we don’t have to create the .php file). Please google for more detail about type and virtual types.

The di.xml file can be created in,
a) etc folder (global).
b) etc/frontend folder (front-end area specific).
c) etc/adminhtml folder (admin area specific).

Now let’s come back to coding, we need to create the di file as etc/di.xml

Code for etc/di.xml file

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <virtualType name="Webkul\BlogManager\Model\ResourceModel\Blog\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
        <arguments>
            <argument name="mainTable" xsi:type="string">blogmanager_blog</argument>
            <argument name="resourceModel" xsi:type="string">Webkul\BlogManager\Model\ResourceModel\Blog</argument>
        </arguments>
    </virtualType>
    <type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
        <arguments>
            <argument name="collections" xsi:type="array">
                <item name="blogmanager_blog_listing_data_source" xsi:type="string">Webkul\BlogManager\Model\ResourceModel\Blog\Grid\Collection</item>
            </argument>
        </arguments>
    </type>
</config>

Here with the virtualType tag, we are creating a virtual class Webkul\BlogManager\Model\ResourceModel\Blog\Grid\Collection which is a subclass of Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult. And we have provided the mainTable and resourceModel argument for that class. mainTable is the table name and resourceModel is the resource model class related to that table.

type tag

With the type tag, we are adding our data provider to the collection of data providers. The Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory class has the collections of all data providers in the collections argument which is of type array. Here we have added our virtual class to that collections array. If you notice we have used the same name as we mentioned in the ui_component file as the dataSource name.

You can find both of these classes inside vendor/magento/framework/View/Element/UiComponent/DataProvider folder. In case you are curious to verify the arguments.

Now if you have done everything correctly you will be able to see the grid when you click on the menu,

2021-03-04_15-08

PS: Most of the time issues related to uiComponent are because of missing tags or some mistypes or mismatched names and Magento does not show any helpful error message if there is any issue in ui component. So please keep this in mind while coping uiComponent related codes.

Folder Structure,

Selection_117
Folder Structure

Next Blog -> Magento 2 Development 17: More about Admin Grid

Previous Blog -> Magento 2 Development 15: Admin Menu and Controller

. . .

Leave a Comment

Your email address will not be published. Required fields are marked*


Be the first to comment.

Back to Top

Message Sent!

If you have more details or questions, you can reply to the received confirmation email.

Back to Home