:::: MENU ::::

Adding a damn button to a Magento admin form

Today I got mad at Magento. Again. 🙃

It’s like that toxic relationship that sometimes gives you joy, but when it decides to play hardball, it ruins your afternoon.

Today’s episode of “things that should be easy but turn out to be a total pain-in-the-ass”: adding a simple button to a Magento admin form.

Specifically, to a form like this:

[IMAGE]

The worst part? It looked easy… but neither ChatGPT, nor Claude, nor the mother of all AIs gave me a decent solution. All of them went with overcomplicated answers, while the real solution was way simpler.

<field name="chat_button"
       class="Vendor\Module\Ui\Component\ChatButton"
       component="Vendor_Module/js/form/component/chat-button"
       template="Magento_Theme/form/button-field" formElement="button">
    <settings>
        <dataScope>chat_button</dataScope>
    </settings>
    <formElements>
        <button>
            <settings>
                <title translate="true">Chat</title>
            </settings>
        </button>
    </formElements>
</field>

The problem is that there isn’t a single example of this in a “normal” form. The only place you see something similar is in the system configuration — which is very peculiar, and even though it shares some components, it’s not the same thing… well, if you’re here reading this, you already knew that 😉.

Anyway, let’s cut to the chase. Besides the XML above (which obviously goes in your form, e.g. .../ui_component/my_form_form.xml), you’ll need to add a couple more things:

  • A JS component so it actually does something, because we don’t just want it decorating the page.
  • A PHP class to configure the button.

The PHP class (pretty simple)

Put it here:

app/code/Vendor/Module/Ui/Component/ChatButton.php
<?php

namespace Vendor\Module\Ui\Component;

use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Ui\Component\Form\Field;

class ChatButton extends Field
{
/**
* ResetButton constructor
*
* @param ContextInterface $context
* @param UiComponentFactory $uiComponentFactory
* @param \Magento\Framework\View\Element\UiComponentInterface[] $components
* @param array $data
* @param ScopeConfigInterface $scopeConfig
*/
public function __construct(
ContextInterface $context,
UiComponentFactory $uiComponentFactory,
$components,
array $data,
ScopeConfigInterface $scopeConfig
) {
$this->scopeConfig = $scopeConfig;
parent::__construct($context, $uiComponentFactory, $components, $data);
}

/**
* Add js listener to chat button
*
* @return void
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function prepare()
{
parent::prepare();

$this->_data['config']['actions'] = [
[
'actionName' => 'sendChat',
'targetName' => '${ $.name }',
'__disableTmpl' => ['targetName' => false],
//'params' => [
// 'test' => 'text'
//]
]
];
}
}

The only thing you really care about here is the sendChat at the end. That’s the method in the JS component that will be called when you click the button. The rest is fluff — just copy/paste it as is.

Need to pass some parameters? That’s what the params I left commented out right below is for.

The JS component (even simpler)

Place it here:

app/code/Vendor/Module/view/adminhtml/web/js/form/component/chat-button.js
/**
* @api
*/
define
([
'Magento_Ui/js/form/components/button',
'uiRegistry'
], function (Button, registry) {
'use strict';

return Button.extend({
defaults: {
label: '',
buttonTpl: 'Magento_Theme/form/element/button'
},

sendChat: function () {
console.log('ACTION executed')
}
});
});

A component that extends Magento’s button and hooks into our sendChat function. When you click it, it runs and… magic.

That’s it — leaving it here so you don’t waste an hour arguing with Magento like I did. 😅




So, what do you think ?