This is the first CRUD module (called Sinapsis_Store, for code understanding) I am trying to write in Magento2. I have followed different ways for it, going step by step, trying to understand every new piece of code in module. This project is Magento 2.3.0 CE
I was able to get module Grid work using Blocks approach (very similar to Magento1). Next step was the Edit form, for that I followed UI Components approach & got it working in a short time, so I came back to the Grid part, but surely I am missing something (or lot of things). The grid page loads with no errors, but the page is stuck "Loading..."
This is my component for Edit form (very simple, just with one single field right now: name
)
app/code/Sinapsis/Store/view/adminhtml/ui_component/store_form.xml
<?xml version="1.0" encoding="UTF-8"?>
<form 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">store_form.store_form_data_source</item>
<item name="deps" xsi:type="string">store_form.store_form_data_source</item>
</item>
<item name="label" xsi:type="string" translate="true">Store Information</item>
<item name="config" xsi:type="array">
<item name="dataScope" xsi:type="string">data</item>
<item name="namespace" xsi:type="string">store_form</item>
</item>
<item name="template" xsi:type="string">templates/form/collapsible</item>
<item name="buttons" xsi:type="array">
<item name="back" xsi:type="string">Sinapsis\Store\Block\Adminhtml\Edit\BackButton</item>
<item name="delete" xsi:type="string">Sinapsis\Store\Block\Adminhtml\Edit\DeleteButton</item>
<item name="save" xsi:type="string">Sinapsis\Store\Block\Adminhtml\Edit\SaveButton</item>
<item name="save_and_continue" xsi:type="string">Sinapsis\Store\Block\Adminhtml\Edit\SaveAndContinueButton</item>
</item>
</argument>
<dataSource name="store_form_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">Sinapsis\Store\Model\DataProvider</argument>
<argument name="name" xsi:type="string">store_form_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">store_id</argument>
<argument name="requestFieldName" xsi:type="string">store_id</argument>
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="submit_url" path="*/*/save" xsi:type="url"/>
</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/form/provider</item>
</item>
</argument>
</dataSource>
<fieldset name="store_details">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="collapsible" xsi:type="boolean">false</item>
<item name="label" xsi:type="string" translate="true">Store Details</item>
<item name="sortOrder" xsi:type="number">20</item>
</item>
</argument>
<field name="name">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="dataType" xsi:type="string">text</item>
<item name="label" xsi:type="string" translate="true">Store Name</item>
<item name="formElement" xsi:type="string">input</item>
<item name="source" xsi:type="string">store</item>
<item name="dataScope" xsi:type="string">name</item>
</item>
</argument>
</field>
</fieldset>
</form>
The dataProvider class for this is very simple
app/code/Sinapsis/Store/Model/DataProvider.php
<?php
namespace Sinapsis\Store\Model;
use Sinapsis\Store\Model\ResourceModel\Store\CollectionFactory;
class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider
{
protected $_loadedData;
/**
* @param string $name
* @param string $primaryFieldName
* @param string $requestFieldName
* @param CollectionFactory $employeeCollectionFactory
* @param array $meta
* @param array $data
*/
public function __construct(
$name,
$primaryFieldName,
$requestFieldName,
CollectionFactory $collectionFactory,
array $meta = [],
array $data = []
) {
$this->collection = $collectionFactory->create();
parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
}
public function getData()
{
if (isset($this->_loadedData)) {
return $this->_loadedData;
}
$items = $this->collection->getItems();
foreach ($items as $store) {
$this->_loadedData[$store->getId()] = $store->getData();
}
return $this->_loadedData;
}
}
And here is the last try for Grid component... I have tried several ways for the dataProvider class, but none of them worked
app/code/Sinapsis/Store/view/adminhtml/ui_component/store_grid.xml
<?xml version="1.0" ?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<argument name="context" xsi:type="configurableObject">
<argument name="class" xsi:type="string">Magento\Framework\View\Element\UiComponent\Context</argument>
<argument name="namespace" xsi:type="string">store_grid</argument>
</argument>
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="config" xsi:type="array">
<item name="provider" xsi:type="string">store_grid.store_grid_listing_data_source</item>
</item>
<item name="deps" xsi:type="string">store_grid.store_grid_listing_data_source</item>
</item>
<item name="spinner" xsi:type="string">store_grid_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" translate="true" xsi:type="string">Add new store</item>
<item name="class" xsi:type="string">primary</item>
<item name="url" xsi:type="string">*/*/create</item>
</item>
</item>
</argument>
<dataSource name="store_grid_listing_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">Sinapsis\Store\Model\DataProvider</argument>
<argument name="name" xsi:type="string">store_grid_listing_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">store_id</argument>
<argument name="requestFieldName" xsi:type="string">store_id</argument>
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item>
<item name="update_url" xsi:type="url" path="mui/index/render"/>
<item name="storageConfig" xsi:type="array">
<item name="indexField" xsi:type="string">store_id</item>
</item>
</item>
</argument>
</argument>
</dataSource>
<listingToolbar name="listing_top">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="sticky" xsi:type="boolean">true</item>
</item>
</argument>
<bookmark name="bookmarks"/>
<columnsControls name="columns_controls"/>
<filters name="listing_filters"/>
<paging name="listing_paging"/>
</listingToolbar>
<columns name="store_grid_columns">
<selectionsColumn name="ids">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="indexField" xsi:type="string">store_id</item>
</item>
</argument>
</selectionsColumn>
<column name="store_id">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="label" translate="true" xsi:type="string">ID</item>
</item>
</argument>
</column>
<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="label" translate="true" xsi:type="string">Store Name</item>
</item>
</argument>
</column>
</columns>
</listing>
Reading this https://devdocs.magento.com/guides/v2.3/ui_comp_guide/concepts/ui_comp_data_source.html, and as you can see in the code my last try is using same class as the one I use in Edit form, as that class does extend \Magento\Ui\DataProvider\AbstractDataProvider so I added a getDataSourceData()
method
To make the data available in javascript, add a getDataSourceData() method to the UI component’s PHP class and return $this->getContext()->getDataProvider()->getData(). This will output the result of the data provider’s getData() method into the JSON that is sent to the browser along with the rest of the UI component’s configuration
But again, same result... grid is stuck "Loading..."
So, any tips? Maybe the problem is not in dataProvider, but in another piece of XML code in the component?