Close [x]

Using UI components' client-side

Edit this page on GitHub

What鈥檚 in this topic

This topic is aimed for developers, who need to reuse the Magento UI Components.

The topic covers the following:

UI components鈥 configuration

A UI component鈥檚 behavior, configuration and structure is defined by the following:

  • The available configuration options and methods for components of a certain type, defined in the component鈥檚 .js file.

  • The actual configuration and structure of a particular component, specified in the component鈥檚 configuration .xml file, in the scope of the <argument></argument> node. The configuration file also extends properties, specifies the component鈥檚template and the path to the component鈥檚 .js file.

All these properties, options, and methods are available in the component template鈥檚 scope.

Most important UI components鈥 properties

The most important client-side properties of a UI component are the following:

  • component: the path to the component鈥檚 .js file in terms of RequireJS.

Example: The .js file of the bookmark component is Magento/Ui/view/base/web/js/grid/controls/bookmarks/bookmarks.js

So the component property is set in the .xml configuration file like following:

<argument name="data" xsi:type="array">
        <item name="component" xsi:type="string">Magento_Ui/js/grid/controls/bookmarks/bookmarks</item>
</argument>
  • template: path to the component鈥檚 .html template.

Example:

The .html template of the bookmarks component is Magento/Ui/view/base/web/templates/grid/controls/bookmarks/bookmarks.html.

<argument name="data" xsi:type="array">
        <item name="template" xsi:type="string">ui/grid/controls/bookmarks/bookmarks</item>
</argument>
  • children: is a general name for the nested components of a certain component. Children can be specified in the .xml configuration of the parent component (all nodes except <argument/> and <dataSource/> are considered children) and in the Knockout JS templates: children are the keys of the elems property.

  • name: the name of the component specified in the .xml configuration file of the parent UI component. In the run-time in a browser this value is transformed to a complex string. This string represents hierarchy of components in the run-time. For example, (app/code/Magento/Cms/view/adminhtml/ui_component/cms_block_listing.xml:57)[https://github.com/magento/magento2/blob/2.0/app/code/Magento/Cms/view/adminhtml/ui_component/cms_block_listing.xml#L57]:

<component name="columns_controls">

In the run-time columns_controls is transformed to the following string: cms_block_listing.cms_block_listing.listing_top.columns_controls.

This string is constructed from the following values:

  • cms_block_listing.cms_block_listing: - the full name of the root component.
  • listing_top: the value of the name attribute of the parent <container name="listing_top"> component.
  • columns_controls - the value of the name attribute of the component itself.

The following properties are used for linking observable properties and methods of UI components:

  • exports: used to notify some external entity about property changing. exportss value is an object, composed of the following:

    • key: name of the internal property or method which is tracked for changes.
    • value: name of the property or method which receives the notification. Can use string templates.

Example of setting exports in a component鈥檚 .js file:

{
  'exports': {
   'visible': '${ $.provider }.visibility'
  }
}

Here visible is the key, ${ $.provider }.visibility is the value.

Example of setting exports in a component鈥檚 configuration .xml file:

<argument name="data" xsi:type="array">
       <item name="config" xsi:type="array">
                    <item name="exports" xsi:type="array">
                        <item name="visible" xsi:type="string">sample_config.sample_provider.visibility</item>
                    </item>
       </item>
</argument>

In this example, visible is the key, sample_config.sample_provider.visibility is the value.

  • imports: used for tracking changes of an external entity property. imports鈥檚 value is an object, composed of the following:

    • key: name of the internal property or method which receives the notifications.
    • value: name of the property or method which is tracked for changes. Can use string templates.

Example of using imports in a component鈥檚 .js file:

{
  'imports': {
   'visible': '${ $.provider }.visibility'
  }
}

Example of using imports in a component鈥檚 configuration .xml file:

<argument name="data" xsi:type="array">
       <item name="config" xsi:type="array">
                    <item name="imports" xsi:type="array">
                        <item name="visible" xsi:type="string">sample_config.sample_provider.visibility</item>
                    </item>
       </item>
</argument>
  • links: used for mutual tracking property changes. links鈥檚 value is an object, composed of the following:

    • key: name of the internal property or method which sends and receives the notifications.
    • value - name of the property or method which sends and receives the notifications. Can use string templates.

Example of using links in a component鈥檚 .js file:

{
  'links': {
   'visible': '${ $.provider }.visibility'
  }
}

Example of using links in a component鈥檚 configuration .xml file:

<argument name="data" xsi:type="array">
       <item name="config" xsi:type="array">
                    <item name="links" xsi:type="array">
                        <item name="visible" xsi:type="string">sample_config.sample_provider.visibility</item>
                    </item>
       </item>
</argument>
  • listens: used to track the changes of a component鈥檚 proporty.
    • key - name of the internal property which listens to the changes.
    • value - name of the property or method which is tracked for changes. Can use string templates.

Example of using listens in a component鈥檚 .js file :

{
  'listens': {
   'visible': '${ $.provider }.visibility'
  }
}

Example of using listens in a component鈥檚 configuration .xml file:

<argument name="data" xsi:type="array">
       <item name="config" xsi:type="array">
                    <item name="listens" xsi:type="array">
                        <item name="visible" xsi:type="string">sample_config.sample_provider.visibility</item>
                    </item>
       </item>
</argument>

Frequently used additional components

This section is a brief description of the most frequently used additional UI components.

uiClass

Enables OOP pattern implementation.

uiElement

Extends uiClass. Adds the following:

  • the defaults property
  • events handling
  • handling properties linking (the imports, exports, links and listens properties)
  • ability to add itself to the UI registry

uiCollection

Extends uiElement. Adds the following:

uiRegistry

In-memory storage. Plain storage of entities by keys. Implements the get(), set(), and has() methods.

All the components described in this section are aliases in terms of RequireJS. So they can be directly requested in the component鈥檚 .js file or used in a component鈥檚 configuration .xml file (except uiRegistry, which by its nature is not expected to be used in a configuration file).

Example for the uiClass property request:

define( ['uiClass'], function (abstractClass) {
    return abstractClass.extend({ 
      ... // needed methods here
   };
});

Example of using the uiClass property in a configuration file:

<container name="some_custom_component">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="component" xsi:type="string">uiClass</item>
            </item>
        </argument>
    </container>

JS UI components debugging

This section describes how to define what UI components are used on a particular page and what data they use.

To define the UI components used on a page, you can use browser built-in developer tools, or install additionally a plugin, for example Knockout JS context debugger for Google Chrome.

Debug using browser built-in tools

  1. Open the required page in a browser.
  2. Select to view the page source.
  3. Search for data-bind="scope:. The string after scope is the full name of the component.
  4. Open developers tools and in the console tab run require('uiRegistry').get('<full_component_name>'). Where <full_component_name> is the name you defined on the previous step. The name and the configuration of the UI component instance is displayed once the command is executed.

For illustration, let鈥檚 find out what UI components are used on the Catalog page in the Admin panel:

The catalog page

According to the described procedure, open the page source and search for 鈥data-bind="scope:

searching for data-bind=scope:

So we find out that the main UI component used on this page is product listing, with product_listing.product_listing as a full name. To see its configuration, child components and data source, in the in the Console tab we run require('uiRegistry').get('product_listing.product_listing'):

run the command in Console

And we get the component鈥檚 configuration:

view the configuration

Debug using a Google Chrome plug-in

  1. Install the Knockout JS context debugger for Google Chrome.
  2. Open the required page in Chrome.
  3. Point to the required element on the page, right-click and select Inspect Element. The developer tools panel opens.
  4. In the right column of the panel, click the Knockout context tab. The tab displays the name and the configuration of the UI component instance.