I was trying to create an admin grid in the adminhtml trying to learn how they function and work and I ran into an issue following this guide: Mageplaza. I've been trying to debug where the issue is and, to the best of my knowledge I found that the issue lies somewhere in the core files of my module which are:
- di.xml
- layout files (or their name)
- menu.xml
- routes.xml
And here is my code, I am sharing mine because, of course, I made adjustments to the naming of the fields and the database fields.
Request/Price/Controller/Adminhtml/Blog/Index.php
<?php
namespace Request\Price\Controller\Adminhtml\Blog;
use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
class Index extends Action
{
protected $resultPageFactory = false;
public function __construct(
Context $context,
PageFactory $resultPageFactory
)
{
parent::__construct($context);
$this->resultPageFactory = $resultPageFactory;
}
public function execute()
{
$resultPage = $this->resultPageFactory->create();
$resultPage->getConfig()->getTitle()->prepend((__('Posts')));
return $resultPage;
}
}
Request/Price/etc/adminhtml/menu.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd">
<menu>
<add id="Request_Price::menu"
title="Request Price" module="Request_Price"
sortOrder="10"
resource="Magento_Customer::customer"/>
<add id="Request_Price::menu_item"
title="Price Requests" module="Request_Price"
sortOrder="10" parent="Request_Price::menu"
action="request_price/create/index"
resource="Request_Price::menu_item"/>
</menu>
Request/Price/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="request_price" frontName="request_price">
<module name="Request_Price"/>
</route>
</router>
</config>
Request/Price/etc/di.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
<arguments>
<argument name="collections" xsi:type="array">
<item name="request_price_listing_data_source" xsi:type="string">
Request\Price\Model\ResourceModel\Price\Grid\Collection
</item>
</argument>
</arguments>
</type>
<virtualType name="Request\Price\Model\ResourceModel\Price\Grid\Collection"
type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
<arguments>
<argument name="mainTable" xsi:type="string">request_price</argument>
<argument name="resourceModel" xsi:type="string">Request\Price\Model\ResourceModel\Price</argument>
</arguments>
</virtualType>
</config>
Request/Price/Setup/InstallSchema.php
<?php
namespace Request\Price\Setup;
use Magento\Framework\DB\Adapter\AdapterInterface;
use Magento\Framework\DB\Ddl\Table;
use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Zend_Db_Exception;
class InstallSchema implements InstallSchemaInterface
{
/**
* @throws Zend_Db_Exception
*/
public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
{
$installer = $setup;
$installer->startSetup();
if (!$installer->tableExists('request_price')) {
$table = $installer->getConnection()->newTable(
$installer->getTable('request_price')
)
->addColumn(
'request_id',
Table::TYPE_INTEGER,
null,
[
'identity' => true,
'nullable' => false,
'primary' => true,
'unsigned' => true,
],
'Request'
)
->addColumn(
'username',
Table::TYPE_TEXT,
255,
['nullable' => false],
'username'
)
->addColumn(
'email',
Table::TYPE_TEXT,
255,
['nullable' => false],
'Email '
)
->addColumn(
'message_area',
Table::TYPE_TEXT,
500,
['nullable' => true],
'Message'
)
->addColumn(
'Name',
Table::TYPE_TEXT,
255,
['nullable' => false],
'Name'
)
->addColumn(
'created_at',
Table::TYPE_TIMESTAMP,
null,
['nullable' => false, 'default' => Table::TIMESTAMP_INIT],
'Created At'
)
->addColumn(
'status',
Table::TYPE_TEXT,
255,
['nullable' => false],
'status'
)
->setComment('Request Table');
$installer->getConnection()->createTable($table);
$installer->getConnection()->addIndex(
$installer->getTable('request_price'),
$setup->getIdxName(
$installer->getTable('request_price'),
['username', 'email', 'message_area', 'Name'],
AdapterInterface::INDEX_TYPE_FULLTEXT
),
['username', 'email', 'message_area', 'Name'],
AdapterInterface::INDEX_TYPE_FULLTEXT
);
}
$installer->endSetup();
}
}
But I keep getting this error every time I try to access my menu item in my debug.log
[2021-10-10 12:20:48] main.DEBUG: Request validation failed for action "Magento\Backend\Controller\Adminhtml\Index\Index\Interceptor" {"exception":"[object] (Magento\Framework\App\Request\InvalidRequestException(code: 0): Invalid request received at D:\Work\mag6\vendor\magento\module-backend\App\Request\BackendValidator.php:176)"} []
This is my file system, just in case I got the name of something wrong
And, this is what I see when I open the new grid
I Would appreciate your help, fellow Magento developers. Thanks in advance.
Edit 1: I found what was the issue, I named the layout file was named incorrectly so when I changed its name from request_price_post_index to request_price_blog_index the layout worked but unfortunately I get this new error when I open the new grid
Exception #0 (Magento\Framework\Exception\LocalizedException): The XML in file "D:/Work/mag6/app/code/Request/Price/view/adminhtml/ui_component/request_price_listing.xml" is invalid: Element 'argument': This element is not expected. Line: 39
Verify the XML and try again.
Exception #0 (Magento\Framework\Exception\LocalizedException): The XML in file "D:/Work/mag6/app/code/Request/Price/view/adminhtml/ui_component/request_price_listing.xml" is invalid: Element 'argument': This element is not expected. Line: 39
and the code for the ui_component is as follows:
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<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"/>
<filterSearch name="fulltext"/>
<filters name="listing_filters"/>
<massaction name="listing_massaction">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/grid/tree-massactions</item>
</item>
</argument>
<action name="delete">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="type" xsi:type="string">delete</item>
<item name="label" xsi:type="string" translate="true">Delete</item>
<item name="url" xsi:type="url" path="request_price/post/massDelete"/>
<item name="confirm" xsi:type="array">
<item name="title" xsi:type="string" translate="true">Delete Post</item>
<item name="message" xsi:type="string" translate="true">Are you sure you want to delete
selected items?
</item>
</item>
</item>
</argument>
</action>
</massaction>
<paging name="listing_paging"/>
<exportButton name="export_button"/>
</listingToolbar>
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="provider" xsi:type="string">
request_price_listing.request_price_listing_data_source
</item>
<item name="deps" xsi:type="string">
request_price_listing.request_price_listing_data_source
</item>
</item>
<item name="spinner" xsi:type="string">requestcoloumn</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 Post</item>
<item name="class" xsi:type="string">primary</item>
<item name="url" xsi:type="string">*/*/new</item>
</item>
</item>
</argument>
<dataSource name="request_price_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">request_price_listing_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">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">id</item>
</item>
</item>
</argument>
</argument>
</dataSource>
<columns name="requestcoloumn">
<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">id</item>
</item>
</argument>
</selectionsColumn>
<column name="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>
<!-- <column name="product_name">-->
<!-- <argument name="data" xsi:type="array">-->
<!-- <item name="config" xsi:type="array">-->
<!-- <item name="filter" xsi:type="string">text</item>-->
<!-- <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/column</item>-->
<!-- <item name="dataType" xsi:type="string">text</item>-->
<!-- <item name="label" xsi:type="string" translate="true">Product Name</item>-->
<!-- <item name="sortOrder" xsi:type="number">12</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="editor" xsi:type="array">
<item name="editorType" xsi:type="string">text</item>
<item name="validation" xsi:type="array">
<item name="required-entry" xsi:type="boolean">true</item>
</item>
</item>
<item name="label" xsi:type="string" translate="true">Name</item>
</item>
</argument>
</column>
<column name="created_at" class="Magento\Ui\Component\Listing\Columns\Date">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">dateRange</item>
<item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item>
<item name="dataType" xsi:type="string">date</item>
<item name="label" xsi:type="string" translate="true">Created</item>
</item>
</argument>
</column>
</columns>
</listing>