How to turn Forms Tabs into separate Tabs on Power Pages

I’ve recently had a Power Pages implementation where we had to display a form with a lot of data and multiple tabs.

Since Web Forms render Dataverse forms as a single page, regardless of how many tabs it has, this turned my portal page into a never ending scroll hell! Customer asked if there was some way to work around this and turn the Dataverse tabs to clickable tabs in Power Pages as well.

Bootstrap v3.3.6 supports both Tabs and Pills, so the plan was to turn a form into something that used these components as Tab selectors.

Looking into how the forms are rendered it looked like it was possible, so, after searching for different approaches and mashing together a few resources, here’s what I came up with:

var ListedTabs = function(){
    // Find the parent element containing the form
    var formContainer = $("#EntityFormPanel").find("div:first")[0];

    // Create a new unordered list element
    var ul = document.createElement('ul');
    ul.role = "tablist";
    $(ul).addClass("nav nav-pills");

    // Find all the h2 and div elements within the form container
    var tabnames=[];    
    var tabids=[];     
    
    $('.tab-title').each(function() { tabnames.push($(this).text()); $(this).hide(); });
    $('.tab').each(function() 
    { 
        tabids.push($(this).attr("data-name")); 
        $(this).addClass("tab-pane"); 
    });
    $('.tab').first().addClass("active");

    // Loop through the headings and contents to create tab navigation
    for (var i = 0; i < tabnames.length; i++) {
        // Create a new list item element
        var li = document.createElement('li');

        // Create a new anchor element for the tab link
        var a = document.createElement('a');
        a.href = '#tabs-' + (i + 1); // Set the href attribute
        a.role="tab";
        a.setAttribute("data-toggle","tab");
        a.textContent = tabnames[i];
        a.title = tabnames[i];
        if(i == 0)
            a.setAttribute("aria-expanded", "true");

        // Append the anchor element to the list item element
        li.appendChild(a);

        // Append the list item element to the unordered list
        ul.appendChild(li);

        // Add a class to the content div corresponding to the tab
        $("div[data-name=" + tabids[i] + "]").addClass('content');
        $("div[data-name=" + tabids[i] + "]").attr('id', 'tabs-' + (i + 1));
    }

    // Insert the unordered list before the first h2 element
    var firstHeading = formContainer.querySelector('h2');
    formContainer.insertBefore(ul, firstHeading);
    formContainer.insertBefore(document.createElement('br'), firstHeading);
    $(formContainer).addClass("tab-content");

    // Select first tab
    $("ul[role='tablist'] a:first").click();
};

$(document).ready(function () {
    ListedTabs();
});

Add this snippet to the JavaScript part of the Web Page that has the Web Form.

If all goes well the snippet will search for all headings that are supposed to have the Tab name and create a clickable list item for each of them.

Pills looked a lot better than tabs so that’s what I went with, but to use tabs we just need to change the nav-pills class to nav-tabs.

Also, keep in mind that if at any point the form rendering changes and the IDs or components are different the functionality might break, something to always keep in mind when we use this approach!

Comments

Leave a Reply

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