Magento 2 Development 13: uiComponent and di.xml

0

 

Magento usage grids to show tabular data, such as products, customers lists. So we will use similar admin grid to show our blogs list. Which will be created with uiComponent.

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

<?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 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 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.

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


<?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 is most of the cases you will end up copy pasting and changing the names according to your uiComponent name. Later when you need to do some customisation in the grid then you can always check the 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 which 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 base or default data provider class. We will change the class with help of a file called as di.xml file.

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

The columns tag is use to manage the columns. To add column we use the column tag. And we need to mention the tables’s column name (that we used in 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 does 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 status column. One thing you may have noticed that for the updated_at and created_at columns I have provided component attribute and value for that attribute is a js file which will convert the date to 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 it when you see because they are very similar.


di.xml

The di.xml file has many functionalities such as,

  • It can be used to rewrite/override a class.
  • It can be used to send new or replace the existing class arguments.
  • It can be used to create plugins to do some stuff before, after and around a function.
  • It can be used to create 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 arguments of class or to pass new arguments to that class. Whereas virtualType is used to create a virtual sub-class (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

<?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 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.

With 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 collections argument which is of type array. Here we have added our virtual class in that collections array. If you notice we have used the same name as we mentioned in the ui_component file as 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 issue related to ui component are because of missing tag or some mistypes or mismatched names and magento does not show any helpful error messsage, if there is any issue in ui component. So please keep in mind while coping ui component related codes.


Folder Structure,

2021-03-04_15-17


Post a Comment

0Comments
Post a Comment (0)
To Top