Our Work
200+ Enterprises across globally trust KTree for their Web & Mobile application Development needs.See What We Do
Magento 2 creation of admin grid is quite different from Magento 1. In this article we will see how we can create Magento 2 admin grid. Admin Grids. As you are aware Magento 2 Grids are kind of table which lists the items of your database table and provide you some common features like sort, filter, delete, update item, etc.
The below diagram show roughly the activities involved in creating admin grid. Further in the Article these all are described in detail.
For the purpose of this article we will create simple Ticketing system admin grid which shows the support tickets created by customers (The next article covers where logged in customer can raise a ticket, and also see his previous created tickets in List)
The full source code can be downloaded from this Github link
https://github.com/KtreeOpenSource/Magento2Examples/tree/master/TicketingSystem
The full source code can be downloaded from this Github link
To create backend Admin grid we need to do the following activities
Please refer this article for Module Creation.
https://ktree.com/create-magento-2-module-custom.html
app
code
Ktree(Vendor)
TicketingSystem(Custom Module Name)
Block
Adminhtml/Module/Grid/Renderer/Action/UrlBuilder.php
Adminhtml/Tickets/Edit/Form.php
Adminhtml/Tickets/Add.php
Controller
Adminhtml/Tickets/Add.php
Adminhtml/Tickets/Index.php
Adminhtml/Tickets/Save.php
etc
adminhtml/menu.xml
adminhtml/routes.xml
di.xml
module.xml
Model
ResourceModel/Tickets/Collection.php
ResourceModel/Tickets.php
Source/Category.php
Source/Priority.php
Source/Status.php
Tickets.php
Setup
InstallSchema.php
Ui
Component/Listing/Column/Actions.php
Component/Listing/Column/Update.php
view
adminhtml/layout/ticketingsystem_tickets_add.xml
adminhtml/layout/ticketingsystem_tickets_index.xml
adminhtml/ui_component/ticketingsystem_tickets_listing.xml
registration.php
Through Admin Routes we can define, how our modules can be accessed. This can be done in two different ways, one as \admin another more specific name based on your module. Here we will go with the second approach. To do this we will
Since we want to have specific url, we will use specific route. We will create frontName as “ticketingsystem” for our module
File Location: app/code/Ktree/TicketingSystem/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="ticketingsystem" frontName="ticketingsystem">
<module name="Ktree_TicketingSystem" />
</route>
</router>
</config>
In node attributes id - type of the router and admin is for backend
node attributes id - unique identifier
node attributes name - _
FrontName - our module backend route name and its defines the first segment of admin url(it should unique).
Next step would be to add to Magento 2 Backend Menu. To add admin menu we need to define this in menu.xml file inside etc/admin.html
Below we are creating a “Ticketing System” parent menu and under it we are adding menu item “Manage Tickets”
File Location: app/code/Ktree/TicketingSystem/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="Ktree_TicketingSystem::ticketingsystem" title="Ticketing System" module="Ktree_TicketingSystem" sortOrder="51" resource="Ktree_TicketingSystem::ticketingsystem" />
<add id="Ktree_TicketingSystem::manage" title="Manage Tickets" module="Ktree_TicketingSystem" sortOrder="10" action="ticketingsystem/tickets/index" resource="Ktree_TicketingSystem::manage" parent="Ktree_TicketingSystem::ticketingsystem" />
</menu>
</config>
The node
id - Unique identifier and format should be {Vendor_ModuleName}::
{menu_description}
title - Admin menu bar text
module - which this menu is belong to
sortOrder - position of the menu
action - url and format should be {router_name}{controller_folder}{action_name}
resource - Using this we can define ACL rules.
parent - Id of parent menu
4.Create Controller
In this step we will create Controller and Action for “Manage Tickets” which we have defined in menu.xml, Step 3 (action="ticketingsystem/tickets/index"). Magento 2 Controller contains one or more files in Controller folder of module, it includes class of action type which contain execute() method. If we put in another way every URL in Magento 2 corresponds to a single controller file, and each controller file has a single execute method.
For our example we created Tickets controller and Index action inside Controller/Admin.html folder of module.
File Location:
app/code/Ktree/TicketingSystem/Controller/Adminhtml/Tickets/Index.php
<?php
namespace Ktree\TicketingSystem\Controller\Adminhtml\Tickets;
class Index extends \Magento\Backend\App\Action
{
protected $resultPageFactory = false;
public function __construct(\Magento\Backend\App\Action\Context $context, \Magento\Framework\View\Result\PageFactory $resultPageFactory)
{
parent::__construct($context);
$this->resultPageFactory = $resultPageFactory;
}
public function execute()
{
$resultPage = $this->resultPageFactory->create();
$resultPage->setActiveMenu('Ktree_TicketingSystem::tickets_manage');
$resultPage->getConfig()->getTitle()->prepend((__('Tickets')));
return $resultPage;
}
}
Our controller is rendering the page in execute method, this is how it happens.
We injected a “page factory” object via automatic constructor dependency injection in the __construct method.
\Magento\Backend\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $resultPageFactory
We Use that page factory object to create a page and Return the created page.
$resultPage = $this->resultPageFactory->create();
return $resultPage;
Since our module is running in the backend due to the automatic DI our resultPage returns result of type MagentoBackendModelViewResultPage
This step is similar to Magento 1, where we define Database schema or table structure. We create a file InstallSchema.php inside Setup folder of module.
File Location: app/code/Ktree/TicketingSystem/Setup/InstallSchema.php
<?php
namespace Ktree\TicketingSystem\Setup;
class InstallSchema implements \Magento\Framework\Setup\InstallSchemaInterface {
public function install(\Magento\Framework\Setup\SchemaSetupInterface $setup, \Magento\Framework\Setup\ModuleContextInterface $context) {
$installer = $setup;
$installer->startSetup();
if (!$installer->tableExists('ktree_ticketing_system')) {
$table = $installer->getConnection()->newTable($installer->getTable('ktree_ticketing_system'))->addColumn('id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, null, ['identity' => true, 'nullable' => false, 'primary' => true, 'unsigned' => true, ], 'Id')->addColumn('ticket_id', \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, 255, [], 'Ticket Id')
// Other Columns Download from Github link
->setComment('Ktree Ticketing System Table');
$installer->getConnection()->createTable($table);
}
$installer->endSetup();
}
}
After completing above step:
Run command “php bin/magento setup:upgrade” to create table. Validate if table is created or not in the DB
Note: If table is not created remove module entry from “setup_module” table and re-run “php bin/magento setup:upgrade”.
Now our Database table is created, our next step is to create model and other requisites for CRUD
Here we create our base model, in other words our ‘Tickets’ object is instantiated using this class.
File Location: app/code/Ktree/TicketingSystem/Model/Tickets.php
<?php
namespace Ktree\TicketingSystem\Model;
class Tickets extends \Magento\Framework\Model\AbstractModel implements \Magento\Framework\DataObject\IdentityInterface {
const CACHE_TAG = 'ktree_ticketingsystem_ticket';
protected $_cacheTag = 'ktree_ticketingsystem_ticket';
protected $_eventPrefix = 'ktree_ticketingsystem_ticket';
protected function _construct() {
$this->_init('Ktree\TicketingSystem\Model\ResourceModel\Tickets');
}
public function getIdentities() {
return [self::CACHE_TAG . '_' . $this->getId() ];
}
public function getDefaultValues() {
$values = [];
return $values;
}
}
$_eventPrefix - a prefix for events to be triggered
$_eventObject - a object name when access in event
$_cacheTag - a unique identifier for usage in caching
Next step is a resource model class, which actually contains the methods that will fetch the information from the database. Each CRUD model in Magento 2 has a corresponding resource model class.
File Location:app/code/Ktree/TicketingSystem/Model/ResourceModel/Tickets.php
<?php
namespace Ktree\TicketingSystem\Model\ResourceModel;
class Tickets extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb {
protected function _construct() {
$this->_init('ktree_ticketing_system', 'id');
}
Collections are also type of ResourceModel, but instead of single object they get multiple objects. A collection collects individual Models.
File Location:
app/code/Ktree/TicketingSystem/Model/ResourceModel/Tickets/Collection.php
<?php
namespace Ktree\TicketingSystem\Model\ResourceModel\Tickets;
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection {
protected $_idFieldName = 'id';
protected $_eventPrefix = 'ktree_ticketingsystem_ticket_collection';
protected $_eventObject = 'ticket_collection';
/**
* Define resource model
* @return void
*/
protectedfunction _construct() {
$this->_init('Ktree\TicketingSystem\Model\Tickets', 'Ktree\TicketingSystem\Model\ResourceModel\Tickets');
}
}
Factory design pattern is where instead of creating the object using ‘New’ Keyword, we create it using our ‘Own Class’, the main reason is being to avoid hard dependency and also to localize the logic for complex objects. In Magento 2 for each CRUD model there is corresponding factory class, with ‘Factory’ appended to CRUD Model name.
A new concept in the Magento 2 is UI Components, which helps in reusability of components, the basic idea behind is to allow us build more complex UI components reusing smaller components
In this step we will define the data provider which is the Ticket collection class, table and resourceModel for the table. This source is used in our next step Layout file to get data for grid
File Location : app/code/Ktree/TicketingSystem/etc/di.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
<arguments>
<argument name="collections" xsi:type="array">
<item name="ktree_ticketingsystem_tickets_listing_data_source"
xsi:type="string">Ktree\TicketingSystem\Model\ResourceModel
\Tickets\Collection
</item>
</argument>
</arguments>
</type>
<virtualType name="Ktree\TicketingSystem\Model\ResourceModel\Tickets\Collection"
type="Magento\Framework\View\Element\UiComponent
\DataProvider\SearchResult">
<arguments>
<argument name="mainTable" xsi:type="string">ktree_ticketing_system</argument>
<argument name="resourceModel"
xsi:type="string">Ktree\TicketingSystem\Model\ResourceModel
\Tickets</argument>
</arguments>
</virtualType>
</config>
Here we create layout file for our admin grid, we define we use the Listing UI Component "ticketingsystem_tickets_listing" which we are going to create in next step 7.3
File Location :
app/code/Ktree/TicketingSystem/view/adminhtml/layout/ticketingsystem_tickets_index.xml
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
<update handle="styles" />
<body>
<referenceContainer name="content">
<uiComponent name="ticketingsystem_tickets_listing" />
</referenceContainer>
</body>
</page>
Listing is a basic UI component responsible for rendering grids, lists and tiles, providing filtering, pagination, sorting. In this step we will configure it.
<listingToolbar name="listing_top">
<filters name="listing_filters" />
<columnsControls name="columns_controls"/>
<filterSearch name="fulltext"/>
<paging name="listing_paging"/>
<exportButton name="export_button"/>
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="sticky" xsi:type="boolean">true</item>
</item>
</argument>
</listingToolbar>
File Location :
app/code/Ktree/TicketingSystem/view/adminhtml/ui_component/ticketingsystem_tickets_listing.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">ticketingsystem_tickets_listing.ktree_ticketingsystem_tickets_listing_data_source</item>
<item name="deps" xsi:type="string">ticketingsystem_tickets_listing.ktree_ticketingsystem_tickets_listing_data_source</item>
</item>
<item name="spinner" xsi:type="string">spinner_columns</item>
</argument>
<dataSource name="nameOfDataSource">
<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">ktree_ticketingsystem_tickets_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>
<listingToolbar name="listing_top">
<filters name="listing_filters" />
<columnsControls name="columns_controls" />
<filterSearch name="fulltext" />
<paging name="listing_paging" />
<exportButton name="export_button" />
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="sticky" xsi:type="boolean">true</item>
</item>
</argument>
</listingToolbar>
<columns name="spinner_columns">
<column name="ticket_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">Ticket Id</item>
</item>
</argument>
</column>
<column name="custmer_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">Custmer Id</item>
</item>
</argument>
</column>
<column name="category">
<argument name="data" xsi:type="array">
<item name="options" xsi:type="object">Ktree\TicketingSystem\Model\Source\Category</item>
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">select</item>
<item name="dataType" xsi:type="string">multiselect</item>
<item name="sorting" xsi:type="string">asc</item>
<item name="label" xsi:type="string" translate="true">Category</item>
</item>
</argument>
</column>
// More columns download source code from github
</columns>
</listing>
Clear cache by running “php bin/magento cache:clean” to check result.
You should see empty grid, since we did not added any records
For testing purposes, add records manually from database and see if those are appearing in the grid or not.
To enable edit and delete of the records in the admin grid we create actions.
<actionsColumn name="actions" class="Ktree\TicketingSystem\Ui\Component\Listing\Column\Actions">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="indexField" xsi:type="string">id</item>
</item>
</argument>
</actionsColumn>
File Location :
Ktree\TicketingSystem\Ui\Component\Listing\Column\Actions.php
<?php
namespace Ktree\TicketingSystem\Ui\Component\Listing\Column;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Ui\Component\Listing\Columns\Column;
use Ktree\TicketingSystem\Block\Adminhtml\Module\Grid\Renderer\Action\UrlBuilder;
use Magento\Framework\UrlInterface;
class Actions extends Column {
/** Url path */
const URL_PATH_EDIT = 'ticketingsystem/tickets/add';
/** @var UrlBuilder */
protected $actionUrlBuilder;
/** @var UrlInterface */
protected $urlBuilder;
/**
* @param ContextInterface $context
* @param UiComponentFactory $uiComponentFactory
* @param UrlBuilder $actionUrlBuilder
* @param UrlInterface $urlBuilder
* @param array $components
* @param array $data
*/
public function __construct(ContextInterface $context, UiComponentFactory $uiComponentFactory, UrlBuilder $actionUrlBuilder, UrlInterface $urlBuilder, array $components = [], array $data = []) {
$this->urlBuilder = $urlBuilder;
$this->actionUrlBuilder = $actionUrlBuilder;
parent::__construct($context, $uiComponentFactory, $components, $data);
}
/**
* Prepare Data Source
*
* @param array $dataSource
* @return array
*/
public function prepareDataSource(array $dataSource) {
if (isset($dataSource['data']['items'])) {
foreach ($dataSource['data']['items'] as & $item) {
$name = $this->getData('name');
if (isset($item['id'])) {
$item[$name]['edit'] = ['href' => $this->urlBuilder->getUrl(self::URL_PATH_EDIT, ['id' => $item['id']]), 'label' => __('Edit') ];
}
}
}
return $dataSource;
}
}
File Location :
app/code/Ktree/TicketingSystem/Block/Adminhtml/Module/Grid/Renderer/Action/UrlBuilder.php
<?php
namespace Ktree\TicketingSystem\Block\Adminhtml\Module\Grid\Renderer\Action;
class UrlBuilder {
/**
* @var \Magento\Framework\UrlInterface
*/
protected $frontendUrlBuilder;
/**
* @param \Magento\Framework\UrlInterface $frontendUrlBuilder
*/
public function __construct(\Magento\Framework\UrlInterface $frontendUrlBuilder) {
$this->frontendUrlBuilder = $frontendUrlBuilder;
}
/**
* Get action url
*
* @param string $routePath
* @param string $scope
* @param string $store
* @return string
*/
public function getUrl($routePath, $scope, $store) {
$this->frontendUrlBuilder->setScope($scope);
$href = $this->frontendUrlBuilder->getUrl($routePath, ['_current' => false, '_query' => '___store=' . $store]);
return $href;
}
}
If you refresh admin grid we will able to grid with edit option.
Now we need to add action to edit column.
As we mentioned URL_PATH_EDIT in Action.php to active link we need to create Controller, layout, block files.
File Location:
app/code/Ktree/TicketingSystem/Controller/Adminhtml/Tickets/Add.php
<?php
namespace Ktree\TicketingSystem\Controller\Adminhtml\Tickets;
use Magento\Framework\Controller\ResultFactory;
class Add extends \Magento\Backend\App\Action {
/**
* @var \Magento\Framework\Registry
*/
private $coreRegistry;
protected $_ticketsFactory;
/**
* @param \Magento\Backend\App\Action\Context $context
* @param \Magento\Framework\Registry $coreRegistry,
*/
publicfunction __construct(\Magento\Backend\App\Action\Context $context, \Magento\Framework\Registry $coreRegistry, \Ktree\TicketingSystem\Model\TicketsFactory $ticketsFactory) {
parent::__construct($context);
$this->coreRegistry = $coreRegistry;
$this->_ticketsFactory = $ticketsFactory;
}
/**
* Mapped Grid List page.
* @return \Magento\Backend\Model\View\Result\Page
*/
publicfunction execute() {
$rowId = (int)$this->getRequest()->getParam('id');
/** @var \Magento\Backend\Model\View\Result\Page $resultPage */
if($rowId) {
$rowData = $this->_ticketsFactory->create()->load($rowId);
if(!$rowData->getId()) {
$this->messageManager->addError(__('row data no longer exist.'));
$this->_redirect('ticketingsystem/tickets');
return;
}
}
$this->coreRegistry->register('row_data', $rowData);
$resultPage = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
$title = $rowId ? __('Edit Row Data ') : __('Add Row Data');
$resultPage->getConfig()->getTitle()->prepend($title);
return $resultPage;
}
protectedfunction _isAllowed() {
return $this->_authorization->isAllowed('Ktree_TicketingSystem::add');
}
}
Create admin layout file
File Location:
app/code/Ktree/TicketingSystem/view/adminhtml/layout/ticketingsystem_tickets_add.xml
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
<update handle="styles" />
<body>
<referenceContainer name="content">
<block class="Ktree\TicketingSystem\Block\Adminhtml\Tickets\Add" name="add" />
</referenceContainer>
</body>
</page>
In node class - path of the respective block class
Name - block name
Create admin block file
File Location:
app/code/Ktree/TicketingSystem/Block/Adminhtml/Tickets/Add.php
ERROR -----------------------------------------------------------------
The document cannot be processed.
If you think this request should have succeeded please send your feedback.
Email:[email protected]
XmlException ----------------------------------------------------------
Unexpected end of file while parsing PI has occurred. Line 73, position 2.
XML Document ----------------------------------------------------------
<?php
namespace Ktree\TicketingSystem\Block\Adminhtml\Tickets;
class Add extends \Magento\Backend\Block\Widget\Form\Container {
/**
* Core registry.
*
* @var \Magento\Framework\Registry
*/
protected $_coreRegistry = null;
/**
* @param \Magento\Backend\Block\Widget\Context $context
* @param \Magento\Framework\Registry $registry
* @param array $data
*/
public function __construct(\Magento\Backend\Block\Widget\Context $context, \Magento\Framework\Registry $registry, array $data = []) {
$this->_coreRegistry = $registry;
parent::__construct($context, $data);
}
/**
* Initialize Imagegallery Images Edit Block.
*/
protected function _construct() {
$this->_objectId = 'row_id';
$this->_blockGroup = 'Ktree_TicketingSystem';
$this->_controller = 'adminhtml_tickets';
parent::_construct();
if ($this->_isAllowedAction('Ktree_TicketingSystem::add')) {
$this->buttonList->update('save', 'label', __('Save'));
} else {
$this->buttonList->remove('save');
}
$this->buttonList->remove('reset');
}
/**
* Retrieve text for header element depending on loaded image.
*
* @return \Magento\Framework\Phrase
*/
public function getHeaderText() {
return __('Add Tickets');
}
/**
* Check permission for passed action.
*
* @param string $resourceId
*
* @return bool
*/
protected function _isAllowedAction($resourceId) {
return $this->_authorization->isAllowed($resourceId);
}
/**
* Get form action URL.
*
* @return string
*/
public function getFormActionUrl() {
if ($this->hasFormActionUrl()) {
return $this->getData('form_action_url');
}
return $this->getUrl('*/*/save');
}
}
Create admin edit block form file
File Location:
app/code/Ktree/TicketingSystem/Block/Adminhtml/Tickets/Edit/Form.php
<?php
namespace Ktree\TicketingSystem\Block\Adminhtml\Tickets\Edit;
/**
* Adminhtml Add New Row Form.
*/
class Form extends \Magento\Backend\Block\Widget\Form\Generic {
/**
* @var \Magento\Store\Model\System\Store
*/
protected $_systemStore;
protected $_status;
protected $_priority;
protected $_category;
/**
* @param \Magento\Backend\Block\Template\Context $context
* @param \Magento\Framework\Registry $registry
* @param \Magento\Framework\Data\FormFactory $formFactory
* @param array $data
*/
public function __construct(\Magento\Backend\Block\Template\Context $context, \Magento\Framework\Registry $registry, \Magento\Framework\Data\FormFactory $formFactory, \Magento\Cms\Model\Wysiwyg\Config $wysiwygConfig, \Ktree\TicketingSystem\Model\Source\Status $status, \Ktree\TicketingSystem\Model\Source\Priority $priority, \Ktree\TicketingSystem\Model\Source\Category $category, array $data = []) {
$this->_status = $status;
$this->_priority = $priority;
$this->_category = $category;
$this->_wysiwygConfig = $wysiwygConfig;
parent::__construct($context, $registry, $formFactory, $data);
}
/**
* Prepare form.
*
* @return $this
*/
protected function _prepareForm() {
$dateFormat = $this->_localeDate->getDateFormat(\IntlDateFormatter::SHORT);
$model = $this->_coreRegistry->registry('row_data');
$form = $this->_formFactory->create(['data' => ['id' => 'edit_form', 'enctype' => 'multipart/form-data', 'action' => $this->getData('action'), 'method' => 'post']]);
$form->setHtmlIdPrefix('tickets_');
if ($model->getId()) {
$fieldset = $form->addFieldset('base_fieldset', ['legend' => __('Edit Row Data'), 'class' => 'fieldset-wide']);
$fieldset->addField('id', 'hidden', ['name' => 'id']);
} else {
$fieldset = $form->addFieldset('base_fieldset', ['legend' => __('Add Row Data'), 'class' => 'fieldset-wide']);
}
$fieldset->addField('ticket_id', 'text', ['name' => 'ticket_id', 'label' => __('Ticket Id'), 'id' => 'ticket_id', 'title' => __('Ticket Id'), 'class' => 'required-entry', 'required' => true, 'disabled' => true, ]);
$fieldset->addField('custmer_id', 'text', ['name' => 'custmer_id', 'label' => __('Custmer Id'), 'id' => 'custmer_id', 'title' => __('Custmer Id'), 'class' => 'required-entry', 'required' => true, 'disabled' => true, ]);
// Other Columns get code from github
);
$form->setValues($model->getData());
$form->setUseContainer(true);
$this->setForm($form);
return parent::_prepareForm();
}
}
After creating above files and if you click on edit action you will able to see the form as below
In the form we have disabled all field except Status field. To save Form changes we need to create action.
Create save action,
File Location:
app/code/Ktree/TicketingSystem/Controller/Adminhtml/Tickets/Save.php
<?php
namespace Ktree\TicketingSystem\Controller\Adminhtml\Tickets;
class Save extends \Magento\Backend\App\Action
{
protected $_ticketsFactory;
public function __construct(\Magento\Backend\App\Action\Context $context, \Ktree\TicketingSystem\Model\TicketsFactory $ticketsFactory)
{
$this->_ticketsFactory = $ticketsFactory;
parent::__construct($context);
}
/**
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
*/
public function execute()
{
$data = $this->getRequest()->getPostValue();
if (!$data) {
$this->_redirect('ticketingsystem/tickets/add');
return;
}
try {
$rowData = $this->_ticketsFactory->create()->load($data['id']);
if (!$rowData->getId()) {
$this->messageManager->addError(__('row data no longer exist.'));
$this->_redirect('ticketingsystem/tickets');
return;
}
$rowData->setData($data);
$rowData->save();
$this->messageManager->addSuccess(__('Row data has been successfully saved.'));
}
catch (\Exception $e) {
$this->messageManager->addError(__($e->getMessage()));
}
$this->_redirect('ticketingsystem/tickets');
}
/**
* @return bool
*/
protected function _isAllowed()
{
return $this->_authorization->isAllowed('Ktree_TicketingSystem::save');
}
}
After completing above step and click on Save button, changes will be stored to and success message will be displayed.
Note: We updated status from New -> Open
when we are creating table through installer sometime table won’t be created.
When we update any changes our custom module admin/front css and js file will not load
rm -rf var/*
When we are trying to create admin grid it will display only heading.
Sometimes grid keeps on loading
We may get Magento 2 Class *Factory does not exist exception when we trying to create object for our customly created factory object ex: $this->_ticketsFactory->create()
Please Contact us if you have any Magento Implementation requirements. Hire dedicated Magento developers or Magento Development services from KTree. KTree is Best offshore Magento E-commerce development company with extensive experience in E-commerce development and Magento Plugins.
Request For Quote