I'm trying to populate a grid with data from DB. I've looked at other examples, tried appending _listing
to the xml that renders the grid, tried just about everything I can think of and still can't get it to work.
The full error I get is:
Fatal error: Call to undefined method Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider::addField() in Magento2/vendor/magento/module-ui/Component/Listing/Columns/Column.php on line 116
Magento\Ui\Component\Listing\Columns\Column->addFieldToSelect( )
calls addField()
which is not defined. Even if I define it (by extending AbstractDataProvider if I recall right) $this->getCollection()->addFieldToSelect($field, $alias);
throws an error. Because it can't get the collection. It's null. But digging and tinkering through the source code is of no use. I must've missed something and I have no idea what it might be.
I've seen modules with custom DataProvider classes, i.e. di.xml
has nothing to do with the dataSource
defined in the listing XML. I've tried that as well but without luck.
This is my grid(or listing, if you prefer) – so_grid.xml:
<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">so_grid.so_grid_data_source</item>
<item name="deps" xsi:type="string">so_grid.so_grid_data_source</item>
</item>
<item name="spinner" xsi:type="string">listing_columns</item>
<item name="buttons" xsi:type="array">
<item name="add" xsi:type="array">
<item name="name" xsi:type="string">add</item>
<item name="label" xsi:type="string" translate="true">Add New Item</item>
<item name="class" xsi:type="string">primary</item>
<item name="url" xsi:type="string">*/*/new</item>
</item>
</item>
</argument>
<!-- Data Source -->
<dataSource name="so_grid_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">TestDataProvider</argument>
<argument name="name" xsi:type="string">so_grid_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">entity_id</argument>
<argument name="requestFieldName" xsi:type="string">request_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>
</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">
<!-- Filters -->
<filters name="listing_filters">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="columnsProvider" xsi:type="string">so_grid.so_grid.listing_columns</item>
<item name="storageConfig" xsi:type="array">
<item name="provider" xsi:type="string">so_grid.so_grid.listing_top.bookmarks</item>
<item name="namespace" xsi:type="string">current.filters</item>
</item>
<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 name="childDefaults" xsi:type="array">
<item name="provider" xsi:type="string">so_grid.so_grid.listing_top.listing_filters</item>
<item name="imports" xsi:type="array">
<item name="visible" xsi:type="string">so_grid.so_grid.listing_columns.${ $.index }:visible</item>
</item>
</item>
</item>
<item name="observers" xsi:type="array">
<item name="column" xsi:type="string">column</item>
</item>
</argument>
</filters>
<!-- Paging -->
<paging name="listing_paging">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="storageConfig" xsi:type="array">
<item name="provider" xsi:type="string">so_grid.so_grid.listing_top.bookmarks</item>
<item name="namespace" xsi:type="string">current.paging</item>
</item>
<item name="selectProvider" xsi:type="string">so_grid.so_grid.listing_columns.ids</item>
</item>
</argument>
</paging>
</listingToolbar>
<!-- Columns -->
<columns name="listing_columns">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="storageConfig" xsi:type="array">
<item name="provider" xsi:type="string">so_grid.so_grid.listing_top.bookmarks</item>
<item name="namespace" xsi:type="string">current</item>
</item>
<item name="childDefaults" xsi:type="array">
<item name="storageConfig" xsi:type="array">
<item name="provider" xsi:type="string">so_grid.so_grid.listing_top.bookmarks</item>
<item name="root" xsi:type="string">columns.${ $.index }</item>
<item name="namespace" xsi:type="string">current.${ $.storageConfig.root}</item>
</item>
<item name="fieldAction" xsi:type="array">
<item name="provider" xsi:type="string">so_grid.so_grid.listing_columns.actions</item>
<item name="target" xsi:type="string">applyAction</item>
<item name="params" xsi:type="array">
<item name="0" xsi:type="string">edit</item>
<item name="1" xsi:type="string">${ $.$data.rowIndex }</item>
</item>
</item>
</item>
</item>
</argument>
<column name="name">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="add_field" xsi:type="boolean">true</item>
<item name="label" xsi:type="string" translate="true">Name</item>
<item name="sortOrder" xsi:type="number">30</item>
</item>
</argument>
</column>
</columns>
I have a working routing; the InstallSchema
ran fine; there's a model, resourceModel
and a collection
. Let me know if I you need me to provide the code for any of it.
Best Answer
I got it working! It turned out I was missing a lot of things(__constructors, di config, xml nodes for the grid/listing). Have a look at the code below.
Model:
ResourceModel:
Collection:
Grid:
di.xml:
so_grid.xml:
Probably I don't need all the code above to get the grid going. But still... I find all this relentless. So much stuff going around just to render a grid with data.