HowTo: Add a Button using a Ui Component in Magento 2
On this page
Buttons in the admin used to be a one liner in Magento 1. In Magento 2, when your page is a Ui Component, you add a button through the component: you declare it in the XML and back it with a small PHP class that provides its configuration. It feels like more work at first, but it is actually cleaner because every button becomes testable and reusable.
Declare the buttons in the form
The buttons of a form live in its <settings> node. Each one points at a class that implements
ButtonProviderInterface.
<?xml version="1.0"?>
<!-- app/code/Vendor/Module/view/adminhtml/ui_component/vendor_entity_form.xml -->
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<settings>
<buttons>
<button name="save" class="Vendor\Module\Block\Adminhtml\Entity\Edit\SaveButton"/>
<button name="back" class="Vendor\Module\Block\Adminhtml\Entity\Edit\BackButton"/>
</buttons>
</settings>
</form>The button class
Each button class returns an array with its label, class, order and, most importantly, what it does when clicked.
<?php
/** app/code/Vendor/Module/Block/Adminhtml/Entity/Edit/BackButton.php */
namespace Vendor\Module\Block\Adminhtml\Entity\Edit;
use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;
use Magento\Backend\Block\Widget\Context;
class BackButton implements ButtonProviderInterface
{
/**
* @var Context
*/
private $context;
/**
* @param Context $context
*/
public function __construct(Context $context)
{
$this->context = $context;
}
/**
* @return array
*/
public function getButtonData()
{
return [
'label' => __('Back'),
'on_click' => sprintf("location.href = '%s';", $this->context->getUrl('*/*/')),
'class' => 'back',
'sort_order' => 10,
];
}
}on_clickis plain JavaScript, handy for a simple redirect.- For the Save button you usually skip
on_clickand instead return adata_attributewith aform-roleofsave, so it submits the form the Ui Component way.
A button inside a grid (listing)
If instead you want a button on top of a listing, you add it in the listing XML with a container that points to a
button block, the pattern is the same idea, a small provider class returning the button data.
Deploy the admin static content and flush the cache, and your buttons appear exactly where you declared them.
Hope this helps.
If you have any question or know a better way to achieve this, feel free to share in the comments below.