Question

I'm trying to us the UI grid component to create a grid in the backend that displays information that's not from the database. So far I created the XML files, the controller and a custom data provider. The data provider is used to override some methods that would normally be used, and it just sends an array with dummy data.

This is my Controller file:

namespace MyVendor\LogViewer\Controller\Adminhtml\Index;

use Magento\Backend\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
use Magento\Backend\App\Action;

class Index extends Action
{
    const ADMIN_RESOURCE = 'MyVendor_LogViewer::mylogviewer';
    /**
     * @var PageFactory
     */
    protected $resultPageFactory;
    /**
     * @param Context $context
     * @param PageFactory $resultPageFactory
     */
    public function __construct(
        Context $context,
        PageFactory $resultPageFactory
    )
    {
        $this->resultPageFactory = $resultPageFactory;
        parent::__construct($context);
    }
    /**
     * Index action
     *
     * @return \Magento\Backend\Model\View\Result\Page
     */
    public function execute()
    {
        /** @var \Magento\Backend\Model\View\Result\Page $resultPage */
        $resultPage = $this->resultPageFactory->create();

        $resultPage->setActiveMenu('MyVendor_LogViewer::a_menu_item');
        $resultPage->addBreadcrumb(__('Log Viewer'), __('Log Viewer'));
        $resultPage->addBreadcrumb(__('Log Viewer'), __('Log Viewer'));
        $resultPage->getConfig()->getTitle()->prepend(__('Log Viewer'));

        return $resultPage;
    }
    /**
     * {@inheritdoc}
     */
    protected function _isAllowed()
    {
        return $this->_authorization->isAllowed(self::ADMIN_RESOURCE);
    }
}

This is the layout file which is displayed by the controller, it references the UI grid:

<?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="my_logviewer_grid"/>
        </referenceContainer>
    </body>
</page>

This is my view/adminhtml/ui_comonent/my_logviewer_grid.xml file, for the grid configuration:

<?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">my_logviewer_grid.my_logviewer_grid_data_source</item>
        </item>
    </argument>

    <settings>
        <spinner>my_logviewer_columns</spinner>
        <deps>
            <dep>my_logviewer_grid.my_logviewer_grid_data_source</dep>
        </deps>
    </settings>

    <dataSource name="my_logviewer_grid_data_source">
        <argument name="dataProvider" xsi:type="configurableObject">
            <argument name="class" xsi:type="string">MyVendor\LogViewer\Ui\DataProvider\LogsProvider</argument>
            <argument name="name" xsi:type="string">my_logviewer_grid_data_source</argument>
            <argument name="primaryFieldName" xsi:type="string">filename_id</argument>
            <argument name="requestFieldName" xsi:type="string">filename_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">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="sticky" xsi:type="boolean">true</item>
            </item>
        </argument>

        <filters name="listing_filters" displayArea="dataGridFilters">

            <settings>
                <dataScope>filters</dataScope>
                <childDefaults>
                    <param name="imports" xsi:type="array">
                        <item name="visible" xsi:type="string">my_logviewer_grid.my_logviewer_grid.listing_top.bookmarks:current.columns.${ $.index }.visible</item>
                    </param>
                    <param name="provider" xsi:type="string">my_logviewer_grid.my_logviewer_grid.listing_top.listing_filters</param>
                </childDefaults>
                <storageConfig>
                    <namespace>current.filters</namespace>
                    <provider>my_logviewer_grid.my_logviewer_grid.listing_top.bookmarks</provider>
                </storageConfig>
            </settings>

            <filterInput name="filename_id" provider="${ $.parentName }">
                <settings>
                    <label translate="true">Filename Id</label>
                    <dataScope>filename_id</dataScope>
                </settings>
            </filterInput>

        </filters>

        <paging name="listing_paging">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="selectProvider" xsi:type="string">my_logviewer_grid.my_logviewer_grid.my_logviewer_columns.ids</item>
                    <item name="storageConfig" xsi:type="array">
                        <item name="provider" xsi:type="string">my_logviewer_grid.my_logviewer_grid.listing_top.bookmarks</item>
                        <item name="namespace" xsi:type="string">current.paging</item>
                    </item>
                </item>
            </argument>
        </paging>

    </listingToolbar>

    <columns name="my_logviewer_columns">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="childDefaults" xsi:type="array">
                    <item name="fieldAction" xsi:type="array">
                        <item name="provider" xsi:type="string">my_logviewer_grid.my_logviewer_grid.my_logviewer_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 name="controlVisibility" xsi:type="boolean">true</item>
                    <item name="appendTo" xsi:type="string">my_logviewer_grid.my_logviewer_grid.listing_top.columns_controls</item>
                    <item name="storageConfig" xsi:type="array">
                        <item name="provider" xsi:type="string">my_logviewer_grid.my_logviewer_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>
            </item>
        </argument>
        <column name="filename_id">
            <argument name="data" xsi:type="array">
                <item name="js_config" xsi:type="array">
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/column</item>
                </item>
                <item name="config" xsi:type="array">
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="align" xsi:type="string">left</item>
                    <item name="label" xsi:type="string" translate="true">File name</item>
                    <item name="sortOrder" xsi:type="number">10</item>
                </item>
            </argument>
        </column>

        <column name="other_val">
            <argument name="data" xsi:type="array">
                <item name="js_config" xsi:type="array">
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/column</item>
                </item>
                <item name="config" xsi:type="array">
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="align" xsi:type="string">left</item>
                    <item name="label" xsi:type="string" translate="true">Other val</item>
                    <item name="sortOrder" xsi:type="number">10</item>
                </item>
            </argument>
        </column>

    </columns>
</listing>

Finally, here's my data provider, it's located in MyVendor/LogViewer/Ui/DataProvider/LogsProvider.php :

use Magento\Ui\DataProvider\AbstractDataProvider;
use Magento\Framework\App\Request\Http;

/**
 * Class ProductDataProvider
 */
class LogsProvider extends AbstractDataProvider
{

    /**
     * @var \Magento\Ui\DataProvider\AddFieldToCollectionInterface[]
     */
    protected $addFieldStrategies;

    /**
     * @var \Magento\Ui\DataProvider\AddFilterToCollectionInterface[]
     */
    protected $addFilterStrategies;

    /**
     * @var \Magento\Framework\App\Request\Http
     */
    protected $request;

    /**
     * Construct
     *
     * @param string $name
     * @param string $primaryFieldName
     * @param string $requestFieldName
     * @param array $meta
     * @param array $data
     */
    public function __construct(
        $name,
        $primaryFieldName,
        $requestFieldName,
        Http $request,
        array $meta = [],
        array $data = []
    ) {
        parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
        $this->request = $request;
    }

    /**
     * Get data
     *
     * @return array
     */
    public function getData()
    {
        $items = [
            ['filename_id' => "1", 'other_val' => 'dddd'],
            ['filename_id' => "2", 'other_val' => 'dddd'],
            ['filename_id' => "3", 'other_val' => 'dddd'],
            ['filename_id' => "4", 'other_val' => 'dddd'],
            ['filename_id' => "5", 'other_val' => 'dddd'],
            ['filename_id' => "6", 'other_val' => 'dddd'],
            ['filename_id' => "7", 'other_val' => 'dddd'],
            ['filename_id' => "8", 'other_val' => 'dddd'],
            ['filename_id' => "9", 'other_val' => 'dddd'],
            ['filename_id' => "10", 'other_val' => 'dddd'],
            ['filename_id' => "11", 'other_val' => 'dddd'],
            ['filename_id' => "12", 'other_val' => 'dddd'],
            ['filename_id' => "13", 'other_val' => 'dddd'],
            ['filename_id' => "14", 'other_val' => 'dddd'],
            ['filename_id' => "15", 'other_val' => 'dddd'],
            ['filename_id' => "16", 'other_val' => 'dddd'],
            ['filename_id' => "17", 'other_val' => 'dddd'],
            ['filename_id' => "18", 'other_val' => 'dddd'],
            ['filename_id' => "19", 'other_val' => 'dddd'],
            ['filename_id' => "20", 'other_val' => 'dddd'],
            ['filename_id' => "21", 'other_val' => 'dddd'],
            ['filename_id' => "22", 'other_val' => 'dddd'],
            ['filename_id' => "23", 'other_val' => 'dddd'],
            ['filename_id' => "24", 'other_val' => 'dddd'],
            ['filename_id' => "25", 'other_val' => 'dddd'],
            ['filename_id' => "26", 'other_val' => 'dddd'],
            ['filename_id' => "27", 'other_val' => 'dddd'],
        ];

        $pagesize = intval($this->request->getParam('paging')['pageSize']);
        $pageCurrent = intval($this->request->getParam('paging')['current']);
        $pageoffset = ($pageCurrent - 1)*$pagesize;

        return [
            'totalRecords' => count($items),
            'items' => array_slice($items,$pageoffset , $pageoffset+$pagesize),
        ];
    }

    // ###########################################

    public function setLimit($offset, $size)
    {
    }

    public function addOrder($field, $direction)
    {
    }

    public function addFilter(\Magento\Framework\Api\Filter $filter)
    {
    }
}

Basically what I'm doing with the dataprovider is overriding the "getData" function and just passing some random array, which should be displayed in the grid. I also have some logic in it to make it work with the pagination $_GET variables. Also, I'm overriding he "setLimit", "addOrder" and "addFilter" functions, this is just so the grid will work properly, as far as I can tell at least.

So, my problem now is that the pagination doesn't work properly. When I access the page with the grid, it displays it properly, with the "File name" and "Other val" columns, each having their proper value. It displays the first 20 items in that array. If I click the "Next" button in the pagination, that also works properly, it shows the next 7 items.

The problem arises when I click the "Back" button. The UI grid seems to have some sort of caching system, it doesn't make another ajax request when it has to show results that you've already seen before (I assume it loads the from somewhere in the knockout js viewmodel). So, when I click "back" it just shows me the 27th array item 20 times. The same thing happens if I switch the pagination from "20" per page to "30" per page, then switch it back to "20". This is what it looks like:

enter image description here

I'm not sure what's causing this or how to ge about fixing it. Any help would be greatly appreciated.

Was it helpful?

Solution

Try updating your grid xml with this:

<argument name="dataProvider" xsi:type="configurableObject">
    <argument name="class" xsi:type="string">MyVendor\LogViewer\Ui\DataProvider\LogsProvider</argument>
    <argument name="name" xsi:type="string">my_logviewer_grid_data_source</argument>
    <argument name="primaryFieldName" xsi:type="string">filename_id</argument>
    <argument name="requestFieldName" xsi:type="string">filename_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">filename_id</item>
            </item>
        </item>
    </argument>
</argument>
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top