Come creare un pulsante nella sezione di configurazione di Magento 2?


12

Come posso aggiungere un pulsante nella sezione di configurazione del backend di Magento 2 e chiamare un semplice metodo PHP quando faccio clic sul pulsante?

Questa chiamata al metodo può essere una chiamata AJAX.

Risposte:


19

Descriveremo la soluzione usando il nostro modulo Altri anche acquistati come esempio, in cui MageWorx - un nome del fornitore e AlsoBought - un nome del modulo:

Innanzitutto, è necessario aggiungere il pulsante come campo nel file di configurazione. (mageworx_collect come esempio):

app / code / MageWorx / AlsoBought / etc / adminhtml / system.xml

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2016 MageWorx. All rights reserved.
 * See LICENSE.txt for license details.
 */
 -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <tab id="mageworx" sortOrder="2001">
            <label>MageWorx</label>
        </tab>
        <section id="mageworx_alsobought" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="0">
            <label>Also Bought</label>
            <tab>mageworx</tab>
            <resource>MageWorx_AlsoBought::config</resource>
            <group id="general" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                <label>General</label>
                <field id="mageworx_collect" translate="label comment" type="button" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="0">
                    <frontend_model>MageWorx\AlsoBought\Block\System\Config\Collect</frontend_model>
                    <label>Collect all available data (in separate table)</label>
                </field>
            </group>
        </section>
    </system>
</config>

Per disegnare questo pulsante di campo MageWorx\AlsoBought\Block\System\Config\Collectverrà utilizzato il modello frontend . Crealo:

app / code / MageWorx / AlsoBought / blocchi / System / Config / Collect.php

<?php
/**
 * Copyright © 2016 MageWorx. All rights reserved.
 * See LICENSE.txt for license details.
 */

namespace MageWorx\AlsoBought\Block\System\Config;

use Magento\Backend\Block\Template\Context;
use Magento\Config\Block\System\Config\Form\Field;
use Magento\Framework\Data\Form\Element\AbstractElement;

class Collect extends Field
{
    /**
     * @var string
     */
    protected $_template = 'MageWorx_AlsoBought::system/config/collect.phtml';

    /**
     * @param Context $context
     * @param array $data
     */
    public function __construct(
        Context $context,
        array $data = []
    ) {
        parent::__construct($context, $data);
    }

    /**
     * Remove scope label
     *
     * @param  AbstractElement $element
     * @return string
     */
    public function render(AbstractElement $element)
    {
        $element->unsScope()->unsCanUseWebsiteValue()->unsCanUseDefaultValue();
        return parent::render($element);
    }

    /**
     * Return element html
     *
     * @param  AbstractElement $element
     * @return string
     */
    protected function _getElementHtml(AbstractElement $element)
    {
        return $this->_toHtml();
    }

    /**
     * Return ajax url for collect button
     *
     * @return string
     */
    public function getAjaxUrl()
    {
        return $this->getUrl('mageworx_alsobought/system_config/collect');
    }

    /**
     * Generate collect button html
     *
     * @return string
     */
    public function getButtonHtml()
    {
        $button = $this->getLayout()->createBlock(
            'Magento\Backend\Block\Widget\Button'
        )->setData(
            [
                'id' => 'collect_button',
                'label' => __('Collect Data'),
            ]
        );

        return $button->toHtml();
    }
}
?>

Questo è un tipico modello di campo. Il pulsante viene disegnato usando il getButtonHtml()metodo Utilizzare il getAjaxUrl()metodo per ottenere un URL.

Quindi, avrai bisogno del modello:

app / code / MageWorx / AlsoBought / view / adminhtml / templates / system / config / collect.phtml

<?php
/**
 * Copyright © 2016 MageWorx. All rights reserved.
 * See LICENSE.txt for license details.
 */
?>
<?php /* @var $block \MageWorx\AlsoBought\Block\System\Config\Collect */ ?>

<script>
    require([
        'jquery',
        'prototype'
    ], function(jQuery){

        var collectSpan = jQuery('#collect_span');

        jQuery('#collect_button').click(function () {
            var params = {};
            new Ajax.Request('<?php echo $block->getAjaxUrl() ?>', {
                parameters:     params,
                loaderArea:     false,
                asynchronous:   true,
                onCreate: function() {
                    collectSpan.find('.collected').hide();
                    collectSpan.find('.processing').show();
                    jQuery('#collect_message_span').text('');
                },
                onSuccess: function(response) {
                    collectSpan.find('.processing').hide();

                    var resultText = '';
                    if (response.status > 200) {
                        resultText = response.statusText;
                    } else {
                        resultText = 'Success';
                        collectSpan.find('.collected').show();
                    }
                    jQuery('#collect_message_span').text(resultText);

                    var json = response.responseJSON;
                    if (typeof json.time != 'undefined') {
                        jQuery('#row_mageworx_alsobought_general_collect_time').find('.value .time').text(json.time);
                    }
                }
            });
        });

    });
</script>

<?php echo $block->getButtonHtml() ?>
<span class="collect-indicator" id="collect_span">
    <img class="processing" hidden="hidden" alt="Collecting" style="margin:0 5px" src="<?php echo $block->getViewFileUrl('images/process_spinner.gif') ?>"/>
    <img class="collected" hidden="hidden" alt="Collected" style="margin:-3px 5px" src="<?php echo $block->getViewFileUrl('images/rule_component_apply.gif') ?>"/>
    <span id="collect_message_span"></span>
</span>

Dovrai riscrivere la parte del codice in base alle tue esigenze, ma lo lascerò come esempio. Il metodo di richiesta Ajax onCreatee onSuccessdovrebbe soddisfare le tue esigenze. Inoltre, puoi rimuovere l' <span class="collect-indicator" id="collect_span">elemento. Lo usiamo per visualizzare il caricamento (spinner) e il risultato dell'azione.

Inoltre, avrai bisogno di un controller, in cui verranno elaborate tutte le operazioni richieste e di un router.

app / code / MageWorx / AlsoBought / etc / adminhtml / routes.xml

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2016 MageWorx. All rights reserved.
 * See LICENSE.txt for license details.
 */
 -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="admin">
        <route id="mageworx_alsobought" frontName="mageworx_alsobought">
            <module name="MageWorx_AlsoBought" before="Magento_Backend" />
        </route>
    </router>
</config>

app / code / MageWorx / AlsoBought / Controller / Adminhtml / System / Config / Collect.php

<?php
/**
 * Copyright © 2016 MageWorx. All rights reserved.
 * See LICENSE.txt for license details.
 */

namespace MageWorx\AlsoBought\Controller\Adminhtml\System\Config;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Controller\Result\JsonFactory;
use MageWorx\AlsoBought\Helper\Data;

class Collect extends Action
{

    protected $resultJsonFactory;

    /**
     * @var Data
     */
    protected $helper;

    /**
     * @param Context $context
     * @param JsonFactory $resultJsonFactory
     * @param Data $helper
     */
    public function __construct(
        Context $context,
        JsonFactory $resultJsonFactory,
        Data $helper
    )
    {
        $this->resultJsonFactory = $resultJsonFactory;
        $this->helper = $helper;
        parent::__construct($context);
    }

    /**
     * Collect relations data
     *
     * @return \Magento\Framework\Controller\Result\Json
     */
    public function execute()
    {
        try {
            $this->_getSyncSingleton()->collectRelations();
        } catch (\Exception $e) {
            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
        }

        $lastCollectTime = $this->helper->getLastCollectTime();
        /** @var \Magento\Framework\Controller\Result\Json $result */
        $result = $this->resultJsonFactory->create();

        return $result->setData(['success' => true, 'time' => $lastCollectTime]);
    }

    /**
     * Return product relation singleton
     *
     * @return \MageWorx\AlsoBought\Model\Relation
     */
    protected function _getSyncSingleton()
    {
        return $this->_objectManager->get('MageWorx\AlsoBought\Model\Relation');
    }

    protected function _isAllowed()
    {
        return $this->_authorization->isAllowed('MageWorx_AlsoBought::config');
    }
}
?>

PS Questo è l'esempio funzionante del nostro modulo MageWorx Altri acquistati . Se vuoi studiarlo, puoi scaricarlo gratuitamente.


Ho usato la tua risposta, ma come posso chiamare le funzioni definite in Controller/Adminhtml/System/Config/Collection.php?
Condor

1

Lo controlli anche in fornitore / magento / module-customer / etc / adminhtml / system.xml per il pulsante. Sotto il codice controlla nel percorso sopra. Crea frontend_model come questo fornitore / magento / module-customer / Block / Adminhtml / System / Config / Validatevat.php .

<group id="store_information">
     <field id="validate_vat_number" translate="button_label" sortOrder="62" showInDefault="1" showInWebsite="1" showInStore="0">
           <button_label>Validate VAT Number</button_label>
           <frontend_model>Magento\Customer\Block\Adminhtml\System\Config\Validatevat</frontend_model>
     </field>
</group>

Sopra il percorso per il tuo riferimento. Ora crea il giusto per il tuo modulo.


1

Per aggiungere un pulsante nella configurazione del sistema ed eseguire una funzione personalizzata, è necessario creare frontend_modelper eseguire il rendering del pulsante. Nel modello di frontend_model, puoi scrivere la tua logica Ajax.

Ecco un esempio:

System.xml

Path: /root_path/magento2/app/code/Skumar/Sync/etc/adminhtml/system.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
    <tab id="skumar" translate="label" sortOrder="1000">
        <label>Skumar Extensions</label>
    </tab>
    <section id="sync" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1">
        <label>Sync</label>
        <tab>skumar</tab>
        <resource>Skumar_Sync::config</resource>
        <group id="general" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
            <label>Configuration</label>
            <field id="build_indexes" translate="label comment tooltip" type="button" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="0">
                <label>Build Search Indexes</label>
                <frontend_model>Skumar\Sync\Block\System\Config\Synchronize</frontend_model>
            </field>
        </group>
    </section>
</system>
</config>

Modello frontend

Questa classe sarà responsabile del rendering del pulsante html. getButtonHtml()La funzione genererà il pulsante html.

Path: /{root_path}/magento2/app/code/Skumar/Sync/Block/System/Config/Synchronize.php

<?php
/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Skumar\Sync\Block\System\Config;

/**
 * Synchronize button renderer
 */
class Synchronize extends \Magento\Config\Block\System\Config\Form\Field
{
    /**
     * @var string
     */
    protected $_template = 'Skumar_Sync::system/config/synchronize.phtml';

    /**
     * @param \Magento\Backend\Block\Template\Context $context
     * @param array $data
     */
    public function __construct(
        \Magento\Backend\Block\Template\Context $context,
        array $data = []
    ) {
        parent::__construct($context, $data);
    }

    /**
     * Remove scope label
     *
     * @param  \Magento\Framework\Data\Form\Element\AbstractElement $element
     * @return string
     */
    public function render(\Magento\Framework\Data\Form\Element\AbstractElement $element)
    {
        $element->unsScope()->unsCanUseWebsiteValue()->unsCanUseDefaultValue();
        return parent::render($element);
    }

    /**
     * Return element html
     *
     * @param  \Magento\Framework\Data\Form\Element\AbstractElement $element
     * @return string
     *
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    protected function _getElementHtml(\Magento\Framework\Data\Form\Element\AbstractElement $element)
    {
        return $this->_toHtml();
    }

    /**
     * Return ajax url for synchronize button
     *
     * @return string
     */
    public function getAjaxSyncUrl()
    {
        return $this->getUrl('sync/system_config/synchronize');
    }

    /**
     * Generate synchronize button html
     *
     * @return string
     */
    public function getButtonHtml()
    {
        $button = $this->getLayout()->createBlock(
            'Magento\Backend\Block\Widget\Button'
        )->setData(
            [
                'id' => 'synchronize_button',
                'label' => __('Synchronize'),
            ]
        );

        return $button->toHtml();
    }
}

Qui, abbiamo il nostro frontend_modelpulsante per il rendering. Ora, dobbiamo creare una classe controller che gestirà la nostra richiesta Ajax.

Synchronize.php

Path: /{root_path}/magento2/app/code/Skumar/Sync/Controller/Adminhtml/System/Config/Synchronize.php

<?php
/**
 *
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Skumar\Sync\Controller\Adminhtml\System\Config;

use \Magento\Catalog\Model\Product\Visibility;

class Synchronize extends \Magento\Backend\App\Action
{
    /**
     * @var \Psr\Log\LoggerInterface
     */
    protected $_logger;

    /**
     * @param \Magento\Backend\App\Action\Context $context
     * @param \Psr\Log\LoggerInterface $logger
     */
    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Psr\Log\LoggerInterface $logger
    ) {
        $this->_logger = $logger;
        parent::__construct($context);
    }


    /**
     * Synchronize
     *
     * @return void
     */
    public function execute()
    {
        $this->_logger->debug('Sync Starts!!');
        // do whatever you want to do
    }
}

Abbiamo una getAjaxSyncUrl()nostra funzione frontend_modelche restituirà l'URL di questo controller. Inoltre, v'è variabile $_templatein frontend_modelche contiene il percorso del nostro file di modello per il nostro renderer.

synchronize.phtml

Path: /{root_path}/magento2/app/code/Skumar/Sync/view/adminhtml/templates/system/config/synchronize.phtml

<?php /* @var $block \Skumar\Sync\Block\System\Config\Synchronize */ ?>
<script>
require([
    'jquery',
    'prototype',
], function(jQuery){
    function syncronize() {
        params = {
        };

        new Ajax.Request('<?php /* @escapeNotVerified */ echo $block->getAjaxSyncUrl() ?>', {
            loaderArea:     false,
            asynchronous:   true,
            parameters:     params,
            onSuccess: function(transport) {
                var response = JSON.parse(transport.responseText);
            }
        });
    }

    jQuery('#synchronize_button').click(function () {
        syncronize();
    });
});
</script>

<?php echo $block->getButtonHtml() ?>

Puoi vedere nel modello, facendo clic sul pulsante, attiverà una richiesta Ajax al controller definito in forntend_model.

Spero che sarà di aiuto.


1

È necessario definire un frontend_modelcampo personalizzato per il rendering nella configurazione. Puoi ricevere aiuto da questo link .


1

Per creare un pulsante nella sezione di configurazione del back-end, è necessario eseguire questi passaggi:

Passaggio 1: Aggiungi un campo è il pulsante nel file system.xmlcome questi script:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <tab id="namespace" translate="label" sortOrder="400">
            <label>Namspace Module</label>
        </tab>
        <section id="section" translate="label" type="text" sortOrder="300" showInDefault="1" showInWebsite="1" showInStore="1">
            <class>separator-top</class>
            <label>Section Name</label>
            <tab>tab</tab>
            <resource>Namespace_Module::resource</resource>
            <group id="group_id" translate="label" type="text" sortOrder="5" showInDefault="1" showInWebsite="1" showInStore="1">
                <label>Group Label</label>
                <field id="button" type="text" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
                    <button_label>Button</button_label>
                    <frontend_model>Namspace\Module\Block\System\Config\Button</frontend_model>
                </field>
            </group>
        </section>
    </system>
</config>

Passaggio 2: creare il pulsante di sistema Block:

Crea file Namspace\Module\Block\System\Config\Button.php:

<?php

namespace Namespace\Module\Block\System\Config;


use Magento\Backend\Block\Template\Context;
use Magento\Customer\Model\Session;
use Magento\Framework\ObjectManagerInterface;

class Button extends \Magento\Config\Block\System\Config\Form\Field {

    /**
     * Path to block template
     */
    const CHECK_TEMPLATE = 'system/config/button.phtml';

    public function __construct(Context $context,
                                $data = array())
    {
        parent::__construct($context, $data);
    }

    /**
     * Set template to itself
     *
     * @return $this
     */
    protected function _prepareLayout()
    {
        parent::_prepareLayout();
        if (!$this->getTemplate()) {
            $this->setTemplate(static::CHECK_TEMPLATE);
        }
        return $this;
    }

    /**
     * Render button
     *
     * @param  \Magento\Framework\Data\Form\Element\AbstractElement $element
     * @return string
     */
    public function render(\Magento\Framework\Data\Form\Element\AbstractElement $element)
    {
        // Remove scope label
        $element->unsScope()->unsCanUseWebsiteValue()->unsCanUseDefaultValue();
        return parent::render($element);
    }

    protected function _getElementHtml(\Magento\Framework\Data\Form\Element\AbstractElement $element)
    {
        $this->addData(
            [
                'url' => $this->getUrl(),
                'html_id' => $element->getHtmlId(),
            ]
        );

        return $this->_toHtml();
    }

    protected function getUrl()
    {
        return "url"; //This is your real url you want to redirect when click on button
    }

} 

Passaggio 3: creare il file view/adminhtml/templates/system/config/button.phtml:

<div class="pp-buttons-container">
    <p>
        <button id="<?php echo $block->getHtmlId() ?>" onclick="setLocation('<?php /* @escapeNotVerified */ echo $block->getUrl() ?>')" type="button">
            <?php /* @escapeNotVerified */ echo __('Click Here') ?>
        </button>
    </p>
</div>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.