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.

Horizontal Navbar Component in PowerApps

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.

Screens in PowerApps

Step 2: Define the collection

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

  • For the items, which has ParentTab value as blank indicates that those are the parent menu items.
  • For defining the child items i.e. submenu, set the ParentTab value to the Title value of the Parent item as shown below.
  • Each set of menu-submenu should have same Id value.

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: ""}

);

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));

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, 0);

Step 3: Add a component

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

Add a component

  • Width = App.Width
  • Height = 70
    • We will update the height to dynamic in the next steps, but for now, keep it 70
  • Fill = Transparent
  • Access spp scope = ON
    • This property allows you to access variables defined in the OnStart property of the app. You can find this property in the right side of the component properties.

Step 4: Add rectangle

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

Add rectangle

  • DisplayMode = DisplayMode.Disabled
    • So that it will not have a hover effect.
  • DisabledFill = varMenuPrimaryColor
  • X = 0, Y =0
  • Width = App.Width
  • Height = 70
    • This should be the same as the component height.

Step 5: Add blank horizontal gallery

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:

Add blank horizontal gallery

  • Items = GroupBy(Filter(colHorizontalMenu, Id = varTabSelected || ParentTab = "") ,"Id","GroupMenu")
    • We have filtered the collection to only show the parent menu items along with the submenu items of the active tab.
  • TemplateSize = 200
    • This will be the width of each main menu item.
  • Show Scrollbar = Off
  • X = 0, Y = 0 (You can change the X position if you want the center-aligned menu)
  • Width = CountRows(Self.AllItems)*Self.TemplateWidth
    • This will cover all the parent items horizontally and removes the horizontal scrolling.
  • Height = App.Height
    • So that it can show all the submenu items vertically.
  • TemplatePadding = 0

Step 6: Add a nested blank flexible height gallery

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:

Add nested blank vertical gallery
  • Width = 200
    • This is the same width we are using for parent items (Step 3.3)
  • Height = 600
  • Items = AddColumns(ThisItem.GroupMenu, "Id", ThisItem.Id)
    • We will use the GroupMenu property of the parent item. This will only show the submenu options of the parent item.
  • ShowScrollbar = false
  • TemplateSize = 40
  • TemplatePadding = 0

Step 7: Add a button

Add a button (say Button1) inside the blank flexible height gallery - Gallery2
We will use the button to show the menu and submenu items.

Add button

  • Width = 200
    • Same as the width of the parent gallery
  • X = 0, Y = 0
    • To remove spacing
  • Height = If(IsBlank(ThisItem.ParentTab), 70, 40)
    • To show different heights for Parent items and submenu items.
  • BorderThickness = 0
  • Border radius = 0
  • Fill = If(ThisItem.Id = LookUp(colHorizontalMenu, Screen = App.ActiveScreen).Id && IsBlank(ThisItem.ParentTab), varMenuSecondaryColor, varMenuPrimaryColor)
    • This will show different colors for the Active menu item
  • Text = ThisItem.Title
    • To show the tile of the menu-submenu
  • OnSelect = If(varTabSelected=ThisItem.Id,Set(varTabSelected,0),Set(varTabSelected,ThisItem.Id));Navigate(ThisItem.Screen)
    • This will update the varTabSelected variable and also navigate the user to the respective screen.
  • HoverFill = ColorFade(varMenuSecondaryColor, -20%)
  • FocusedBorderThickness = 0

Step 8: Add a downward icon

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.

Add downward arrow

  • Width = 20
  • Height = 70
  • X = 170
    • This you can change according to your menu title length
  • Y = 0
  • Visible = IsBlank(ThisItem.ParentTab) && CountRows(Filter(colHorizontalMenu, Id = ThisItem.Id)) > 1
    • This will hide the icon if any parent menu does not have child menus.


Step 9: Logic to update the height when the submenu is opened

In step 3.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(varTabSelected = 0, 70, App.Height)

Add dynamic 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 10: Create output property

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

FlexibleHeight

Step 11: Set the value of the custom property

Set the property value to Label1.Text

Set the value of the custom property

Step 12: 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

Set height

Step 13: 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.

Add the component on all the Screens

Output:

Horizontal navbar powerapps


P.S – This article was originally published at this link .