If you have a form in Power Pages that has a lot of fields on it, sometimes it makes sense to break it up and not display all of the fields at once. A common UI pattern to do that is tabs.
While tabs are a concept that exist in modern model-driven Power Apps, whose form technology is what Power Pages is based on, Power Pages forms were originally created at a time when Microsoft didn’t display the tabs in Power Apps. So the developers of Power Pages (which at that time was still Adxstudio) mirrored that and just displayed the entire form all at once.
So if we decide we want tabs anyways, what can we do?
Some Other Possibilities
The “out-of-the-box” option would be to use multi-step forms. This allows you to break the form into smaller chunks, and then the user can navigate between them by going forwards and backwards. However, multi-step forms still don’t have what might be the most requested Power Pages enhancement – the ability to navigate to a specific step by clicking on it. So multi-step forms are an option, just as long as it is ok for users to going through step-by-step in a specific order.
If that is not ok, let’s look at how other people have solved similar problems.
João Santos has a post on how to turn Forms Tabs into separate Tabs on Power Pages. This option uses JavaScript to turn the long form into a single page with tabs.
Ulrikke Akerbæk has a post on how to create clickable tabs navigation for Power Pages and Power Apps Portals. This one more closely resembles the user experience of a multi-step form.
In my particular case, the reason I wanted to break up the form is that it was extremely long, with many subgrids, which meant the page took a long time to load. This made João’s solution not practical in my case, since I wanted to move certain data to other pages that would only load when specifically needed.
So instead I devised a way to separate the forms and display tabs using Web Link Sets.
Separate Forms and Pages
The first step is to separate your long form into one form per tab. For each model-driven app/Dataverse form, we’re also going to create a Web Page and a Power Pages Form that uses that form.
Let’s say you want three tabs. We’ll end up with three web pages, each with their own Power Pages Form, which uses a model-driven app/Dataverse form.
Next, we’re going to use a Web Link Set to create the ability to navigate between these Web Pages.
Web Link Sets
Web Link Sets are a content-management feature of Power Pages that allow content authors to manage lists of links. Links can be either to internal pages or external URLs.
Web Link Sets are used to manage the links that appear in the primary navigation of the site. You can also define your own custom Web Link Sets, and then display on your Power Pages site using Liquid.
Custom Web Link Sets are managed in the Power Pages/Portals Management App. You can find them in the Content area of the navigation.
Web Link Sets are nice because they allow non-developers to create lists of links, and the developer can reference the list by name, and use loops to display all the configured links.
In our case, we are going to create a Web Link Set with links to each of the Web Pages we created earlier.
Liquid to Display Tabs
With the Web Link Set defined (in our example, we called the Web Link Set “Tabbed Form”), let’s look at some Liquid code that loops through all of the links and displays them as navigation pills:
{% assign formWL = weblinks['Tabbed Form'] %}
{% if formWL %}
<ul class="nav nav-pills">
{% for link in formWL.weblinks %}
<li role="presentation" {% if link.is_sitemap_current %}class="active"{% endif %}><a href='{{ link.url | escape }}?id={{request.params.id}}' title='{{ link.tooltip | escape }}'>{{ link.name | escape }}</a></li>
{% endfor %}
</ul>
{% endif %}
Mostly pretty standard stuff. We get the specific Web Link Set by name using the weblinks object. Next, after checking to ensure we have a Web Link Set, we create our <UL> using the Bootstrap classes for navigation pills (this example has Bootstrap v3, but should be easily adaptable to v5), and then loop around all of the links in the set, displaying an <LI> and an <A> for each of them.
There are a few things I want to highlight:
- Notice the use of the escape filter. This is best practice when outputting HTML text.
- Notice the use of the is_sitemap_current attribute of the link to add the active class to the current page.
- Notice the id query string that is appended to the URL of the link. This is key! Power Pages Forms need to know where to get the data from, and the most common way is via a query string parameter. When a user is first navigated to our new multi-tab form, the URL should contain the ID of the row to display. However, the links to the other tabs won’t include that ID by default. So we need to grab it from the current URL, and add it to the links to the other tabs.
Next, I’d create a new Web Template that contains a wrapper <DIV>, followed by that code, followed by an include statement for the Page Copy, like so:
<div id="mainContent" class="wrapper-body" role="main">
{% assign formWL = weblinks['Tabbed Form'] %}
{% if formWL %}
<ul class="nav nav-pills">
{% for link in formWL.weblinks %}
<li role="presentation" {% if link.is_sitemap_current %}class="active"{% endif %}><a href='{{ link.url | escape }}?id={{request.params.id}}' title='{{ link.tooltip | escape }}'>{{ link.name | escape }}</a></li>
{% endfor %}
</ul>
{% endif %}
{% include 'Page Copy' %}
</div>
Then I’d create a Page Template using that Web Template, and use that Page Template for each of the pages that contain my forms.
With that in place, you should see the lists of tabs (i.e. pages) above the form, with the ability to click on them to take you to those other pages, maintaining the correct ID in the query string.
Another Alternative – Child Pages
While Web Link Sets are one way to do this, another option would to create a parent page, with each of the tabs being a child page of the parent page. You can then craft Liquid code to loop through the child pages in a similar manner. Ulrikke’s post mentioned above does this.