{"id":5617,"date":"2016-08-08T11:06:16","date_gmt":"2016-08-08T11:06:16","guid":{"rendered":"https:\/\/blog.mageworx.com\/?p=5617"},"modified":"2022-03-23T08:34:06","modified_gmt":"2022-03-23T08:34:06","slug":"creating-a-button-in-magento-2-configuration-section","status":"publish","type":"post","link":"https:\/\/www.mageworx.com\/blog\/creating-a-button-in-magento-2-configuration-section","title":{"rendered":"Creating a Button in Magento 2 Configuration Section"},"content":{"rendered":"\n<!-- SEO Ultimate (http:\/\/www.seodesignsolutions.com\/wordpress-seo\/) - Code Inserter module -->\n<!-- Google Tag Manager (noscript) -->\r\n<noscript><iframe src=\"https:\/\/www.googletagmanager.com\/ns.html?id=GTM-5DTCW7B8\"\r\nheight=\"0\" width=\"0\" style=\"display:none;visibility:hidden\"><\/iframe><\/noscript>\r\n<!-- End Google Tag Manager (noscript) -->\n<!-- \/SEO Ultimate -->\n\n<span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\"> 3<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span><p>A lot of our users ask how to add a button in Magento 2 backend configuration section and call a simple PHP method when clicking on it.<\/p>\n<p>In fact, that&#8217;s quite easy to do.<\/p>\n<p>I&#8217;ll describe the solution on the example of our new free <a href=\"https:\/\/www.mageworx.com\/magento-2-others-also-bought.html\">Others Also Bought<\/a> extension for Magento 2, where <strong>MageWorx<\/strong> \u2013 is a vendor&#8217;s name and <strong>AlsoBought<\/strong> \u2013 is a name of the extension.<\/p>\n<p>First, you need to add a button as a field in the<em> Configuration<\/em> file (<em>mageworx_collect<\/em> as an example):<!--more--><\/p>\n<pre class=\"theme:github font:courier-new font-size:16 line-height:28 lang:default decode:true \">app\/code\/MageWorx\/AlsoBought\/etc\/adminhtml\/system.xml<\/pre>\n<pre class=\"theme:github font:courier-new font-size:16 line-height:18 lang:default decode:true \">&lt;?xml version=\"1.0\"?&gt;\n&lt;!--\n\/**\n * Copyright \u00a9 2016 MageWorx. All rights reserved.\n * See LICENSE.txt for license details.\n *\/\n --&gt;\n&lt;config xmlns:xsi=\"https:\/\/www.w3.org\/2001\/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"urn:magento:module:Magento_Config:etc\/system_file.xsd\"&gt;\n    &lt;system&gt;\n        &lt;tab id=\"mageworx\" sortOrder=\"2001\"&gt;\n            &lt;label&gt;MageWorx&lt;\/label&gt;\n        &lt;\/tab&gt;\n        &lt;section id=\"mageworx_alsobought\" translate=\"label\" type=\"text\" sortOrder=\"100\" showInDefault=\"1\" showInWebsite=\"1\" showInStore=\"0\"&gt;\n            &lt;label&gt;Also Bought&lt;\/label&gt;\n            &lt;tab&gt;mageworx&lt;\/tab&gt;\n            &lt;resource&gt;MageWorx_AlsoBought::config&lt;\/resource&gt;\n            &lt;group id=\"general\" translate=\"label\" type=\"text\" sortOrder=\"10\" showInDefault=\"1\" showInWebsite=\"1\" showInStore=\"1\"&gt;\n                &lt;label&gt;General&lt;\/label&gt;\n                &lt;field id=\"mageworx_collect\" translate=\"label comment\" type=\"button\" sortOrder=\"10\" showInDefault=\"1\" showInWebsite=\"1\" showInStore=\"0\"&gt;\n                    &lt;frontend_model&gt;MageWorx\\AlsoBought\\Block\\System\\Config\\Collect&lt;\/frontend_model&gt;\n                    &lt;label&gt;Collect all available data (in separate table)&lt;\/label&gt;\n                &lt;\/field&gt;\n            &lt;\/group&gt;\n        &lt;\/section&gt;\n    &lt;\/system&gt;\n&lt;\/config&gt;<\/pre>\n<p>To draw this field-button, I use the frontend <em><code>MageWorx\\AlsoBought\\Block\\System\\Config\\Collect<\/code><\/em> model. This is how to create it:<\/p>\n<pre class=\"theme:github font:courier-new font-size:16 line-height:18 lang:default decode:true \">app\/code\/MageWorx\/AlsoBought\/Block\/System\/Config\/Collect.php<\/pre>\n<pre class=\"theme:github font:courier-new font-size:16 line-height:18 lang:default decode:true\">&lt;?php\n\/**\n * Copyright \u00a9 2016 MageWorx. All rights reserved.\n * See LICENSE.txt for license details.\n *\/\n\nnamespace MageWorx\\AlsoBought\\Block\\System\\Config;\n\nuse Magento\\Backend\\Block\\Template\\Context;\nuse Magento\\Config\\Block\\System\\Config\\Form\\Field;\nuse Magento\\Framework\\Data\\Form\\Element\\AbstractElement;\n\nclass Collect extends Field\n{\n    \/**\n     * @var string\n     *\/\n    protected $_template = 'MageWorx_AlsoBought::system\/config\/collect.phtml';\n\n    \/**\n     * @param Context $context\n     * @param array $data\n     *\/\n    public function __construct(\n        Context $context,\n        array $data = []\n    ) {\n        parent::__construct($context, $data);\n    }\n\n    \/**\n     * Remove scope label\n     *\n     * @param  AbstractElement $element\n     * @return string\n     *\/\n    public function render(AbstractElement $element)\n    {\n        $element-&gt;unsScope()-&gt;unsCanUseWebsiteValue()-&gt;unsCanUseDefaultValue();\n        return parent::render($element);\n    }\n\n    \/**\n     * Return element html\n     *\n     * @param  AbstractElement $element\n     * @return string\n     *\/\n    protected function _getElementHtml(AbstractElement $element)\n    {\n        return $this-&gt;_toHtml();\n    }\n\n    \/**\n     * Return ajax url for collect button\n     *\n     * @return string\n     *\/\n    public function getAjaxUrl()\n    {\n        return $this-&gt;getUrl('mageworx_alsobought\/system_config\/collect');\n    }\n\n    \/**\n     * Generate collect button html\n     *\n     * @return string\n     *\/\n    public function getButtonHtml()\n    {\n        $button = $this-&gt;getLayout()-&gt;createBlock(\n            'Magento\\Backend\\Block\\Widget\\Button'\n        )-&gt;setData(\n            [\n                'id' =&gt; 'collect_button',\n                'label' =&gt; __('Collect Data'),\n            ]\n        );\n\n        return $button-&gt;toHtml();\n    }\n}\n<\/pre>\n<p>This is a typical field model. The button is drawn using the <em><code>getButtonHtml()<\/code><\/em> method.<\/p>\n<p>To get a URL, you need to use the <em><code>getAjaxUrl()<\/code><\/em> method.<\/p>\n<p>Next, you will need to create a template:<\/p>\n<pre class=\"theme:github font:courier-new font-size:16 line-height:18 lang:default decode:true \">app\/code\/MageWorx\/AlsoBought\/view\/adminhtml\/templates\/system\/config\/collect.phtml<\/pre>\n<pre class=\"theme:github font:courier-new font-size:16 line-height:18 lang:default decode:true \">&lt;?php\n\/**\n * Copyright \u00a9 2016 MageWorx. All rights reserved.\n * See LICENSE.txt for license details.\n *\/\n?&gt;\n&lt;?php \/* @var $block \\MageWorx\\AlsoBought\\Block\\System\\Config\\Collect *\/ ?&gt;\n\n&lt;script&gt;\n    require([\n        'jquery',\n        'prototype'\n    ], function(jQuery){\n\n        var collectSpan = jQuery('#collect_span');\n\n        jQuery('#collect_button').click(function () {\n            var params = {};\n            new Ajax.Request('&lt;?php echo $block-&gt;getAjaxUrl() ?&gt;', {\n                parameters:     params,\n                loaderArea:     false,\n                asynchronous:   true,\n                onCreate: function() {\n                    collectSpan.find('.collected').hide();\n                    collectSpan.find('.processing').show();\n                    jQuery('#collect_message_span').text('');\n                },\n                onSuccess: function(response) {\n                    collectSpan.find('.processing').hide();\n\n                    var resultText = '';\n                    if (response.status &gt; 200) {\n                        resultText = response.statusText;\n                    } else {\n                        resultText = 'Success';\n                        collectSpan.find('.collected').show();\n                    }\n                    jQuery('#collect_message_span').text(resultText);\n\n                    var json = response.responseJSON;\n                    if (typeof json.time != 'undefined') {\n                        jQuery('#row_mageworx_alsobought_general_collect_time').find('.value .time').text(json.time);\n                    }\n                }\n            });\n        });\n\n    });\n&lt;\/script&gt;\n\n&lt;?php echo $block-&gt;getButtonHtml() ?&gt;\n&lt;span class=\"collect-indicator\" id=\"collect_span\"&gt;\n    &lt;img class=\"processing\" hidden=\"hidden\" alt=\"Collecting\" style=\"margin:0 5px\" src=\"&lt;?php echo $block-&gt;getViewFileUrl('images\/process_spinner.gif') ?&gt;\"\/&gt;\n    &lt;img class=\"collected\" hidden=\"hidden\" alt=\"Collected\" style=\"margin:-3px 5px\" src=\"&lt;?php echo $block-&gt;getViewFileUrl('images\/rule_component_apply.gif') ?&gt;\"\/&gt;\n    &lt;span id=\"collect_message_span\"&gt;&lt;\/span&gt;\n&lt;\/span&gt;\n<\/pre>\n<p>Note that in this case, you will have to rewrite a part of the code according to your needs. Below is an example of how you can do that.<\/p>\n<p>The AJAX request method <em><code>onCreate<\/code> <\/em>and <em><code>onSuccess<\/code><\/em> should suit your needs. Also, you can remove the <em><code>&lt;span class=\"collect-indicator\" id=\"collect_span\"&gt;<\/code><\/em> element. We use it to display the loading (spinner) process and the result of the action.<\/p>\n<p>Also, you will need a controller (where all further operations will be processed) and a router.<\/p>\n<pre class=\"theme:github font:courier-new font-size:16 line-height:18 lang:default decode:true \">app\/code\/MageWorx\/AlsoBought\/etc\/adminhtml\/routes.xml<\/pre>\n<pre class=\"theme:github font:courier-new font-size:16 line-height:18 lang:default decode:true \">&lt;?xml version=\"1.0\"?&gt;\n&lt;!--\n\/**\n * Copyright \u00a9 2016 MageWorx. All rights reserved.\n * See LICENSE.txt for license details.\n *\/\n --&gt;\n&lt;config xmlns:xsi=\"https:\/\/www.w3.org\/2001\/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"urn:magento:framework:App\/etc\/routes.xsd\"&gt;\n    &lt;router id=\"admin\"&gt;\n        &lt;route id=\"mageworx_alsobought\" frontName=\"mageworx_alsobought\"&gt;\n            &lt;module name=\"MageWorx_AlsoBought\" before=\"Magento_Backend\" \/&gt;\n        &lt;\/route&gt;\n    &lt;\/router&gt;\n&lt;\/config&gt;\n<\/pre>\n<pre class=\"theme:github font:courier-new font-size:16 line-height:18 lang:default decode:true \">app\/code\/MageWorx\/AlsoBought\/Controller\/Adminhtml\/System\/Config\/Collect.php<\/pre>\n<pre class=\"theme:github font:courier-new font-size:16 line-height:18 lang:default decode:true \">&lt;?php\n\/**\n * Copyright \u00a9 2016 MageWorx. All rights reserved.\n * See LICENSE.txt for license details.\n *\/\n\nnamespace MageWorx\\AlsoBought\\Controller\\Adminhtml\\System\\Config;\n\nuse Magento\\Backend\\App\\Action;\nuse Magento\\Backend\\App\\Action\\Context;\nuse Magento\\Framework\\Controller\\Result\\JsonFactory;\nuse MageWorx\\AlsoBought\\Helper\\Data;\n\nclass Collect extends Action\n{\n\n    protected $resultJsonFactory;\n\n    \/**\n     * @var Data\n     *\/\n    protected $helper;\n\n    \/**\n     * @param Context $context\n     * @param JsonFactory $resultJsonFactory\n     * @param Data $helper\n     *\/\n    public function __construct(\n        Context $context,\n        JsonFactory $resultJsonFactory,\n        Data $helper\n    )\n    {\n        $this-&gt;resultJsonFactory = $resultJsonFactory;\n        $this-&gt;helper = $helper;\n        parent::__construct($context);\n    }\n\n    \/**\n     * Collect relations data\n     *\n     * @return \\Magento\\Framework\\Controller\\Result\\Json\n     *\/\n    public function execute()\n    {\n        try {\n            $this-&gt;_getSyncSingleton()-&gt;collectRelations();\n        } catch (\\Exception $e) {\n            $this-&gt;_objectManager-&gt;get('Psr\\Log\\LoggerInterface')-&gt;critical($e);\n        }\n\n        $lastCollectTime = $this-&gt;helper-&gt;getLastCollectTime();\n        \/** @var \\Magento\\Framework\\Controller\\Result\\Json $result *\/\n        $result = $this-&gt;resultJsonFactory-&gt;create();\n\n        return $result-&gt;setData(['success' =&gt; true, 'time' =&gt; $lastCollectTime]);\n    }\n\n    \/**\n     * Return product relation singleton\n     *\n     * @return \\MageWorx\\AlsoBought\\Model\\Relation\n     *\/\n    protected function _getSyncSingleton()\n    {\n        return $this-&gt;_objectManager-&gt;get('MageWorx\\AlsoBought\\Model\\Relation');\n    }\n\n    protected function _isAllowed()\n    {\n        return $this-&gt;_authorization-&gt;isAllowed('MageWorx_AlsoBought::config');\n    }\n}\n?&gt;<\/pre>\n<p>That&#8217;s basically it.<\/p>\n<p>As I mentioned above, this is a working example from our MageWorx Others Also Bought module for Magento 2.&nbsp; If you want to further explore it, you can <a href=\"https:\/\/www.mageworx.com\/magento-2-others-also-bought.html\">download it from here<\/a> <strong>for FREE<\/strong>.<\/p>\n<p>Should you have any questions on the topic, feel free to drop me a line in the comments below.<\/p>\n","protected":false},"excerpt":{"rendered":"<p><span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\"> 3<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span>A lot of our users ask how to add a button in Magento 2 backend configuration section and call a simple PHP method when clicking on it. In fact, that&#8217;s quite easy to do. I&#8217;ll describe the solution on the example of our new free Others Also Bought extension for Magento 2, where MageWorx \u2013 [&hellip;]<\/p>\n","protected":false},"author":13,"featured_media":5836,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[425],"tags":[436],"class_list":{"0":"post-5617","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-magento-how-tos","8":"tag-developer-diaries"},"_links":{"self":[{"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/posts\/5617","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/users\/13"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/comments?post=5617"}],"version-history":[{"count":5,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/posts\/5617\/revisions"}],"predecessor-version":[{"id":15590,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/posts\/5617\/revisions\/15590"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/media\/5836"}],"wp:attachment":[{"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/media?parent=5617"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/categories?post=5617"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/tags?post=5617"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}