Power Apps Portal – Create Left Navigation Menu

Introduction

Hey everyone,, Hope you are doing well and staying safe!

In this #PowerGuideTip, I am going to share a Tip to customize portal default toolbar menu. As you know that currently portal toolbar menu (weblinks) has two major UI limitations:

  • By default portal menu/toolbar can only be appeared on the header.
  • Only display navigation menu up to 1 level. As depicted in pic below, you can see child links of only Power Guide Tips, not the child links of Power Platform and Dynamics 365.

Business Requirement

Customizing portal UI is one of the most common business requirement, where your client wants to customize the portal UI (Login, Registration, Home and Toolbar menu) to match the portal UI with other existing applications & websites. Recently, I have came across a UI requirement, where I had to show the navigation menu in left panel instead of showing it on top.

Solution

I am going to share a code snippet which is based on JavaScript, HTML, CSS and Liquid Code. Where,

  • HTML + CSS – is being used to design the custom toolbar menu
  • JavaScript – is being used to write some client side validations & logics.
  • Liquid Code – Dynamically fetching the portal weblinks from web link set table.

Alright, let’s get into more details and implement the requirement by performing followings steps:

Note: I have created following Web Links under Primary Navigation Web Link Set.

Step 2 – Open ‘Mobile Header’ content snippet (Portal Management > Content Snippets) and paste the following code
<span style="font-size: 22px;cursor:pointer;color: black;" onclick="openNav()">☰ </span>
<a href="~/"><img src="/powerguidelogo3" alt="Power Guide" style="width: 214px;margin-top: -14px;"></a>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
  body {
    font-family: "Lato", sans-serif;
  }
  .sidenav {
    height: 100%;
    width: 0;
    position: fixed;
    z-index: 1;
    top: 0;
    left: 0;
    background-color: white;
    overflow-x: hidden;
    transition: 0.5s;
    padding-top: 60px;
  }
  .sidenav a {
    padding: 0px 8px 3px 32px;
    text-decoration: none;
    font-size: 16px;
    color: #818181;
    display: block;
    transition: 0.3s;
    margin-left: 26%;
  }
  .sidenav a:hover {
    color: #f1f1f1;
    text-decoration: underline !important;
  }
  .sidenav .closebtn {
    position: absolute;
    top: 20px;
    font-size: 32px;
    margin-left: 0px;
    font-weight: normal;
  }
  #sublink_L1 {
    font-size: 15px;
    font-weight: normal;
    margin-left: 5%;
  }
  #sublink_L2 {
    font-size: 15px;
    font-weight: normal;
    margin-left: 15%;
  }
  @media screen and (max-height: 450px) {
    .sidenav {
      padding-top: 15px;
    }
    .sidenav a {
      font-size: 18px;
    }
  }
</style>
<div id="mySidenav" class="sidenav" style="width: 0px;">
  <img src="/powerguidelogo3" style="width: 54.52%;margin-left: 22%;top: 0px;position: absolute;">
  <br>
  <a href="javascript:void(0)" class="closebtn" onclick="closeNav()">×</a>
  {% assign primary_nav = weblinks["Primary Navigation"] %}
  {% if primary_nav %}
    {% for parentLink in primary_nav.weblinks %}
    <a href="{{ parentLink.url }}">{{ parentLink.name | escape }}</a>
    {% assign sublinks_L1 = parentLink.weblinks %}
        {% for sublink_L1 in sublinks_L1 %}
            {% if sublink_L1 %}
                <a href="{{ sublink_L1.url }}">
                <p id="sublink_L1"><span>- </span>{{ sublink_L1.name | escape }}</p>
                </a>
            {% endif %}
            {% assign sublinks_L2 = sublink_L1.weblinks %}
            {% for sublink_L2 in sublinks_L2 %}
                {% if sublink_L2 %}
                <a href="{{ sublink_L2.url }}">
                <p id="sublink_L2"><span>- </span>{{ sublink_L2.name | escape }}</p>
                </a>
                {% endif %}
            {% endfor %}
        {% endfor %}
    {% endfor %}
  {% endif %}
</div>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
  function openNav() {
    $("#mySidenav").css('width', '415px');
    $("body").css('backgroundColor', '#eee');
    $('.navbar').css('backgroundColor', '#eee');
  }
  function closeNav() {
    $("#mySidenav").css('width', '0');
    $("body").css('backgroundColor', 'White');
    $('.navbar').css('backgroundColor', 'White');
  }
</script>
  • Update the Line 2 (portal logo & company name ) as per your business requirement. This line of code will already be presented in your content snippet.
  • Update the CSS (Line 4 – 57) as per your UI guidelines.
  • Line 63 – change the web link set name that you want to customize. I have used ‘Primary Navigation’ for the demonstration, however this might be different in your case. For ex: Default, Secondary Navigation, Profile Navigation etc.
  • Lines (63 – 84) – Liquid code is used to fetch the weblinks under ‘Primary Navigation’ and also fetching the sublinks (childlinks) of each weblink. In the given code, I have fetched the sublinks only till second depth. As depicted in the pic below: D1 represents Depth 1 child links and D2 represents Depth 2 childlinks (child links of a child link) .
Step 3 – Hide portal default toolbar menu from Header template

Open Header web template and add style=”display:none;” at following places.

Demo

  • Important Tip: You can create a new content snippet to write your code (i shared above) and include that in your Mobile Header content snippet.

Thank you for reading this article and hope you found it useful and valuable. Please share your feedback and hit subscribe to learn such more useful #PowerGuideTips. Stay tuned!

Published by arpitpowerguide

My name is Arpit Shrivastava, who is a Microsoft MVP in the Business Applications category. I am a Microsoft Dynamics 365 and Power Platform enthusiast person who is having a passion for researching and learning new things and acquiring immense knowledge. I am providing consistent help, support, and sharing my knowledge through various Social Media Channels along with my Personal Blog, Microsoft Community, conducting online training and attending various 365 Saturday Events worldwide and sharing the best Solutions to the readers helping them achieve their goals and objectives in Customer Relationship Space.

Leave a comment