June 23, 2024

SamTech 365

PowerPlatform, Power Apps, Power Automate, PVA, SharePoint, C#, .Net, SQL, Azure News, Tips ….etc

Power Apps Canvas App – Vertical Menu with Sub Levels

In today’s article, I will describe how you can create a vertical menu control in Power Apps Canvas Application.

The process is as Follow;

I will start in Excel, for the sake of simplicity and create a table of all my menu items.

The idea is that for each entry of my menu, I will need:

Menu Items Table

  • Screen Name: This is the actual name (or label) of the menu button.
  • ID: For internal use, this needs to be unique.
  • IDParent: This value group the sub menus per parent item. It is very important to set the IDParent to -1 (or another unique value) for all the parent items.
  • Icon: Optional, this will be set to the image on the left side of the menu.
  • Screen: This will be the actual app screen which we will navigate to when a menu item is selected.

 

Screen Name ID IDParent Icon Screen
Home 0 -1 ico_home scrHome
Employees 1 -1 ico_employees scrEmployees
List of Employees 11 1 ico_list scrListofEmployees
New Employee 12 1 ico_newemployee scrNewEmployee
Leavers 13 1 ico_leavers scrLeavers
Dashboard 14 1 ico_dashboard scrDashboard
Requests 2 -1 ico_request scrRequests
Outstanding requests 21 2 ico_awaiting scrOutstandingrequests
All requests 22 2 ico_list scrAllrequests
Requests Dashbaord 23 2 ico_dashboard scrRequestsDashbaord
Settings 9 -1 ico_settings scrSettings
Jobs list 91 9 ico_jobs scrJobslist
Documents Types 91 9 ico_doctypes scrDocumentsTypes
Locations 92 9 ico_location scrLocations
Absences Types 93 9 ico_absence scrAbsencesTypes
Benefits 94 9 ico_benefits scrBenefits
Contacts Types 95 9 ico_contactstypes scrContactsTypes
Equipments 96 9 ico_equipments scrEquipments
OnBoarding Tasks 97 9 ico_onboardingtasks scrOnBoardingTasks
Trainings 98 9 ico_training scrTrainings
Forms 99 9 ico_forms scrForms
Questions 910 9 ico_questions scrQuestions
Employees Types 911 9 ico_employeestypes scrEmployeesTypes
Job Types 912 9 ico_jobs scrJobTypes
Employees Statuses 913 9 ico_statuses scrEmployeesStatuses
System 914 9 ico_system scrSystem

Menu Record Entry

Now, for each entry, I will generate an entry, which will be a record that will be appended to my PowerApps collection later.

Example of a record

{
Title: "Home",
ID: 0,
IdParent: -1,
Icon: ico_home,
Screen: scrHome
}

 

At the bottom of the table, I will concatenate all the records in one entry.

Now, let the fun begin !

PowerApps Menu Table

Now, when the app starts, I will initialise a table which will be passed as a parameter to the Menu controls in each screen.

Set(
    tblMenu,
    Table(
        {
            Title: "Home",
            ID: 0,
            IdParent: -1,
            Icon: ico_home,
            Screen: scrHome
        },
        {
            Title: "Employees",
            ID: 1,
            IdParent: -1,
            Icon: ico_employees,
            Screen: scrEmployees
        },
        {
            Title: "List of Employees",
            ID: 11,
            IdParent: 1,
            Icon: ico_list,
            Screen: scrListofEmployees
        },
        {
            Title: "New Employee",
            ID: 12,
            IdParent: 1,
            Icon: ico_newemployee,
            Screen: scrNewEmployee
        },
        {
            Title: "Leavers",
            ID: 13,
            IdParent: 1,
            Icon: ico_leavers,
            Screen: scrLeavers
        },
        {
            Title: "Dashboard",
            ID: 14,
            IdParent: 1,
            Icon: ico_dashboard,
            Screen: scrDashboard
        },
        {
            Title: "Requests",
            ID: 2,
            IdParent: -1,
            Icon: ico_request,
            Screen: scrRequests
        },
        {
            Title: "Outstanding requests",
            ID: 21,
            IdParent: 2,
            Icon: ico_awaiting,
            Screen: scrOutstandingrequests
        },
        {
            Title: "All requests",
            ID: 22,
            IdParent: 2,
            Icon: ico_list,
            Screen: scrAllrequests
        },
        {
            Title: "Requests Dashbaord",
            ID: 23,
            IdParent: 2,
            Icon: ico_dashboard,
            Screen: scrRequestsDashbaord
        },
        {
            Title: "Settings",
            ID: 9,
            IdParent: -1,
            Icon: ico_settings,
            Screen: scrSettings
        },
        {
            Title: "Jobs list",
            ID: 91,
            IdParent: 9,
            Icon: ico_jobs,
            Screen: scrJobslist
        },
        {
            Title: "Documents Types",
            ID: 91,
            IdParent: 9,
            Icon: ico_doctypes,
            Screen: scrDocumentsTypes
        },
        {
            Title: "Locations",
            ID: 92,
            IdParent: 9,
            Icon: ico_location,
            Screen: scrLocations
        },
        {
            Title: "Absences Types",
            ID: 93,
            IdParent: 9,
            Icon: ico_absence,
            Screen: scrAbsencesTypes
        },
        {
            Title: "Benefits",
            ID: 94,
            IdParent: 9,
            Icon: ico_benefits,
            Screen: scrBenefits
        },
        {
            Title: "Contacts Types",
            ID: 95,
            IdParent: 9,
            Icon: ico_contactstypes,
            Screen: scrContactsTypes
        },
        {
            Title: "Equipments",
            ID: 96,
            IdParent: 9,
            Icon: ico_equipments,
            Screen: scrEquipments
        },
        {
            Title: "OnBoarding Tasks",
            ID: 97,
            IdParent: 9,
            Icon: ico_onboardingtasks,
            Screen: scrOnBoardingTasks
        },
        {
            Title: "Trainings",
            ID: 98,
            IdParent: 9,
            Icon: ico_training,
            Screen: scrTrainings
        },
        {
            Title: "Forms",
            ID: 99,
            IdParent: 9,
            Icon: ico_forms,
            Screen: scrForms
        },
        {
            Title: "Questions",
            ID: 910,
            IdParent: 9,
            Icon: ico_questions,
            Screen: scrQuestions
        },
        {
            Title: "Employees Types",
            ID: 911,
            IdParent: 9,
            Icon: ico_employeestypes,
            Screen: scrEmployeesTypes
        },
        {
            Title: "Job Types",
            ID: 912,
            IdParent: 9,
            Icon: ico_jobs,
            Screen: scrJobTypes
        },
        {
            Title: "Employees Statuses",
            ID: 913,
            IdParent: 9,
            Icon: ico_statuses,
            Screen: scrEmployeesStatuses
        },
        {
            Title: "System",
            ID: 914,
            IdParent: 9,
            Icon: ico_system,
            Screen: scrSystem
        },
        {
            Title: "Security",
            ID: 10,
            IdParent: -1,
            Icon: ico_permissions,
            Screen: scrSecurity
        },
        {
            Title: "Users",
            ID: 101,
            IdParent: 10,
            Icon: ico_security,
            Screen: scrUsers
        },
        {
            Title: "Profiles",
            ID: 102,
            IdParent: 10,
            Icon: ico_profiles,
            Screen: scrProfiles
        }
    )
);

 

The Menu Component

In Power Apps, create a new component, and add the following structure:

The use of a container is optional, but I like to keep all my controls within containers, it is just a good habit !

Now, the gallery will be fed the menu table as data source.

Wen it comes to the gallery’s controls, we need just two controls:

  • Image: Which will be the menu icon
  • Button: this is the actual actionable menu button.

The sub menu logic

In order to implement the sub levels logic, I will follow this simple logic.

Menu Icon

The menu icon X value, will be set by a simple formula:

If(ThisItem.IdParent=-1,2,26)


The idea is that, if the IdParent=-1 (Which mean, the menu is a root level menu), the X (left position) is set to 2px otherwise, we will shift it a bit to the right (to create the sub menus structure) to the value of 26px.

Menu Button

Same logic is applied to the button, where we set the X value based on the IdParent value (either 2px for parent menus, or 26px for sub menus).

Please note, that the buttons have a left padding of 35, regardless of whether it is a root or sub menu.

Enjoy !