Skip to content

UI Dynamic navigation items

Victor Tomaili edited this page May 3, 2021 · 1 revision

Fixed navigation items

In Serene, you can add navigation items into the left navigation by using assembly attributes NavigationMenu and NavigationLink. If the navigation items are fixed, those attributes are good enough and we should use them by default.

When Sergen generate code, it also generate those attributes on top of {EntityName}Page.cs for each entity. We should move all navigation attributes for each module to one file, e.g. {Modules}/{ModuleName}/{ModuleName}Navigation.cs, so that we can handle and maintain the navigation more easily.

Dynamic navigation items

From version 2.6.2 of Serenity/Serene, we have ability to inject dynamic navigation items through INavigationItemSource interface. You may want to add some navigation items based on user defined data, e.g. user defined folders under Inbox item. To archive this, just define a class that's derived from INavigationItemSource interface.

Examples 1. Add product categories as dynamic navigation items

Add DynamicNavigationSample class to the file \Modules\BasicSamples\BasicSamplesNavigation.cs as bellow

using System.Collections.Generic;
using Serenity.Navigation;
using Serenity.Data;
using Serenity.Services;
using Serene.Northwind.Repositories;
using Serene.Northwind.Pages;

[assembly: NavigationMenu(7900, "Basic Samples", icon: "icon-magic-wand")]

public class DynamicNavigationSample : INavigationItemSource
    {
        public List<NavigationItemAttribute> GetItems()
        {
            var items = new List<NavigationItemAttribute>
            {
                new NavigationMenuAttribute(7970, "Basic Samples/Dynamic Navigation", "icon-paper-plane")
            };

            // Add product categories as dynamic navigation items for demo purpose
            using (var connection = SqlConnections.NewByKey("Northwind"))
            {
                var categories = connection.List<CategoryRow>();
                foreach (var category in categories)
                    items.Add(new NavigationLinkAttribute(7970,
                        path: "Basic Samples/Dynamic Navigation/" + category.CategoryName.Replace("/", "//"),
                        url: "~/Northwind/Product?cat=" + category.CategoryID,
                        permission: Northwind.PermissionKeys.General,
                        icon: "icon-folder-alt"));
            }

            return items;
        }
    }

Here is the result
categoriesasdynamicnavigationitems

Examples 2. Add organization structure to the navigation

This example show how to add dynamic hierarchy navigation items. Modify the file \Modules\Organization\OrganizationNavigation.cs as bellow to filter contacts by business units with a tree menu

using System.Collections.Generic;
using Serenity.Navigation;
using Serenity.Services;
using Organization = Serene.Organization.Pages;
using Serene.Organization.Repositories;

[assembly: NavigationMenu(8000, "Organization", icon: "fa-sitemap")]
[assembly: NavigationLink(8000, "Organization/Business Units", typeof(Organization.BusinessUnitController), icon: "fa-sitemap")]
[assembly: NavigationMenu(8000, "Organization/Contacts", icon: "fa-address-book")]
[assembly: NavigationLink(8000, "Organization/Contacts/All Contacts", typeof(Organization.ContactController))]

public class ContactsByBusinessUnit : INavigationItemSource
{
    public List<NavigationItemAttribute> GetItems()
    {
        var items = new List<NavigationItemAttribute>();

        using (var connection = Serenity.Data.SqlConnections.NewByKey("Default"))
        {
            var businessUnits = new BusinessUnitRepository().List(connection,  new ListRequest()).Entities;
            foreach (var unit in businessUnits)
            {
                string path = unit.Name;

                // Recursively get path
                var currentUnit = unit;
                while (currentUnit.ParentUnitId != null)
                {
                    currentUnit = businessUnits.Find(y => y.UnitId == currentUnit.ParentUnitId);
                    path = currentUnit.Name + "/" + path;
                }
                path = "Organization/Contacts/" + path;
                                
                // If has no child, add navigation link, else add navigation menu
                if (businessUnits.FindAll(x => x.ParentUnitId == unit.UnitId).Count == 0)
                    items.Add(new NavigationLinkAttribute(8000, path, "Organization/Contact/Index?UnitId=" + unit.UnitId, null));
                else
                    items.Add(new NavigationMenuAttribute(8000, path, icon: "icon-folder-alt"));
            }
        }

        return items;
    }
}

organizationstructureonnavigation

Clone this wiki locally