Hi,
In my web forms based version of my application, I have centralised my navigation menu by having the code for it inside a User Control, and I reference the UC on each page. This saves greatly when adding new pages/menu items as I do not need to amend all the existing pages. I realise that ASP.NET Zero accomplishes this centralisation for me, which is a very good thing, however I wish to amend the code for the whole menu tree that gets generated.
Specifically, I wish to be able to identify LI items in the menu system by assigning them an ID=value, so that I can do something with the menu in client-side JavaScript once the page is ready. The code snippet below is what I want to be able to do...
<li class="nav-item" id="menu-parent01">
<a href="javascript:;">
<i class="icon-puzzle"></i>
<span class="title">Parent 01</span>
<span class="arrow "></span>
</a>
<ul class="sub-menu">
<li class="nav-item start" id="menu-parent01-child01">
<a href="/parent01/child01.aspx">
<i class="icon-grid"></i>
Child 01</a>
</li>
<li class="nav-item" id="menu-parent01-child02">
<a href="parent01/child02.aspx">
<i class="icon-globe"></i>
Child 02</a>
</li>
<li class="nav-item" id="menu-parent01-child03">
<a href="parent01/child03.aspx">
<i class="icon-screen-desktop"></i>
Child 03</a>
</li>
Why? In short, I am dynamically adding sub-items to the Nav-Menu using JavaScript, to represent temporary/dynamic pages that exist in my application when the user drills through into data. For instance, when they drill through a list of computer names they get a page containing details of that computer, and the Nav Menu is modified to include a sub-menu item which shows the name of the computer they are looking at.
So, where do I start? I can see that the mpaNavigationProvider.cs provides for a "customData" parameter? Is this where I might be able to add an ID when I perform the .AddItem(new MenuItemDefinition...)
Thanks,
Andy
4 Answer(s)
-
0
Hi,
CustomData is a good option. Another option is to use MenuItem's Name as ID since the Name is unique in the application. But notice that name may contain "." which can be a problem for HTML's ID value. So, you can replace "." with empty string which assigning it to li tag ID.
Thanks.
-
0
OK, so I might be on the right track - but can I actually use the customData parameter to add an id="myid" inside the <li> tag, or is customData simply a way of adding attributes in the menu object and not a means to output something in client facing html code?
I wish to be able to use JavaScript document.getElementById function to find an <li> in the DOM, by id, so that I can re-use my existing JavaScript code to inject a sub-item into the menu when the page has loaded. Here is my working function below;
<script type="text/javascript"> // Add a Dynamic Menu Item linking back to the parent page and make it active. var li = document.getElementById('menu-parent01-child01'); var dynul = document.createElement('ul'); var dynli = document.createElement('li'); dynul.classList.add('sub-menu'); dynli.setAttribute('id', 'menu-parent01-child01-temp01'); dynli.classList.add('active'); dynul.appendChild(dynli); li.appendChild(dynul); dynli.innerHTML = '<i class=icon-bar-chart></i>MenuName'; </script>
The function above would add a new menu item to the child01 menu item in the menu code I previously posted. or is there an alternative, more modern/MVC solution to finding the current menu item using the abp.application.navigation classes and then the page view adding in a new menu at runtime?
Thanks for your support.
-
0
Any idea?
-
0
Hi,
I assume that you're using MPA. I'm pasting the code I wanted to say. See <span style="color:#FF0000">red</span> parts.
@using Abp.Collections.Extensions @using MyCompanyName.AbpZeroTemplate.Web.Views @model MyCompanyName.AbpZeroTemplate.Web.Areas.Mpa.Models.Layout.SidebarViewModel @{ var calculateMenuUrl = new Func<string, string>((url) => { if (string.IsNullOrEmpty(url)) { return ApplicationPath; }
if (UrlChecker.IsRooted(url)) { return url; } return ApplicationPath + url; });
} <div class="page-sidebar navbar-collapse collapse">
<ul class="page-sidebar-menu" data-keep-expanded="false" data-auto-scroll="true" data-slide-speed="200"> @for (var i = 0; i < Model.Menu.Items.Count; i++) { var menuItem = Model.Menu.Items[i]; var isActive = Model.CurrentPageName == menuItem.Name || (!menuItem.Items.IsNullOrEmpty() && menuItem.Items.Any(item => item.Name == Model.CurrentPageName)); <li <span style="color:#FF0000">id="@menuItem.Name.Replace(".","")"</span> class="@(i==0 ? "start" : "") @(isActive ? "active" : "")"> @if (menuItem.Items.IsNullOrEmpty()) { <a href="@calculateMenuUrl(menuItem.Url)"> <i class="@menuItem.Icon"></i> <span class="title">@menuItem.DisplayName</span> </a> } else { <a href="javascript:;" class="auto"> <i class="@menuItem.Icon"></i> <span class="title">@menuItem.DisplayName</span> <span class="arrow"></span> </a> <ul class="sub-menu"> @foreach (var childMenuItem in menuItem.Items) { <li <span style="color:#FF0000">id="@childMenuItem.Name.Replace(".", "")"</span> class="@(Model.CurrentPageName == childMenuItem.Name ? "active" : "")"> <a href="@calculateMenuUrl(childMenuItem.Url)"> <span><i class="sub-menu-icon @childMenuItem.Icon"></i> @childMenuItem.DisplayName</span> </a> </li> } </ul> } </li> } </ul>
</div>
Thus, you can easily get a menu item by it's Id. For example, to get Roles menu: $('#AdministrationRoles') Then you can add sub items if you want.