Creating standalone collapsible panel

The basic building block for tabbed interface is a Collapsible widget, which works on the top of div layer split into two parts:

  1. The header.
  2. The content of the collapsible panel.

It is rarely used as a standalone interface component, but if need, it can be constructed with the minimal usage of Javascript code.

<div data-mage-init='{"collapsible":{ "active": false, "animate": 200, "collapsible": true}}'>
     <div data-role="title">Show hidden</div>
     <div data-role="content">
          The Magento collapsible widget converts a header/content pair into an accordion, where the content is collapsed or expanded on the header click.
           Unlike the accordion widget is that collapsible is initialized for one title/content pair, while accordion can be initialized for a set of title/contents pairs.
     </div>
</div>

Listing 1. Standalone Collapsible widget

As you can see, our widget is instantiated through the additional tags introduced in Magento 2:

  • data-mage-init. Contains JSON-like array with the options for a widget constructor. In this listing, we used three of them: Active option defines whether a panel is shown by default. We set it to false, so our panel will be hidden. Animate option defines how the state from hidden to visible should be animated. In Listing 1 it’s set to number ? this means, that the panel should be shown within 200 msec. Collapsible option defines whether a panel should collapse if it lost the focus. It’s recommended to have it set in false. This is not the complete set of the useful options, we will return back to them a bit later.
  • data-role. Assigns a role to the HTML container. As we noted above, Collapsible is made from a regular div layer, so its siblings should be explicitly set ? what will be used as a title (permanently shown, and used as a trigger to hide/show our panel) and what will be content (constitutes the panel itself).

With these tags properly set, a customer will see the following result (the template, containing this code can be found here):

Single collapsible panel - hidden

Single collapsible panel - shown

When a customer clicks on Click to show hidden block label, the grey panel will be shown. On another click, it will hide again.

A few notes on this example should be added. Since this widget is one of the basic building blocks for the more complex widgets, it has no default styles, so both title and content containers should be decorated separately.

We mentioned above, that the options we used to construct the example at Listing 1, is not complete. Collapsible is a very flexible widget and allows customizing not only in a visual part, but also can:

  • delegate a trigger function to the other page element,
  • add to itself some special classes for active and hidden states (this makes styles decoration easier),
  • add icons for both states;
  • set custom classes selector for title and content components,
  • set custom classes to the other element, creating its dependency on the current state of the collapsible element.

A full list of Collapsible options can be found here.

The most complex option is animate. It controls to hide/show processes and contains a lot of tricks able to boost a visual appearance of this widget. In fact, there are three different options with the same name, but the different value types:

  • Boolean value (true/false). Enables and disables animation;
  • Numeric value. Sets animation duration time in milliseconds;
  • Object value. Sets jQuery animation properties.

Object value is specified as the json-like array, just like collapsible options as a whole. So, if we want, for example, to change the animation style, we should rewrite data-mage-init content at the Listing 1, and set easing property:

<div data-mage-init='{"collapsible":{ "active": false, "animate": {"easing": "easeInOutElastic"}, "collapsible": true}}'>

Listing 2. Setting animate properties

Elastic animation type defined at the Listing 2 above will make hide/show edgier. Generally, the effect types for easing (e. q. animation types) depend on the jQuery version. Their current list can be found here. Moreover, using the animate property you can control nearly any step of the animation, using the special callbacks functions, which also can be defined directly by the data-mage-init attribute.

But despite its rich flexibility, Collapsible widget works only on one div layer. To make a set of such collapsible panels and organize them to vertical or horizontal tabs, we need either to use extended widgets ? Tabs (for vertical layout) and Accordion (for horizontal), or create our own widget. For the most cases, extended widgets are good enough, but unlike Collapsible, they require some scripting.

Creating vertical tabs with the Tabs widget

Vertical-oriented (e. q. from left to the right) tabs are very common through all Magento interface. For example, product’s overview, extended info and additional information in product’s page are organized just that way.

Like Collapsible, Tabs widget, used for constructing vertical tabs, is created on the top of div container layer, which contains the list of titles and content panels for the tabs as the inner div layers. Titles should be listed as an unordered list, each item of which is a reference to an anchor, and contains a span (it’s necessary to decorate the tab title). The anchor’s reference, in fact, is a pointer to the ID of the layer, which contains the corresponding content pane.

<div id="horizontal_tabs">
     <ul>
          <li><a href="#fragment-1"><span>What is Accordion</span></a></li>
          <li><a href="#fragment-2"><span>What is Collapsible</span></a></li>
          <li><a href="#fragment-3"><span>What is Tabs</span></a></li>
     </ul>
     <div id="fragment-1">
          <p>Magento accordion widget is an extension of the Magento Tabs widget. Accordions are generally used to break content into multiple sections that can be swapped to save space</p>
     </div>
     <div id="fragment-2">
          <p>The Magento collapsible widget converts a header/content pair into an accordion, where the content is collapsed or expanded on the header click.</p>
          <p>Unlike the accordion widget is that collapsible is initialized for one title/content pair, while accordion can be initialized for a set of title/contents pairs.</p>
     </div>
     <div id="fragment-3">
          <p>The Magento tabs widget implements single content area with multiple panels, each associated with a header in a list. It uses the Magento collapsible widget.</p>
     </div>
</div>

Listing 3. Markup of the vertical-oriented tabs

The Code above is a model for tabbed block, consisted of three panels. But to make it work, we need some additional scripting to wrap this div to a widget and place to a separate js file.

require([
     'jquery',
     'jquery/ui'
     ],
     function($, tabs) {
          $("#horizontal_tabs").tabs();
     }
);

Listing 4. Wrapping div to the Tabs widget

After that, markup from the Listing 3 will look like this:

Vertical Tabs widget

Tabs widget is a superset of Collapsible, so it supports animation and other properties, discussed in the previous section. It also supports loading panel contents via AJAX requests. In this case, the anchor link instead of the div layer ID should point to an appropriate controller action or to an existing static page. An example of such purely dynamic Tabs widget can be found here.

Note that AJAX support in Magento Javascript UI is a separate large topic, that’s why we do not include it in this article.

Creating horizontal tabs with the Accordion widget

Another tab widget is Accordion. Unlike Tabs covered above, it creates horizontal-oriented sections, like shown in Figure 3.
Horizontal-oriented Tabs

Figure 3. Horizontal-oriented tabs using Accordion widget

This widget works on the top of div layer as well, but simpler than Tabs. It needs only to have a set of pairs h3 and div tags ? the first tag serves as a title, and the second as panel contents. Here is the markup for three horizontal (e. q. from top to bottom) tabs:

<div id="vertical_tabs">
     <h3>What is Integration</h3>
     <div>An integration enables third-party services to call the Magento web APIs. The Magento APIs currently supports Accounting, Enterprise Resource Planning (ERP), Customer Relationship Management (CRM), Product Information Management (PIM), and marketing automation systems out of the box. </div>

     <h3>What is Redis</h3>
     <div>Redis is an optional backend cache solution to replace Zend_Cache_Backend_File, which is used in Magento 2 by default.</div>

     <h3>What is Varnish</h3>
     <div>Varnish Cache is an open source web application accelerator (also referred to as an HTTP accelerator or caching HTTP reverse proxy). Varnish stores (or caches) files or fragments of files in memory; this enables Varnish to reduce the response time and network bandwidth consumption on future, equivalent requests. Unlike web servers like Apache and nginx,
Varnish was designed for use exclusively with the HTTP protocol.
Magento 2 supports Varnish versions 3.0.5 or later or any Varnish 4.x version.
     </div>
</div>

Listing 5. Markup for the Accordion widget

For this widget, we will need some scripting as well.

require([
     'jquery',
     'jquery/ui'
     ],
     function($, accordion) {
          $("#vertical_tabs").accordion({
               heightStyle: "content"
          });
     }
);

Listing 6. Script for initializing of the Accordion widget

Complete sources for template and script of this example are found at our Github projects.

Although this widget is similar to Tabs, it has some unique options. One of them we used in the code above to control tabs height. By default, all tabs have the same height, which is equal to the tallest of them. For the Tabs, it is a mandatory constant to properly display content. But in the Accordion height can be varied by specifying the height display policy.

Option heightStyle has three states:

  • auto. The default value, which dictates the tabs have the same height, as the tallest.
  • fill. Adjusts the height of the tabs so it can fit the parent element containing the Accordion.
  • content. Makes the tab height dynamic and dependent from its content.

Another useful option is a multipleCollapsible flag. If it’s set to true, the multiple panes can be expanded in one moment. This can be useful in custom checkouts or complex forms, divided into logical blocks.

Of course, being a superset of Collapsible widget, it also features the same properties, as we discussed above. Additional info on the Accordion can be found here.

Compatibility note: styles for Tabs and Accordion widgets.

Magento 2 do not provide styles for the extended widgets, like Accordion or Tabs, by default. It is implied, that styles should be developed separately and depend on a particular theme.

But for the testing purposes and using these widgets with some standard themes, we can use the style package directly from the jQuery UI. This will require the altering layout XML file by adding the following block to the page section in layout XML file:


<head>
     <css src="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" src_type="url" />
</head>

Listing 7. Include external style to the Magento 2 page

This will load style package directly from the latest jQuery repository, and the widgets will obtain default jQuery look and feel.

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

Enjoyed the Read?

Don’t miss our next article!