Using Magento 2 UI for constructing a custom user interface

*note to self: revisit + gather questions before submitting*

The only obstacle stopping most developers (*from doing what? reaching their goals?*) is the hard implementation process required when it comes to Javascript-based robust interface (*did I change the meaning? I couldn't really find these exact words anywhere online*). Therefore, it was initially featured in very few extensions for Magento, and in most cases required additional third-party libraries that made extension more difficult to support.

But this situation has dramatically changed with launching Magento 2. The release comes with a comprehensive set of tools to build Javascript-based interface with its own widgets and the possibility of easily combining and extending them. This is referred to as Magento UI.

Let’s explore how it works by looking at a simple task: display an attention window by clicking a button.

Simple UI Widget with RequireJS

To solve this task, we need a widget for a modal dialog window, and also a working jQuery library. From here, we need to verify whether they are loaded to the page on which we are constructing our preview interface.

This is when Asynchronous Module Definition (AMD) enters the arena. The upshot is it allows developers to load Javascript module on-demand and avoid dependency-connected issues, like loading the module before the designated library module.

(*did I change the meaning with "designated" instead of "relied" module?*)

Magento 2 has built-in support of one the best Javascript AMD framework – RequireJS. This framework features two new keywords – define and require.

Define is used mainly for complex javascripts, extending modules or even for the creation of new objects. The other keyword – require – can be referenced anywhere, even directly from the page. It performs a dependency check, but instead of creating an object or a module, it just runs an enclosed code if the check was successful. A detailed description for both of them, as well as in-depth examples, can be found here.

require(["jquery"],
    function($) {
        alert($('#container').text());
    }
);

Listing 1. Require syntax

As seen in this code, require consists of two arguments – a check for a jQuery library and an anonymous function receiving a global variable to use inside. When a page is loaded, require commands browser to check whether jQuery library is loaded, and if not, it will try to load asynchronously. If the library loading fails, it will return without any actions taken. However, if jQuery is loaded successfully, the code inside the anonymous function will be immediately executed--i.e. an alert message will be displayed.

Therefore, for Magento UI scripting, we will use require keyword, as our code will be located directly on the page and should be run immediately after all requirements are met.

Now let’s add to the backend page alert.phtml our button and layer-container for a message to display:

Listing 2. Template for an attention window

Note that the inner layer has an invisible style. It is used as a container for a message, which will be displayed only on the button click. We can take the code from Listing 1, and add the button click handler there:

require([
     'jquery',
     'Magento_Ui/js/modal/alert'
     ],
     function($, alert) {
          $('#modal').on('click', 'button.modalRun', function(event){
               event.preventDefault();
               alert({
                    content: $(event.target).parent().children('#msg').text()
               })
          })
     }
);

Listing 3. Script to display a simple attention dialogue

There are two dependencies:

  1. jQuery (since we use it to access our message);
  2. Alert widget module.

Note that in the listeners, we need to use event.preventDefault() call. This will prevent the button from the default action (submitting a form, for example), so we can rest assured that the listener’s code will be executed.

The attention window is an override of the standard JavaScript alert function by the Magento UI Alert widget. Therefore, instead of a simple string, as shown in the previous listing, we pass an anonymous object with the content property containing the message itself there, which we obtained through the jQuery expression from msg layer.

We should place this script to the separate alert-test.js and add to the template using layout XML file to the head section:

    
        
            
            
        
    

Listing 4. Layout for Alert widget example.

Now let’s clear the cache and regenerate the static content to melt these modules together with your extension.

Therefore, backend user will see the button Run Action, and by clicking on it, he or she will receive a message with the hidden layer’s content.

Here is how it should look like:

Attention pop up message

Figure 1: Attention popup message

Short Summary

And there you have it! We've just created the attention popup with a few simple lines of code.

Of course, we considered only one of the components that is featured in Magento UI library. By using other widgets and their combinations, we can create a much more complex user interface. Furthermore, we can even extend these components using RequireJS methods.

But these topics will, probably, be covered in the future articles.

Compatibility issue: adding RequireJS to the layout

The method described in this article works not only in the backend, but in the frontend as well. Usually, RequireJS is enabled by default in most Magento 2 themes, but if it’s not activated, you need to add the following block to the head section in the layout XML file.

     
          
               requirejs/require.js
          
     
     

Listing 5. Adding RequireJS explicitly

This will add RequireJS to the frontend forcibly and Magento UI should work properly.

Ready-to-deploy project with this example is available from our Github.

Oleksandr Drok

Head of Products at Mirasvit

Alex serves as the Head of Products at Mirasvit, where he formulates the vision for Mirasvit's extensions, carefully curates new features, and constructs the roadmap.
Loading...