Customising product info tabs in Magento 2 (part 2)

Related Inchoo Services

In this follow up on our first blog post about customising product info tabs in Magento 2 we’ll be talking about reordering tabs. Again it’s a fairly easy task. We already know that we’ll be looking at product page layout and template files in Magento Catalog module.

Standard Magento way for reordering and rearranging elements around the webpage is by modifying layout (xml) files. For that purpose we use move instruction together with a couple of attributes, required ones being:

element – for selecting element to be moved
destination – for denoting destination element

Optional ones, before and after, are used for placing the target element before or after the certain element under the same parent.

Although useful and easy to use, this layout handler is of no help when we face the problem of reordering product tabs so we need to find another way.

HTML markup for our product tabs is stored in details.phtml file found in module-catalog/view/frontend/templates/product/view folder. Inspecting the code we will find out that our tabbed navigation is ordered based on elements position in a $detailedInfoGroup array. We found exactly what we were looking for and now we can copy file to our theme scope and simply redeclare array before foreach loop.

// Reposition elements in array
   $detailedInfoGroup = ["reviews.tab", "product.info.description", "product.attributes"]

And that’s it!

In the example above, we moved reviews.tab to the first position in array and looking at the product page in our browser we can see that tabbed navigation is in the same order defined in $detailedInfoGroup array in template file.

This simple and easy array manipulation is the way to go in almost every situation we need to change tabs ordering. However, there are one or two cases when server-side scripting cannot be our weapon of choice and we need to rely on javascript or jQuery.

Javascript to the rescue

As a client-side language, javascript is suitable in cases we want to reorder our tabs based on some user agent setting or feature such as screen resolution.

To code our .js script let’s first take a look at HTML structure of tabbed navigation. We can see that tab titles and tab contents are all div elements and all siblings, meaning they share the same parent.

In the first part of our script we will get all divs that are children of container div i.e. div class="product data items" in one array in a such a way that tab title and tab content pairs are stored in one array element:

// Get tab title and tab content pairs in one array
   var container = document.getElementsByClassName('product data items');
   var elements = container[0].children;
   var tabs = []; // declare array to hold our elements
 
   for (var i = 0; i < elements.length; i += 2) {
     var tabTitle   = (elements[i]).outerHTML;
     var tabContent = (elements[i + 1]).outerHTML;
 
     tabs.push(tabTitle + tabContent);
   }

The second part of our script is a function that sorts tabs array based on our inputs:

// Function to reorder tabs based on newOrder array
   var result = [];        
   function reorder(tabs, newOrder) {
     for(var i = 0; i < tabs.length; i++) {
       result[i] = tabs[newOrder[i] - 1];
     }
     return result;
   }

Finally, our third code block is where we declare new array with arbitrary elements’ position and call our function:

// Output reordered elements     
   var newOrder = [3, 1, 2]; // new elements' position
   container[0].innerHTML = null;
   container[0].innerHTML = reorder(tabs, newOrder).join("");

As you know Magento 2 has its special way for using custom javascript so I’ll refer you to this excellent post to correctly add javascript files to your project.

***

Obviously, (re)declaring php array in template file is the easier and more convenient of the two methods. But, when dealing with different settings end/or features on end users’ devices, we have no choice but to use javascript.

Igor Tikvic

- Frontend Developer

Igor loves to play chess, but also with Lego sets. He is mostly interested in how to visually communicate to website audience and make their online experience as smooth as possible.

Read more posts by Igor / Visit Igor's profile

1 comment

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.