How to create Grid in admin in Magento 2 - Magesan

How to create Grid in admin in Magento 2

How to create Grid in admin in Magento 2

Magento 2 provides such functionality to add and save data by creating menus and to see data in Grid.

I will teach you today with basic to high of creating module and to add the things in grid.

First of all we need to create extension : Magesan_AdminGrid

registration.php At Path app/code/Magesan/AdminGrid/registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Magesan_AdminGrid',
    __DIR__
);

module.xml At Path app/code/Magesan/AdminGrid/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Magesan_AdminGrid" setup_version="1.0.0" data_version="1.0.0">
        <sequence>
            <module name="Magento_Backend" />
        </sequence>
    </module>
</config>

Now we need to create db table :- `magesan_admin_grid`

SetupMagesanAdminGrid.php At Path :- app/code/Magesan/AdminGrid/Setup/Patch/Schema/SetupMagesanAdminGrid.php

<?php

namespace Magesan\AdminGrid\Setup\Patch\Schema;

use Magento\Framework\Setup\Patch\SchemaPatchInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\DB\Ddl\Table;
use Magesan\AdminGrid\Model\Source\YesNo;

class SetupMagesanAdminGrid implements SchemaPatchInterface
{
    const MAGESAN_ADMIN_GRID = "magesan_admin_grid";

    /**
     * @var SchemaPatchInterface
     */
    private $moduleDataSetup;

    /**
     * __construct
     *
     * @param ModuleDataSetupInterface $moduleDataSetup
     */
    public function __construct(
        ModuleDataSetupInterface $moduleDataSetup
    ) {
        $this->moduleDataSetup = $moduleDataSetup;
    }

    public function apply()
    {
        $this->moduleDataSetup->startSetup();
        $conn = $this->moduleDataSetup->getConnection();

        if (!$conn->isTableExists(self::MAGESAN_ADMIN_GRID)) {
            $adminGrid = $conn->newTable(self::MAGESAN_ADMIN_GRID)
                ->addColumn(
                    'id',
                    Table::TYPE_INTEGER,
                    null,
                    [
                        'identity' => true,
                        'unsigned' => true,
                        'nullable' => false,
                        'primary'  => true
                    ]
                )->addColumn(
                    'status',
                    Table::TYPE_SMALLINT,
                    null,
                    [
                        'nullable' => false,
                        'default'  => YesNo::NO
                    ]
                )->addColumn(
                    'product_sku',
                    Table::TYPE_TEXT,
                    null,
                    [
                        'nullable' => true,
                        'comment'  => 'Product Sku'
                    ]
                )->addColumn(
                    'postcode',
                    Table::TYPE_TEXT,
                    null,
                    [
                        'nullable' => true,
                        'comment'  => 'Postcode'
                    ]
                )->addColumn(
                    'store_ids',
                    Table::TYPE_TEXT,
                    null,
                    [
                        'nullable' => false,
                        'comment'  => 'Store Ids'
                    ]
                )->addColumn(
                    'created_at',
                    Table::TYPE_TIMESTAMP,
                    255,
                    [
                        'nullable' => false,
                        'default'  => Table::TIMESTAMP_INIT,
                        'comment'  => 'Created At'
                    ]
                )->addColumn(
                    'updated_at',
                    Table::TYPE_TIMESTAMP,
                    255,
                    [
                        'nullable' => false,
                        'default'  => Table::TIMESTAMP_INIT_UPDATE,
                        'comment'  => 'Updated At'
                    ]
                )
                ->setOption('charset', 'utf8');

            $conn->createTable($adminGrid);
        }

        $this->moduleDataSetup->endSetup();
    }

    public static function getDependencies()
    {
        return [];
    }

    public function getAliases()
    {
        return [];
    }
}

After creating table you need to create ResourceModel At Path :-

app/code/Magesan/AdminGrid/Model/AdminGrid.php

<?php

namespace Magesan\AdminGrid\Model;

use Magento\Framework\Model\AbstractModel;
use Magesan\AdminGrid\Model\ResourceModel\AdminGrid as ResourceModelAdminGrid;

class AdminGrid extends AbstractModel
{
    /**
     * @inheritDoc
     */
    protected function _construct()
    {
        $this->_init(ResourceModelAdminGrid::class);
    }
}

app/code/Magesan/AdminGrid/Model/ResourceModel/AdminGrid.php

<?php

namespace Magesan\AdminGrid\Model\ResourceModel;

use Magento\Framework\Model\ResourceModel\Db\AbstractDb;

class AdminGrid extends AbstractDb
{
    const MAGESAN_ADMIN_GRID = "magesan_admin_grid";
    const ID                 = "id";

    /**
     * @inheritDoc
     */
    protected function _construct()
    {
        $this->_init(self::MAGESAN_ADMIN_GRID, self::ID);
    }
}

app/code/Magesan/AdminGrid/Model/ResourceModel/AdminGrid/Collection.php

<?php

namespace Magesan\AdminGrid\Model\ResourceModel\AdminGrid;

use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
use Magesan\AdminGrid\Model\AdminGrid;
use Magesan\AdminGrid\Model\ResourceModel\AdminGrid as ResourceModelAdminGrid;

class Collection extends AbstractCollection
{
    /**
     * @inheritDoc
     */
    protected function _construct()
    {
        $this->_init(AdminGrid::class, ResourceModelAdminGrid::class);
    }
}

ResourceModel created Successfully.

Now other files we need to create which responsible for adding menu and creating grid.

app/code/Magesan/AdminGrid/etc/acl.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
    <acl>
        <resources>
            <resource id="Magento_Backend::admin">
                <resource id="Magesan_AdminGrid::magesan" title="Magesan" sortOrder="50">
                    <resource id="Magesan_AdminGrid::admingrid" title="Admin Grid" sortOrder="1" />
                </resource>
            </resource>
        </resources>
    </acl>
</config>

app/code/Magesan/AdminGrid/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="Magesan_AdminGrid::admingrid" title="Admin Grid" module="Magesan_AdminGrid" sortOrder="1" action="magesan/admingrid/index" parent="Magesan_Core::core" resource="Magento_Backend::content" />
    </menu>
</config>

app/code/Magesan/AdminGrid/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="magesan" frontName="magesan">
            <module name="Magesan_AdminGrid" />
        </route>
    </router>
</config>

app/code/Magesan/AdminGrid/Model/Source/ProductSku.php

<?php

namespace Magesan\AdminGrid\Model\Source;

use Magento\Framework\Data\OptionSourceInterface;
use \Magento\Eav\Model\Config;

class ProductSku implements OptionSourceInterface
{
    const PRODUCT_SKU     = "sku";
    const CATALOG_PRODUCT = "catalog_product";

    /**
     * @var Config
     */
    protected $eavConfig;

    /**
     * __construct
     *
     * @param Config $eavConfig
     */
    public function __construct(Config $eavConfig)
    {
        $this->eavConfig = $eavConfig;
    }

    /**
     * {@inheritdoc}
     */
    public function toOptionArray(): array
    {
        return $this->getProductSkuOption();
    }

    protected function getProductSkuOption(): array
    {
        $optionsExists = ["" => " -- Please select sku -- "];
        $attribute     = $this->eavConfig->getAttribute(self::CATALOG_PRODUCT, self::PRODUCT_SKU);

        if ($options = $attribute->getSource()->getAllOptions()) {
            foreach ($options as $option) {
                if ($option['value'] > 0) {
                    $optionsExists[$option['value']] = ["label" => ucfirst($option['label']), "value" => $option['value']];
                }
            }
        }

        return $optionsExists;
    }

    /**
     * getProductAttributeText
     *
     * @param integer $selectedOption
     * @return string
     */
    public function getProductAttributeText($selectedOption): string
    {
        $regionOptions = $this->toOptionArray();
        if (isset($regionOptions[$selectedOption])) {
            return $regionOptions[$selectedOption]["label"];
        }

        return "";
    }
}

app/code/Magesan/AdminGrid/Model/Source/YesNo.php

<?php

namespace Magesan\AdminGrid\Model\Source;

use Magento\Framework\Option\ArrayInterface;

class YesNo implements ArrayInterface
{
    const YES = 1;
    const NO  = 0;

    /**
     * {@inheritdoc}
     */
    public function toOptionArray()
    {
        return [
            ['value' => self::NO, 'label'  => __('No')],
            ['value' => self::YES, 'label' => __('Yes')]
        ];
    }
}

Now we are going to create di.xml At Path :- app/code/Magesan/AdminGrid/etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <!-- magesan_admin_grid -->
    <type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
        <arguments>
            <argument name="collections" xsi:type="array">
                <item name="magesan_admingrid_listing_data_source" xsi:type="string">Magesan\AdminGrid\Model\ResourceModel\AdminGrid\Grid\Collection</item>
            </argument>
        </arguments>
    </type>
    <virtualType name="Magesan\AdminGrid\Model\ResourceModel\AdminGrid\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
        <arguments>
            <argument name="mainTable" xsi:type="string">magesan_admin_grid</argument>
            <argument name="resourceModel" xsi:type="string">Magesan\AdminGrid\Model\ResourceModel\AdminGrid</argument>
        </arguments>
    </virtualType>
</config>

Now we are going to create layout xml files and controllers which responsible to handle the view and fetching data to the grid.

app/code/Magesan/AdminGrid/view/adminhtml/layout/magesan_admingrid_index.xml

<?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">
    <update handle="styles" />
    <body>
        <referenceContainer name="content">
            <uiComponent name="magesan_admingrid_listing" />
        </referenceContainer>
    </body>
</page>

app/code/Magesan/AdminGrid/view/adminhtml/layout/magesan_admingrid_new.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="content">
            <block class="Magesan\AdminGrid\Block\Adminhtml\Grid\AdminGrid\NewAdminGrid" name="admingrid_newaction" />
        </referenceContainer>
    </body>
</page>

app/code/Magesan/AdminGrid/view/adminhtml/ui_component/magesan_admingrid_listing.xml

<?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">magesan_admingrid_listing.magesan_admingrid_listing_data_source</item>
        </item>
    </argument>
    <settings>
        <buttons>
            <button name="add">
                <url path="*/*/new" />
                <class>primary</class>
                <label translate="true">Add Data</label>
            </button>
        </buttons>
        <spinner>magesan_admingrid_columns</spinner>
        <deps>
            <dep>magesan_admingrid_listing.magesan_admingrid_listing_data_source</dep>
        </deps>
    </settings>
    <listingToolbar name="listing_top">
        <filters name="listing_filters" />
        <paging name="listing_paging" />
        <columnsControls name="columns_controls" />
        <exportButton name="export_button" />
        <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 Selected</item>
                        <item name="url" xsi:type="url" path="magesan/admingrid/massdelete" />
                        <item name="confirm" xsi:type="array">
                            <item name="title" xsi:type="string" translate="true">Delete Selected Data</item>
                            <item name="message" xsi:type="string" translate="true">Are you sure you wan't to delete selected items?</item>
                        </item>
                    </item>
                </argument>
            </action>
        </massaction>
    </listingToolbar>
    <dataSource name="magesan_admingrid_index">
        <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">magesan_admingrid_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="magesan_admingrid_columns">
        <settings>
            <editorConfig>
                <param name="clientConfig" xsi:type="array">
                    <item name="saveUrl" xsi:type="url" path="magesan/admingrid/inlineEdit" />
                    <item name="validateBeforeSave" xsi:type="boolean">false</item>
                </param>
                <param name="indexField" xsi:type="string">id</param>
                <param name="enabled" xsi:type="boolean">true</param>
                <param name="selectProvider" xsi:type="string">magesan_admingrid_listing.magesan_admingrid_listing.magesan_admingrid_columns.ids</param>
            </editorConfig>
            <childDefaults>
                <param name="fieldAction" xsi:type="array">
                    <item name="provider" xsi:type="string">magesan_admingrid_listing.magesan_admingrid_listing.magesan_admingrid_columns_editor</item>
                    <item name="target" xsi:type="string">startEdit</item>
                    <item name="params" xsi:type="array">
                        <item name="0" xsi:type="string">${ $.$data.rowIndex }</item>
                        <item name="1" xsi:type="boolean">true</item>
                    </item>
                </param>
            </childDefaults>
        </settings>
        <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_sku">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/columns/column</item>
                    <item name="editor" xsi:type="array">
                        <item name="editorType" xsi:type="string">text</item>
                        <item name="validation" xsi:type="array">
                            <item name="name" xsi:type="boolean">true</item>
                        </item>
                    </item>
                    <item name="label" xsi:type="string" translate="true">Sku</item>
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="sortOrder" xsi:type="number">50</item>
                    <item name="resizeEnabled" xsi:type="boolean">false</item>
                    <item name="resizeDefaultWidth" xsi:type="string">60</item>
                    <item name="sortable" xsi:type="boolean">false</item>
                </item>
            </argument>
        </column>
        <column name="postcode">
            <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">Postcode</item>
                </item>
            </argument>
        </column>
        <column name="status" class="Magesan\AdminGrid\Ui\Component\Listing\Grid\Column\Status">
            <argument name="data" xsi:type="array">
                <item name="options" xsi:type="object">Magesan\AdminGrid\Ui\Component\Listing\Grid\Column\Statuses</item>
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">select</item>
                    <item name="dataType" xsi:type="string">select</item>
                    <item name="editor" xsi:type="array">
                        <item name="editorType" xsi:type="string">select</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">Status</item>
                </item>
            </argument>
        </column>
        <column name="store_ids" class="Magesan\AdminGrid\Ui\Component\Listing\Grid\Column\StoreViews">
            <argument name="data" xsi:type="array">
                <item name="options" xsi:type="object">Magento\Cms\Ui\Component\Listing\Column\Cms\Options</item>
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">select</item>
                    <item name="label" xsi:type="string" translate="true">Stores</item>
                    <item name="dataType" xsi:type="string">select</item>
                    <item name="editor" xsi:type="array">
                        <item name="editorType" xsi:type="string">select</item>
                    </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 At</item>
                </item>
            </argument>
        </column>
        <column name="updated_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">Updated At</item>
                </item>
            </argument>
        </column>
        <actionsColumn name="actions" class="Magesan\AdminGrid\Ui\Component\Listing\Grid\Column\AdminGridAction">
            <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">id</item>
                </item>
            </argument>
        </actionsColumn>
    </columns>
</listing>

Now we are going to create controllers At Path :-

app/code/Magesan/AdminGrid/Controller/Adminhtml/AdminGrid/Index.php

<?php

namespace Magesan\AdminGrid\Controller\Adminhtml\AdminGrid;

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

class Index extends Action
{
    /**
     * @var PageFactory
     */
    private $resultPageFactory;

    /**
     * __construct
     *
     * @param Context $context
     * @param PageFactory $resultPageFactory
     */
    public function __construct(
        Context $context,
        PageFactory $resultPageFactory
    ) {
        parent::__construct($context);
        $this->resultPageFactory = $resultPageFactory;
    }

    /**
     * execute
     *
     * @return PageFactory
     */
    public function execute()
    {
        $resultPage = $this->resultPageFactory->create();
        $resultPage->setActiveMenu('Magesan_AdminGrid::admingrid');
        $resultPage->getConfig()->getTitle()->prepend(__('Admin Grid'));
        return $resultPage;
    }

    /**
     * _isAllowed
     *
     * @return bool
     */
    protected function _isAllowed()
    {
        return $this->_authorization->isAllowed('Magesan_AdminGrid::admingrid');
    }
}

app/code/Magesan/AdminGrid/Controller/Adminhtml/AdminGrid/NewAction.php

<?php

namespace Magesan\AdminGrid\Controller\Adminhtml\AdminGrid;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Registry;
use Magesan\AdminGrid\Model\AdminGridFactory;
use Magento\Framework\Controller\ResultFactory;

class NewAction extends Action
{
    /**
     * @var Registry
     */
    private $_coreRegistry;

    /**
     * @var AdminGridFactory
     */
    private $_adminGridFactory;

    /**
     * __construct
     *
     * @param Context $context
     * @param Registry $coreRegistry
     * @param AdminGridFactory $adminGridFactory
     */
    public function __construct(
        Context $context,
        Registry $coreRegistry,
        AdminGridFactory $adminGridFactory
    ) {
        parent::__construct($context);
        $this->_coreRegistry     = $coreRegistry;
        $this->_adminGridFactory = $adminGridFactory;
    }

    public function execute()
    {
        $rowId   = (int) $this->getRequest()->getParam('id');
        $rowData = $this->_adminGridFactory->create();
        /** @var \Magento\Backend\Model\View\Result\Page $resultPage */
        if ($rowId) {
            $rowData  = $rowData->load($rowId);
            $rowTitle = $rowData->getSku();
            if (!$rowData->getId()) {
                $this->messageManager->addError(__('Data no longer exist.'));
                $this->_redirect('magesan/admingrid/index');

                return;
            }
        }

        $this->_coreRegistry->register('admingrid', $rowData);
        $resultPage = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
        $title      = $rowId ? __('Edit Data ') . $rowTitle : __('Add Data');
        $resultPage->getConfig()->getTitle()->prepend($title);

        return $resultPage;
    }

    /**
     * _isAllowed
     *
     * @return bool
     */
    protected function _isAllowed()
    {
        return $this->_authorization->isAllowed('Magesan_AdminGrid::admingrid');
    }
}

app/code/Magesan/AdminGrid/Controller/Adminhtml/AdminGrid/SaveAction.php

<?php

namespace Magesan\AdminGrid\Controller\Adminhtml\AdminGrid;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magesan\AdminGrid\Model\AdminGridFactory;

class SaveAction extends Action
{
    /**
     * @var AdminGridFactory
     */
    protected $adminGridFactory;

    /**
     * __construct
     *
     * @param Context $context
     * @param AdminGridFactory $adminGridFactory
     */
    public function __construct(
        Context $context,
        AdminGridFactory $adminGridFactory
    ) {
        parent::__construct($context);
        $this->adminGridFactory = $adminGridFactory;
    }

    public function execute()
    {
        $data = $this->getRequest()->getPostValue();
        if (!$data) {
            $this->_redirect('magesan/admingrid/index');
            return;
        }
        try {
            $rowData = $this->adminGridFactory->create();
            $data['store_ids'] = implode(',', $this->getRequest()->getParam('store_ids'));
            $rowData->setData($data);
            if (isset($data['id'])) {
                $rowData->setId($data['id']);
            }

            $rowData->save();
            $this->messageManager->addSuccess(__('Data successfully saved.'));
        } catch (\Exception $e) {
            $this->messageManager->addError(__($e->getMessage()));
        }
        $this->_redirect('magesan/admingrid/index');
    }

    /**
     * _isAllowed
     *
     * @return bool
     */
    protected function _isAllowed()
    {
        return $this->_authorization->isAllowed('Magesan_AdminGrid::admingrid');
    }
}

app/code/Magesan/AdminGrid/Controller/Adminhtml/AdminGrid/Delete.php

<?php

namespace Magesan\AdminGrid\Controller\Adminhtml\AdminGrid;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magesan\AdminGrid\Model\AdminGridFactory;

class Delete extends Action
{
    /**
     * @var AdminGridFactory
     */
    protected $adminGridFactory;

    /**
     * __construct
     *
     * @param Context $context
     * @param AdminGridFactory $adminGridFactory
     */
    public function __construct(
        Context $context,
        AdminGridFactory $adminGridFactory
    ) {
        parent::__construct($context);
        $this->adminGridFactory = $adminGridFactory;
    }

    public function execute()
    {

        $data = $this->getRequest()->getParams();
        if (!$data) {
            $this->_redirect('magesan/admingrid/index');

            return;
        }
        try {
            $rowData = $this->adminGridFactory->create();
            if (isset($data['id'])) {
                $rowData->load($data['id']);
                $rowData->delete();

                $this->messageManager->addSuccess(__('Successfully deleted.'));
            }
        } catch (\Exception $e) {
            $this->messageManager->addSuccess(__('Please try again after some time.'));
        }
        $this->_redirect('magesan/admingrid/index');
    }

    /**
     * _isAllowed
     *
     * @return bool
     */
    protected function _isAllowed()
    {
        return $this->_authorization->isAllowed('Magesan_AdminGrid::admingrid');
    }
}

app/code/Magesan/AdminGrid/Controller/Adminhtml/AdminGrid/MassDelete.php

<?php

namespace Magesan\AdminGrid\Controller\Adminhtml\AdminGrid;

use Magento\Backend\App\Action;
use Magento\Framework\Controller\ResultFactory;
use Magento\Backend\App\Action\Context;
use Magento\Ui\Component\MassAction\Filter;
use Magesan\AdminGrid\Model\ResourceModel\AdminGrid\CollectionFactory;
use Magento\Framework\Message\ManagerInterface;

class MassDelete extends Action
{
    /**
     * @var Filter
     */
    protected $filter;

    /**
     * @var CollectionFactory
     */
    protected $collectionFactory;

    /**
     * @var ManagerInterface
     */
    protected $messageManager;

    public function __construct(
        Context $context,
        Filter $filter,
        CollectionFactory $collectionFactory,
        ManagerInterface $messageManager
    ) {
        parent::__construct($context);
        $this->filter            = $filter;
        $this->collectionFactory = $collectionFactory;
        $this->messageManager    = $messageManager;
    }

    /**
     * _isAllowed
     *
     * @return bool
     */
    protected function _isAllowed()
    {
        return $this->_authorization->isAllowed('Magesan_AdminGrid::admingrid');
    }

    /**
     * Execute action
     *
     * @return \Magento\Backend\Model\View\Result\Redirect
     * @throws \Magento\Framework\Exception\LocalizedException|\Exception
     */
    public function execute()
    {
        $collection     = $this->filter->getCollection($this->collectionFactory->create());
        $collectionSize = $collection->getSize();

        foreach ($collection as $csvRate) {
            $csvRate->delete();
        }

        $this->messageManager->addSuccess(__('A total of %1 record(s) have been deleted.', $collectionSize));

        /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);

        return $resultRedirect->setPath('magesan/admingrid/index');
    }
}

app/code/Magesan/AdminGrid/Controller/Adminhtml/AdminGrid/InlineEdit.php

<?php

namespace Magesan\AdminGrid\Controller\Adminhtml\AdminGrid;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Controller\Result\JsonFactory;
use Magesan\AdminGrid\Model\AdminGrid;

class InlineEdit extends Action
{
    /**
     * @var JsonFactory
     */
    protected $jsonFactory;

    /**
     * @var AdminGrid
     */
    protected $modelAdminGrid;

    /**
     * __construct
     *
     * @param Context $context
     * @param JsonFactory $jsonFactory
     * @param AdminGrid $modelAdminGrid
     */
    public function __construct(
        Context $context,
        JsonFactory $jsonFactory,
        AdminGrid $modelAdminGrid
    ) {
        parent::__construct($context);
        $this->jsonFactory    = $jsonFactory;
        $this->modelAdminGrid = $modelAdminGrid;
    }

    public function execute()
    {
        /** @var \Magento\Framework\Controller\Result\Json $resultJson */
        $resultJson = $this->jsonFactory->create();
        $error      = false;
        $messages   = [];
        if ($this->getRequest()->getParam('isAjax')) {
            $postItems = $this->getRequest()->getParam('items', []);
            if (!count($postItems)) {
                $messages[] = __('Please correct the data sent.');
                $error      = true;
            } else {
                foreach (array_keys($postItems) as $id) {
                    $model = $this->modelAdminGrid->load($id);
                    try {
                        $model->setData(array_merge($model->getData(), $postItems[$id]));
                        $model->save();
                    } catch (\Exception $e) {
                        $messages[] = "[Error:]  {$e->getMessage()}";
                        $error = true;
                    }
                }
            }
        }

        return $resultJson->setData([
            'messages' => $messages,
            'error'    => $error
        ]);
    }
}

Now we are going to create Block At Path :-

app/code/Magesan/AdminGrid/Block/Adminhtml/Grid/AdminGrid/NewAdminGrid.php

<?php

namespace Magesan\AdminGrid\Block\Adminhtml\Grid\AdminGrid;

use Magento\Backend\Block\Widget\Form\Container;
use Magento\Backend\Block\Widget\Context;
use Magento\Framework\Registry;

class NewAdminGrid extends Container
{
    /**
     * @var Registry
     */
    protected $_coreRegistry = null;

    /**
     * __construct
     *
     * @param Context $context
     * @param Registry $registry
     * @param array $data
     */
    public function __construct(
        Context $context,
        Registry $registry,
        array $data = []
    ) {
        parent::__construct($context, $data);
        $this->_coreRegistry = $registry;
    }

    protected function _construct()
    {
        $this->_objectId   = 'id';
        $this->_blockGroup = 'Magesan_AdminGrid';
        $this->_controller = 'adminhtml_grid_adminGrid';
        parent::_construct();
        if ($this->_isAllowedAction('Magesan_AdminGrid::admingrid')) {
            $this->buttonList->update('save', 'label', __('Save Data'));
        }
        $this->buttonList->remove('reset');
        $this->buttonList->update('back', 'onclick', 'setLocation(\'' . $this->getUrl('*/*/index') . '\')');
    }

    /**
     * Retrieve text for header element depending on loaded image.
     *
     * @return \Magento\Framework\Phrase
     */
    public function getHeaderText()
    {
        return __('Add New Data');
    }

    /**
     * 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('*/*/saveaction');
    }
}

app/code/Magesan/AdminGrid/Block/Adminhtml/Grid/AdminGrid/Edit/Form.php

<?php

namespace Magesan\AdminGrid\Block\Adminhtml\Grid\AdminGrid\Edit;

use Magento\Backend\Block\Widget\Form\Generic;
use Magento\Backend\Block\Template\Context;
use Magento\Framework\Registry;
use Magento\Framework\Data\FormFactory;
use Magesan\AdminGrid\Model\Source\YesNo;
use Magento\Store\Model\System\Store;
use Magesan\AdminGrid\Model\Source\ProductSku;

class Form extends Generic
{
    /**
     * @var YesNo
     */
    protected $yesNo;

    /**
     * @var Store
     */
    protected $stores;

    /**
     * @var ProductSku
     */
    protected $productSku;

    /**
     * __construct
     *
     * @param Context $context
     * @param Registry $registry
     * @param FormFactory $formFactory
     * @param YesNo $yesNo
     * @param Store $stores
     * @param ProductSku $productSku
     * @param array $data
     */
    public function __construct(
        Context $context,
        Registry $registry,
        FormFactory $formFactory,
        YesNo $yesNo,
        Store $stores,
        ProductSku $productSku,
        array $data = []
    ) {
        parent::__construct($context, $registry, $formFactory, $data);
        $this->yesNo      = $yesNo;
        $this->stores     = $stores;
        $this->productSku = $productSku;
    }

    /**
     * Prepare form.
     *
     * @return $this
     */
    protected function _prepareForm()
    {
        $model = $this->_coreRegistry->registry('admingrid');

        $form = $this->_formFactory->create(
            [
                'data' => [
                    'id'      => 'edit_form',
                    'enctype' => 'multipart/form-data',
                    'action'  => $this->getData('action'),
                    'method'  => 'post'
                ]
            ]
        );

        $form->setHtmlIdPrefix('admingridgrid_');
        if ($model->getId()) {
            $fieldset = $form->addFieldset(
                'base_fieldset',
                ['legend' => __('Edit ' . $model->getTitle()), 'class' => 'fieldset-wide']
            );
            $fieldset->addField('id', 'hidden', ['name' => 'id']);
        } else {
            $fieldset = $form->addFieldset(
                'base_fieldset',
                ['legend' => __('Add Data'), 'class' => 'fieldset-wide']
            );
        }

        $fieldset->addField(
            'status',
            'select',
            [
                'name'     => 'status',
                'label'    => __('Status'),
                'id'       => 'status',
                'title'    => __('status'),
                'values'   => $this->yesNo->toOptionArray(),
                'class'    => 'required-entry',
                'required' => true,
            ]
        );

        $fieldset->addField(
            'product_sku',
            'select',
            [
                'name'     => 'product_sku',
                'label'    => __('Sku'),
                'id'       => 'product_sku',
                'title'    => __('Sku'),
                'class'    => 'required-entry',
                'required' => true,
                'values'   => $this->productSku->toOptionArray()
            ]
        );

        $fieldset->addField(
            'postcode',
            'text',
            [
                'name'     => 'postcode',
                'label'    => __('Postcode'),
                'id'       => 'postcode',
                'title'    => __('postcode'),
                'class'    => 'required-entry',
                'required' => true,
            ]
        );

        $fieldset->addField(
            'store_ids',
            'multiselect',
            [
                'name'     => 'store_ids[]',
                'label'    => __('Store Views'),
                'title'    => __('Store Views'),
                'required' => true,
                'values'   => $this->stores->getStoreValuesForForm(false, true),
            ]
        );

        $form->setValues($model->getData());
        $form->setUseContainer(true);
        $this->setForm($form);

        return parent::_prepareForm();
    }
}

Block part are done now we will create rest of the files At Path :-

app/code/Magesan/AdminGrid/Ui/Component/Listing/Grid/Column/AdminGridAction.php

<?php

namespace Magesan\AdminGrid\Ui\Component\Listing\Grid\Column;

use Magento\Ui\Component\Listing\Columns\Column;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Framework\UrlInterface;

class AdminGridAction extends Column
{
    const ROW_EDIT_URL = 'magesan/admingrid/new';

    /**
     * @var UrlInterface
     */
    protected $urlBuilder;

    /**
     * @var string
     */
    private $editUrl;

    /**
     * __construct
     *
     * @param ContextInterface $context
     * @param UiComponentFactory $uiComponentFactory
     * @param UrlInterface $urlBuilder
     * @param array $components
     * @param array $data
     * @param string $editUrl
     */
    public function __construct(
        ContextInterface $context,
        UiComponentFactory $uiComponentFactory,
        UrlInterface $urlBuilder,
        array $components = [],
        array $data = [],
        $editUrl = self::ROW_EDIT_URL
    ) {
        parent::__construct($context, $uiComponentFactory, $components, $data);
        $this->urlBuilder = $urlBuilder;
        $this->editUrl    = $editUrl;
    }

    /**
     * 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(
                            $this->editUrl,
                            ['id' => $item['id']]
                        ),
                        'label' => __('Edit'),
                    ];
                }
            }
        }

        return $dataSource;
    }
}

app/code/Magesan/AdminGrid/Ui/Component/Listing/Grid/Column/Statuses.php

<?php

namespace Magesan\AdminGrid\Ui\Component\Listing\Grid\Column;

use Magento\Framework\Data\OptionSourceInterface;
use Magesan\AdminGrid\Model\Source\YesNo;

class Statuses implements OptionSourceInterface
{
    /**
     * @var YesNo
     */
    protected $yesNo;

    /**
     * __construct
     *
     * @param YesNo $yesNo
     */
    public function __construct(
        YesNo $yesNo
    ) {
        $this->yesNo = $yesNo;
    }

    public function toOptionArray()
    {
        return $this->yesNo->toOptionArray();
    }
}

app/code/Magesan/AdminGrid/Ui/Component/Listing/Grid/Column/StoreViews.php

<?php

namespace Magesan\AdminGrid\Ui\Component\Listing\Grid\Column;

use Magento\Ui\Component\Listing\Columns\Column;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Store\Model\StoreManagerInterface;

class StoreViews extends Column
{
    /**
     * @var StoreManagerInterface
     */
    protected $storeManager;

    /**
     * __construct
     *
     * @param ContextInterface $context
     * @param UiComponentFactory $uiComponentFactory
     * @param StoreManagerInterface $storeManager
     * @param array $components
     * @param array $data
     */
    public function __construct(
        ContextInterface $context,
        UiComponentFactory $uiComponentFactory,
        StoreManagerInterface $storeManager,
        array $components = [],
        array $data = []
    ) {
        parent::__construct($context, $uiComponentFactory, $components, $data);
        $this->storeManager = $storeManager;
    }

    public function prepareDataSource(array $dataSource)
    {
        if (isset($dataSource['data']['items'])) {
            foreach ($dataSource['data']['items'] as &$item) {
                if (isset($item['store_ids'])) {
                    $storeId           = $item['store_ids'];
                    $item['store_ids'] = $this->getStoreName(explode(",", $storeId));
                }
            }
        }

        return $dataSource;
    }

    /**
     * getStoreName
     *
     * @param array $storeIds
     * @return array
     */
    public function getStoreName(array $storeIds): array
    {
        $storeViewName = [];
        foreach ($storeIds as $storeId) {
            $storeViewName[] = $this->storeManager->getStore($storeId)->getName();
        }

        return $storeViewName;
    }
}

app/code/Magesan/AdminGrid/Ui/Component/Listing/Grid/Column/Status.php

<?php

namespace Magesan\AdminGrid\Ui\Component\Listing\Grid\Column;

use Magento\Ui\Component\Listing\Columns\Column;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magesan\AdminGrid\Model\Source\YesNo;

class Status extends Column
{
    /**
     * @var YesNo
     */
    protected $yesNo;

    /**
     * __construct
     *
     * @param ContextInterface $context
     * @param UiComponentFactory $uiComponentFactory
     * @param YesNo $yesNo
     * @param array $components
     * @param array $data
     */
    public function __construct(
        ContextInterface $context,
        UiComponentFactory $uiComponentFactory,
        YesNo $yesNo,
        array $components = [],
        array $data = []
    ) {
        parent::__construct($context, $uiComponentFactory, $components, $data);
        $this->yesNo = $yesNo;
    }

    public function prepareDataSource(array $dataSource)
    {
        if (isset($dataSource['data']['items'])) {
            foreach ($dataSource['data']['items'] as &$item) {
                if (isset($item['status'])) {
                    $status         = $item['status'];
                    $statusValue    = $this->yesNo->toOptionArray();
                    if (isset($statusValue[$status]["label"])) {
                        $item['status'] = $statusValue[$status]["label"]->getText();
                    }
                }
            }
        }

        return $dataSource;
    }
}

This is how it will look

Happy Coding…

Leave a Reply

Your email address will not be published. Required fields are marked *.

*
*
You may use these <abbr title="HyperText Markup Language">HTML</abbr> tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>