Magento 2 Modal Widget in Use

Magento 2 Modal Widget in Use
Implementation of a Module Version field for a Custom Module configuration by using JavaScript Modal Widget component from Magento 2 UI Library.

In this article I will show you how to implement new Module Version field for your Custom Module configuration by using JavaScript Modal Widget component from Magento 2 UI Library.

Overview

Let's say you want to show module version somewhere on the configuration settings page of a custom module. It might be helpful for Merchants to see and verify an updated version of a custom module. In addition to a module version we may show release notes for any changes appeared in a release.

The following is example of Module Version field located in Stores -> Configuration -> Custom Module section.

Module Version field with Release Notes

We also have "Release Notes" link which shows additional information in popup window. Here is example:

Release Notes Popup

Alright, let's go into details and implement Release Notes popup using Modal Widget and custom Module Version field.

Configuration

First of all, we have to declare new "Module Version" field in system.xml configuration file. You may notice from picture above the "Module Version" field has no scope information. Also, there is no "Use Config" checkbox setting in case "Store View" is used to see "Store" or "Website" specific configuration. Well, version of a module does not depend on scope :).

The "Module Version" field in Pronko\ModuleVersion\etc\adminhtml\system.xml configuration file:

<field id="version" 
       translate="label" 
       type="note" sortOrder="10" 
       showInDefault="1" showInWebsite="1" showInStore="1">
    <label>Module Version</label>
    <frontend_model>Pronko\ModuleVersion\Block\Adminhtml\System\Config\Version</frontend_model>
</field>

I am using "note" type for "Module Version" field in order to say Form renderer to use Magento\Framework\Data\Form\Element\Note class. The Note class uses simple <div /> element to render text information. The Magento\Framework\Data\Form\Element\Note::getElementHtml() method uses getText() magic method:

public function getElementHtml()
{
    $html = $this->getBeforeElementHtml()
    . '<div id="'
    . $this->getHtmlId()
    . '" class="control-value admin__field-value">'
    . $this->getText()
    . '</div>'
    . $this->getAfterElementHtml();
    return $html;
}

Frontend Model Class

The Pronko\ModuleVersion\Block\Adminhtml\System\Config\Version class is responsible for preparing module version and "Release Notes" link. Once prepared, information is set to Magento\Framework\Data\Form\Element\Note object using 'text' data key. Also, the Version class overrides _renderScopeLabel() and _renderInheritCheckbox() methods in order to remove Scope and Checkbox information from the "Module Version" field.

Here is implementation of the Pronko\ModuleVersion\Block\Adminhtml\System\Config\Version class:

namespace Pronko\ModuleVersion\Block\Adminhtml\System\Config;

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

/**
 * Backend system config module version field renderer
 */
class Version extends Field
{
    /**
     * @var ConfigInterface
     */
    protected $config;

    /**
     * Version constructor.
     * @param Context $context
     * @param ConfigInterface $config
     * @param array $data
     */
    public function __construct(
        Context $context,
        ConfigInterface $config,
        array $data = []
    ) {
        $this->config = $config;
        parent::__construct($context, $data);
    }

    /**
     * @param AbstractElement $element
     * @return string
     */
    protected function _getElementHtml(AbstractElement $element)
    {
        $html = $this->config->getModuleVersion() .
            ' <a href="#" class="changelog module-version popup" id="custom-release-notes">' .
            __('Release Notes') .
            '</a>';

        $element->setData('text', $html);
        return parent::_getElementHtml($element);
    }

    /**
     * @param AbstractElement $element
     * @return string
     */
    protected function _renderScopeLabel(AbstractElement $element)
    {
        return '';
    }

    /**
     * @param AbstractElement $element
     * @return string
     */
    protected function _renderInheritCheckbox(AbstractElement $element)
    {
        return '';
    }
}

Release Notes Modal Component

Next step is to create Release Notes component which will be responsible for Modal Widget initialization and observing "click" event of the "Release Notes" link. For this tutorial I am going to hard-code "custom-release-notes" ID of the Release Notes link.

New Release Notes component is located in the Pronko\ModuleVersion\view\adminhtml\web\js\release-notes.js JavaScript file.

define([
    'jquery',
    'Magento_Ui/js/modal/modal'
], function($) {
    'use strict';

    return function (optionsConfig) {
        var releaseNotes = $('<div/>').html(optionsConfig.html).modal({
            modalClass: 'changelog',
            title: $.mage.__('Realex Payments Release Notes'),
            buttons: [{
                text: 'Ok',
                click: function () {
                    this.closeModal();
                }
            }]
        });
        $('#custom-release-notes').on('click', function() {
            releaseNotes.modal('openModal');
        });
    };
});

We are going to pass HTML from backend side. Alternatively we may create release-notes.html template and pre-populate it in the release-notes.js with information passed from backend.

Release Notes Component Declaration

In order to initialize the release-notes.js componenent it should be added into the adminhtml_system_config_edit.xml layout update.

The declaration is located in the Pronko\ModuleVersion\view\adminhtml\layout\adminhtml_system_config_edit.xml configuration file:

<page>
    <body>
        <referenceContainer name="js">
            <block class="Pronko\ModuleVersion\Block\Adminhtml\System\Config\ReleaseNotes" template="Pronko_ModuleVersion::system/config/release-notes.phtml"/>
        </referenceContainer>
    </body>
</page>

The release-notes.phtml is used to initialize release-notes.js component and pass HTML from the Pronko\ModuleVersion\Block\Adminhtml\System\Config\ReleaseNotes block class.

The Pronko\ModuleVersion\view\adminhtml\templates\system\config\release-notes.phtml file:

<?php /** @var \Pronko\ModuleVersion\Block\Adminhtml\System\Config\ReleaseNotes $block */ ?>
<script type="text/x-magento-init">
{
    "*": {
        "releaseNotes": <?php echo $block->getReleaseNotesJson(); ?>
    }
}
</script>

The releaseNotes alias is declared in the requirejs-config.js:

var config = {
    map: {
        '*': {
            releaseNotes: 'Pronko_ModuleVersion/js/release-notes'
        }
    } 
};

Release Notes Block

The Pronko\ModuleVersion\Block\Adminhtml\System\Config\ReleaseNotes class prepares and returns HTML which later will be rendered as part of Release Notes Popup.

namespace Pronko\ModuleVersion\Block\Adminhtml\System\Config;

use Magento\Backend\Block\Template;

class ReleaseNotes extends Template
{
    /**
     * @return string
     */
    public function getReleaseNotesJson()
    {
        return json_encode([
            'html' => $this->getContent()
        ]);
    }
}

Feel free to implement getContent() method to return release notes of a custom module.

Final Thoughts

Even if Magento backend has Prototype JavaScript library you are still more than welcome to use jQuery Widgets and Knockout libraries for custom UI behavior. This article shows one of ways of implementing new Module Version configuration field where version and Release Notes might be presented for a Merchant in a nice and user friendly manner.

magento 2 javascript jquery

Related Articles

Comments

Next Article Previous Article

LinkedIn Twitter Facebook