Introduction

In this article, we will learn the step-by-step implementation for developing horizontal menus with submenu options in canvas PowerApps. We will make use of a collection and a PowerApps component to easily reuse the navigation menu across multiple screens. This will also highlight the currently active screen in the navigation bar.

Implementation

Let's see the step-by-step implementation for the horizontal navbar in PowerApps.

Step 1. Create screens

In this case, I have created 10 screens as shown below.

Step 2. Define the collection

We will define a collection that will store the menu, submenu, screen names, and ParentTab.

Set the OnStart property of the App to:

ClearCollect(colHorizontalMenu,

{Title:"Property",Screen:Blank(), Id:1, ParentTab: ""},
{Title:"Property 1",Screen:Screen1_1, Id:1, ParentTab: "Property"},
{Title:"Property 2",Screen:Screen1_2, Id:1, ParentTab: "Property"},
{Title:"Property 3",Screen:Screen1_3, Id:1, ParentTab: "Property"},

{Title:"Owner",Screen:Blank(), Id:2, ParentTab: ""},
{Title:"Owner 1",Screen:Screen2_1, Id:2, ParentTab: "Owner"},
{Title:"Owner 2",Screen:Screen2_2, Id:2, ParentTab: "Owner"},

{Title:"Sales",Screen:Blank(), Id:3, ParentTab: ""},
{Title:"Sales 1",Screen:Screen3_1, Id:3, ParentTab: "Sales"},
{Title:"Sales 2",Screen:Screen3_2, Id:3, ParentTab: "Sales"},

{Title:"Contractor",Screen:Blank(), Id:4, ParentTab: ""},
{Title:"Contractor 1",Screen:Screen4_1, Id:4, ParentTab: "Contractor"},
{Title:"Contractor 2",Screen:Screen4_2, Id:4, ParentTab: "Contractor"},

{Title:"Settlement",Screen:Screen5, Id:5, ParentTab: ""}

);

Step 3. Define the color theme

Add the color theme on the OnStart property of the App:

Set(varMenuPrimaryColor, RGBA(4, 42, 61, 1));
Set(varMenuSecondaryColor, RGBA(4, 166, 235, 1));

Step 4. Define the variable for the active tab

We will use a variable named varTabSelected for storing the Id of the active menu. Define this variable to OnStart property of the App:

Set(varTabSelected, 1);

Step 5. Add a component

Step 5.1. Add a new component (say HorizontalMenuComponent) with the below properties:

Step 5.2. Add a rectangle control to show the fixed background. Set the properties as below:

Step 5.3. Add a blank horizontal gallery (say Gallery1) which we will use for showing the parent menu items. Use the below properties for a better look and feel:

Step 5.4. Add a nested blank flexible height gallery (say Gallery2) inside the horizontal gallery - Gallery1 to show the submenu items. use the below properties for a better look and feel:

Step 5.5. Add a button (say Button1) inside the blank flexible height gallery - Gallery2

We will use the button to show the menu and submenu items.

Step 5.6. Add a downward icon inside the blank flexible height gallery - Gallery2 to show that the menu has child items

This step is optional but good to have. It will indicate that the menu has child items.

Step 6. Logic to update the height when the submenu is opened

In step 5.1, we have set the component height to 70. It will not expand if we click on the parent menu item. So to make a dynamic height component, we have to follow below steps:

Add a hidden label (say Label1) to the root level of the component and set the Text property to:

If(
    CountRows(
        Filter(
            Gallery2.AllItems,
            Id = varTabSelected
        )
    ) = 0,
    70,
    App.Height
)

Now we will use the label text property as the dynamic height of the Component. But, we cannot use it because child controls cannot be used to set the parent controls height. As a workaround, we will have to define the custom output property.

Step 7. Create output property

Add an output property (say FlexibleHeight) with data type as Number

Step 8. Set the value of the custom property

Set the property value to Label1.Text

Step 9. Set the height of the component

Set the height of the component to the value of the custom property created in step 5.

Height = Self.FlexibleHeight

Step 10: Add the component on all the Screens

I have added the component to all the screens. For testing purposes, I have added one label at the top of each screen with Text property as App.ActiveScreen.Name. It will help us to show the screen name.

Output

I hope you liked this article. If you have any queries please let me know in the comment section below. Thanks for reading!