Magento 2 – How to Create Action Buttons in Grid

admingridmagento2

How can I create action buttons in each row in magento2 admin grid. I have made this custom grid from my custom model and data is coming from my custom table that I have created using installer. The data is coming properly into the grid. But I am not getting any clue on creating the action buttons.

ui_component/rent_grid.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">
    <!--Declare data source, columns list, button...-->
    <argument name="data" xsi:type="array">
        <item name="js_config" xsi:type="array">
            <item name="provider" xsi:type="string">rent_grid.rent_grid_data_source</item>
            <item name="deps" xsi:type="string">rent_grid.rent_grid_data_source</item>
            <!--Declare the data source name which will be defined below-->
        </item>
        <item name="spinner" xsi:type="string">rent_columns</item>
        <!--Declare the listing of columns which will be defined below-->
        <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 Request</item>
                <item name="class" xsi:type="string">primary</item>
                <item name="url" xsi:type="string">*/*/new</item>
            </item>
            <!--The button on the top of the Grid-->
        </item>
    </argument>
    <dataSource name="rent_grid_data_source">
        <!--The 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">rent_grid_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">
        <filterSearch name="fulltext">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="provider" xsi:type="string">rent_grid.rent_grid_data_source</item>
                    <item name="chipsProvider" xsi:type="string">rent_grid.rent_grid.listing_top.listing_filters_chips</item>
                    <item name="storageConfig" xsi:type="array">
                        <item name="provider" xsi:type="string">rent_grid.rent_grid.listing_top.bookmarks</item>
                        <item name="namespace" xsi:type="string">current.search</item>
                    </item>
                </item>
            </argument>
        </filterSearch>
        <container name="listing_top">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="template" xsi:type="string">ui/grid/toolbar</item>
                </item>
            </argument>
        </container>
        <bookmark name="bookmarks">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="storageConfig" xsi:type="array">
                        <item name="namespace" xsi:type="string">rent_grid</item>
                    </item>
                </item>
            </argument>
        </bookmark>
        <component name="columns_controls">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="columnsData" xsi:type="array">
                        <item name="provider" xsi:type="string">rent_grid.rent_grid.rent_grid_columns</item>
                    </item>
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/controls/columns</item>
                    <item name="displayArea" xsi:type="string">dataGridActions</item>
                </item>
            </argument>
        </component>
        <filters name="listing_filters">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="columnsProvider" xsi:type="string">rent_grid.rent_grid.rent_grid_columns</item>
                    <item name="storageConfig" xsi:type="array">
                        <item name="provider" xsi:type="string">rent_grid.rent_grid.listing_top.bookmarks</item>
                        <item name="namespace" xsi:type="string">current.filters</item>
                    </item>
                    <item name="childDefaults" xsi:type="array">
                        <item name="provider" xsi:type="string">rent_grid.rent_grid.listing_top.listing_filters</item>
                        <item name="imports" xsi:type="array">
                            <item name="visible" xsi:type="string">rent_grid.rent_grid.rent_grid_columns.${ $.index }:visible</item>
                        </item>
                    </item>
                </item>
            </argument>
        </filters>
        <massaction name="listing_massaction">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="selectProvider" xsi:type="string">rent_grid.rent_grid.rent_grid_columns.ids</item>
                    <item name="component" xsi:type="string">Magento_Ui/js/grid/tree-massactions</item>
                    <item name="indexField" xsi:type="string">entity_id</item>
                </item>
            </argument>
            <action name="reject">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="type" xsi:type="string">rejected</item>
                        <item name="label" xsi:type="string" translate="true">Reject</item>
                        <item name="url" xsi:type="url" path="*/*/massDelete"/>
                        <item name="confirm" xsi:type="array">
                            <item name="title" xsi:type="string" translate="true">Reject items</item>
                            <item name="message" xsi:type="string" translate="true">Are you sure to reject selected Requests?</item>
                        </item>
                    </item>
                </argument>
            </action>
            <action name="status">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="type" xsi:type="string">status</item>
                        <item name="label" xsi:type="string" translate="true">Accept</item>
                    </item>
                </argument>
                <!-- <argument name="actions" xsi:type="array">
                    <item name="0" xsi:type="array">
                        <item name="type" xsi:type="string">delivered</item>
                        <item name="label" xsi:type="string" translate="true">Delivered</item>
                        <item name="url" xsi:type="url" path="catalog/product/massStatus">
                            <param name="status">1</param>
                        </item>
                    </item>
                    <item name="1" xsi:type="array">
                        <item name="type" xsi:type="string">complete</item>
                        <item name="label" xsi:type="string" translate="true">Returned</item>
                        <item name="url" xsi:type="url" path="catalog/product/massStatus">
                            <param name="status">2</param>
                        </item>
                    </item>
                </argument> -->
            </action>
        </massaction>
        <paging name="listing_paging">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="storageConfig" xsi:type="array">
                        <item name="provider" xsi:type="string">rent_grid.rent_grid.listing_top.bookmarks</item>
                        <item name="namespace" xsi:type="string">current.paging</item>
                    </item>
                    <item name="selectProvider" xsi:type="string">rent_grid.rent_grid.rent_grid_columns.ids</item>
                </item>
            </argument>
        </paging>
        <exportButton name="export_button">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="selectProvider" xsi:type="string">rent_grid.rent_grid.rent_grid_columns.ids</item>
                </item>
            </argument>
        </exportButton>
    </listingToolbar>
    <columns name="rent_columns">
        <!--The list of columns-->
        <selectionsColumn name="ids">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <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">text</item>
                    <item name="sorting" xsi:type="string">asc</item>
                    <item name="sortOrder" xsi:type="number">0</item>
                    <item name="label" xsi:type="string" translate="true">Request ID</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="sorting" xsi:type="string">asc</item>
                    <item name="sortOrder" xsi:type="number">10</item>
                    <item name="label" xsi:type="string" translate="true">Customer Name</item>
                </item>
            </argument>
        </column>
        <column name="email">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">text</item>
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="sortOrder" xsi:type="number">20</item>
                    <item name="label" xsi:type="string" translate="true">Email Id</item>
                </item>
            </argument>
        </column>
        <column name="phone">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">text</item>
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="sortOrder" xsi:type="number">30</item>
                    <item name="label" xsi:type="string" translate="true">Phone Number</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="sorting" xsi:type="string">asc</item>
                    <item name="sortOrder" xsi:type="number">40</item>
                    <item name="label" xsi:type="string" translate="true">Product Name</item>
                </item>
            </argument>
        </column>
        <column name="sku">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">text</item>
                    <item name="dataType" xsi:type="string">text</item>
                        <item name="sortOrder" xsi:type="number">50</item>
                    <item name="label" xsi:type="string" translate="true">SKU</item>
                </item>
            </argument>
        </column>
        <column name="status">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">text</item>
                    <item name="dataType" xsi:type="string">text</item>
                        <item name="sortOrder" xsi:type="number">60</item>
                    <item name="label" xsi:type="string" translate="true">Status</item>
                </item>
            </argument>
        </column>
        <column name="rental_time">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">text</item>
                    <item name="dataType" xsi:type="string">text</item>
                        <item name="sortOrder" xsi:type="number">70</item>
                    <item name="label" xsi:type="string" translate="true">Rental Time</item>
                </item>
            </argument>
        </column>
        <column name="qty">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">text</item>
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="sortOrder" xsi:type="number">80</item>
                    <item name="label" xsi:type="string" translate="true">Quantity</item>
                </item>
            </argument>
        </column>
        <column name="time" 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="sortOrder" xsi:type="number">70</item>
                    <item name="label" xsi:type="string" translate="true">Request Date</item>
                </item>
            </argument>
        </column>
        <actionsColumn name="actions">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="indexField" xsi:type="string">id</item>
                    <item name="sortOrder" xsi:type="number">200</item>
                </item>
            </argument>
        </actionsColumn>
    </columns>

</listing>

Best Answer

First of all, we need to define the action node in your ui xml.

<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    ......

    <columns name="rent_columns">
        ......
        <actionsColumn name="actions" class="Vendor\Module\Ui\Component\Listing\Column\Actions">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="indexField" xsi:type="string">entity_id</item>
                </item>
            </argument>
        </actionsColumn>
    </columns>
</listing>

Build the action class:

app/code/Vendor/Module/Ui/Component/Listing/Column/Actions.php

<?php

namespace Vendor\Module\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 Vendor\Module\Block\Adminhtml\Module\Grid\Renderer\Action\UrlBuilder;
use Magento\Framework\UrlInterface;

class Actions extends Column
{
    /** Url path */
    const URL_PATH_EDIT = 'your/url/edit';
    const URL_PATH_DELETE = 'your/url/delete';

    /** @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['entity_id'])) {
                    $item[$name]['edit'] = [
                        'href' => $this->urlBuilder->getUrl(self::URL_PATH_EDIT, ['entity_id' => $item['entity_id']]),
                        'label' => __('Edit')
                    ];
                    $item[$name]['delete'] = [
                        'href' => $this->urlBuilder->getUrl(self::URL_PATH_DELETE, ['entity_id' => $item['entity_id']]),
                        'label' => __('Delete'),
                        'confirm' => [
                            'title' => __('Delete ${ $.$data.title }'),
                            'message' => __('Are you sure you wan\'t to delete a ${ $.$data.title } record?')
                        ]
                    ];
                }
            }
        }
        return $dataSource;
    }
}

Url builder class:

app/code/Vendor/Module/Block/Adminhtml/Module/Grid/Renderer/Action/UrlBuilder.php

<?php

namespace Vendor\Module\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;
    }
}

Remember to create the controller actions

We need to create the controller actions:

/** Url path */
const URL_PATH_EDIT = 'your/url/edit';
const URL_PATH_DELETE = 'your/url/delete';