Question

I have a custom resource model mapping to a table named soldiers_thewatcher_watch with a primary key: watch_id.

I added the Grid UI component as well as a controller and admin link, but when I access the view (/admin/thewatcher/grid/index/) the page is basically blank in admin (the admin page loads but there is no content within the content area). I've added 1 row of data directly in the database.

I likely have a typo somewhere, but have been looking through everything for hours and cannot find where the problem is. A lot of code to follow, sorry, any help is greatly appreciated.

Route:

app/code/Soldiers/Thewatcher/etc/adminhtml/routes.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="admin">
        <route id="thewatcher" frontName="thewatcher">
            <module name="Soldiers_Thewatcher"/>
        </route>
    </router>
</config>

Controller:

Soldiers/Thewatcher/Controller/Adminhtml/Grid/Index.php

  namespace Soldiers\Thewatcher\Controller\Adminhtml\Grid;

  class Index extends \Magento\Backend\App\Action
  {
    /**
    * @var \Magento\Framework\View\Result\PageFactory
    */
    protected $resultPageFactory;

    /**
     * Constructor
     *
     * @param \Magento\Backend\App\Action\Context $context
     * @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
     */
    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Framework\View\Result\PageFactory $resultPageFactory
    ) {
         parent::__construct($context);
         $this->resultPageFactory = $resultPageFactory;
    }

    /**
     * Load the page defined in **view/adminhtml/layout/exampleadminnewpage_helloworld_index.xml**
     *
     * @return \Magento\Framework\View\Result\Page
     */
    public function execute()
    {
         return  $resultPage = $this->resultPageFactory->create();
    }
  }

Layout:

Soldiers/Thewatcher/view/adminhtml/layout/soldiers_thewatcher_grid_index.xml

<?xml version="1.0"?>
<page>
<body>
<referenceContainer name="content">
    <uiComponent name="soldiers_thewatcher_watch_grid"/>
</referenceContainer>
</body>
</page>

Data Provider:

Soldiers/Thewatcher/Ui/Component/Listing/DataProviders/Soldiers/Thewatcher/Watch/Grid.php

<?php
namespace Soldiers\Thewatcher\Ui\Component\Listing\DataProviders\Soldiers\Thewatcher\Watch;


/**
 * Class Grid
 */
class Grid extends \Magento\Ui\DataProvider\AbstractDataProvider
{    
    public function __construct(
        $name,
        $primaryFieldName,
        $requestFieldName,
        \Soldiers\Thewatcher\Model\ResourceModel\Watch\CollectionFactory $collectionFactory,
        array $meta = [],
        array $data = []
    ) {
        parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
        $this->collection = $collectionFactory->create();
    }
}

Action Bar:

Soldiers/Thewatcher/Ui/Component/Listing/Column/Soldiersthewatcherwatchgrid/PageActions.php

<?php
namespace Soldiers\Thewatcher\Ui\Component\Listing\Column\Soldiersthewatcherwatchgrid;


/**
 * Class PageActions
 */
class PageActions extends \Magento\Ui\Component\Listing\Columns\Column
{
    public function prepareDataSource(array $dataSource)
    {
        if (isset($dataSource["data"]["items"])) {
            foreach ($dataSource["data"]["items"] as & $item) {
                $name = $this->getData("name");
                $id = "X";
                if(isset($item["watch_id"]))
                {
                    $id = $item["watch_id"];
                }
                $item[$name]["view"] = [
                    "href"=>$this->getContext()->getUrl(
                        "soldiers_thewatcher_watch_grid/watch/edit",["watch_id"=>$id]),
                    "label"=>__("Edit")
                ];
            }
        }

        return $dataSource;
    }    

}

Grid:

Soldiers/Thewatcher/view/adminhtml/ui_component/soldiers_thewatcher_watch_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="data" xsi:type="array">
        <item name="js_config" xsi:type="array">
            <item name="provider" xsi:type="string">soldiers_thewatcher_watch_grid.soldiers_thewatcher_watch_grid_data_source</item>
            <item name="deps" xsi:type="string">soldiers_thewatcher_watch_grid.soldiers_thewatcher_watch_grid_data_source</item>
        </item>
        <item name="spinner" xsi:type="string">soldiers_thewatcher_watch_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" xsi:type="string">Add New</item>
                <item name="class" xsi:type="string">primary</item>
                <item name="url" xsi:type="string">*/Watch/new</item>
            </item>
        </item>
    </argument>
    <dataSource name="soldiers_thewatcher_watch_grid_data_source">
        <argument name="dataProvider" xsi:type="configurableObject">
            <argument name="class" xsi:type="string">Soldiers\Thewatcher\Ui\Component\Listing\DataProviders\Soldiers\Thewatcher\Watch\Grid</argument>
            <argument name="name" xsi:type="string">soldiers_thewatcher_watch_grid_data_source</argument>
            <argument name="primaryFieldName" xsi:type="string">watch_id</argument>
            <argument name="requestFieldName" xsi:type="string">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">watch_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">
        <settings>
            <sticky>true</sticky>
        </settings>
        <paging name="listing_paging"/>
        <filters name="listing_filters"/>
    </listingToolbar>
    <columns name="soldiers_thewatcher_watch_grid_columns">
        <selectionsColumn name="ids">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="resizeEnabled" xsi:type="boolean">false</item>
                    <item name="resizeDefaultWidth" xsi:type="string">55</item>
                    <item name="indexField" xsi:type="string">watch_id</item>
                    <item name="sortOrder" xsi:type="number">10</item>
                </item>
            </argument>
        </selectionsColumn>
        <column name="watch_id">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">textRange</item>
                    <item name="sorting" xsi:type="string">asc</item>
                    <item name="label" xsi:type="string" translate="true">ID</item>
                </item>
            </argument>
        </column>
        <actionsColumn name="actions" class="Soldiers\Thewatcher\Ui\Component\Listing\Column\Soldiersthewatcherwatchgrid\PageActions">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="resizeEnabled" xsi:type="boolean">false</item>
                    <item name="resizeDefaultWidth" xsi:type="string">107</item>
                    <item name="indexField" xsi:type="string">watch_id</item>
                    <item name="sortOrder" xsi:type="number">200</item>
                </item>
            </argument>
        </actionsColumn>
    </columns>
</listing>

Resource Model (Collection)

Soldiers/Thewatcher/Model/ResourceModel/Watch/Collection.php

<?php
namespace Soldiers\Thewatcher\Model\ResourceModel\Watch;

/**
 * Class Collection
 */
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
    protected function _construct()
    {
        $this->_init('Soldiers\Thewatcher\Model\Watch','Soldiers\Thewatcher\Model\ResourceModel\Watch');
    }
}

Resource Model (Entity)

Soldiers/Thewatcher/Model/ResourceModel/Watch.php

<?php
namespace Soldiers\Thewatcher\Model\ResourceModel;

/**
 * Class Watch
 */
class Watch extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
    protected function _construct()
    {
        $this->_init('soldiers_thewatcher_watch','watch_id');
    }
}

Model

app/code/Soldiers/Thewatcher/Model/Watch.php

<?php
namespace Soldiers\Thewatcher\Model;

/**
 * Class Watch
 */
class Watch extends \Magento\Framework\Model\AbstractModel implements
    \Soldiers\Thewatcher\Api\Data\WatchInterface,
     \Magento\Framework\DataObject\IdentityInterface
{
    const CACHE_TAG = 'soldiers_thewatcher_watch';

    protected function _construct()
    {
        $this->_init('Soldiers\Thewatcher\Model\ResourceModel\Watch');
    }

    public function getIdentities()
    {
        return [self::CACHE_TAG . '_' . $this->getId()];
    }
}
Was it helpful?

Solution

I have Analysed the code you have shared there is no typo error.

The Reason for Admin Grid Page not showing/blank is because magento is not able to read your adminhtml layout file. As per your code the admin url for the grid is "http://yoursite.com/admin/thewatcher/grid/index".

Note:-

Your admin URL is thewatcher/grid/index magento will look for a layout xml file which matches the URL part and renders the output.

Your adminhtml layout file should be named as Soldiers/Thewatcher/view/adminhtml/layout/thewatcher_grid_index.xml

Currently your adminhtml layout file is named as

Soldiers/Thewatcher/view/adminhtml/layout/soldiers_thewatcher_grid_index.xml

Solution:- Rename your adminhtml layout file your Grid will be rendered

OTHER TIPS

you may try to update UI Component xml (Soldiers/Thewatcher/view/adminhtml/ui_component/soldiers_thewatcher_watch_grid.xml) as given below .

File : Soldiers/Thewatcher/view/adminhtml/ui_component/soldiers_thewatcher_watch_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">soldiers_thewatcher_watch_grid</argument>
    </argument>
    <argument name="data" xsi:type="array">
        <item name="js_config" xsi:type="array">
            <item name="provider" xsi:type="string">soldiers_thewatcher_watch_grid.soldiers_thewatcher_watch_grid_data_source</item>
            <item name="deps" xsi:type="string">soldiers_thewatcher_watch_grid.soldiers_thewatcher_watch_grid_data_source</item>
        </item>
        <item name="spinner" xsi:type="string">soldiers_thewatcher_watch_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" xsi:type="string">Add New</item>
                <item name="class" xsi:type="string">primary</item>
                <item name="url" xsi:type="string">*/Watch/new</item>
            </item>
        </item>
    </argument>
    <dataSource name="soldiers_thewatcher_watch_grid_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">soldiers_thewatcher_watch_grid_data_source</argument>
            <argument name="primaryFieldName" xsi:type="string">watch_id</argument>
            <argument name="requestFieldName" xsi:type="string">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">watch_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="soldiers_thewatcher_watch_grid_columns">
        <selectionsColumn name="ids">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="resizeEnabled" xsi:type="boolean">false</item>
                    <item name="resizeDefaultWidth" xsi:type="string">55</item>
                    <item name="indexField" xsi:type="string">watch_id</item>
                    <item name="sortOrder" xsi:type="number">10</item>
                </item>
            </argument>
        </selectionsColumn>
        <column name="watch_id">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">textRange</item>
                    <item name="sorting" xsi:type="string">asc</item>
                    <item name="label" xsi:type="string" translate="true">ID</item>
                </item>
            </argument>
        </column>
        <actionsColumn name="actions" class="Soldiers\Thewatcher\Ui\Component\Listing\Column\Soldiersthewatcherwatchgrid\PageActions">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="resizeEnabled" xsi:type="boolean">false</item>
                    <item name="resizeDefaultWidth" xsi:type="string">107</item>
                    <item name="indexField" xsi:type="string">watch_id</item>
                    <item name="sortOrder" xsi:type="number">200</item>
                </item>
            </argument>
        </actionsColumn>
    </columns>
</listing>
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top