Umbraco v7.6 Dynamic Dropdown menu -- populating submenu items dynamically
I'm trying to create a dropdown navigation that's dynamically populated-updated by the backoffice.
I can correctly populate all of the navigtation items ... even remove a few unwanted items as needed. The only thing I can't figure out is how-where to include a foreach loop that will populate the submenu items inside of the correct html tags (the toggled dropdown
).
The code is currently determining if there are children ... if it does not have children a link to that page will be included ... if it DOES have children the link needs to be disabled to allow the dropdown toggle and only the items in the submenu should have links.
Here's the code:
@* Helper method to travers through all descendants *@
@helper Traverse(dynamic node, bool isHome)
{
@* Update the level to reflect how deep you want the sitemap to go *@
var maxLevelForSitemap = 3;
@* Select visible children *@
var selection = node.Children.Where("Visible").Where("Level <= " + maxLevelForSitemap);
@* If any items are returned, render a list *@
if (selection.Any())
{
<ul class="nav navbar-nav">
@if(isHome) {
var cssClass = CurrentPage.Site().Id == CurrentPage.Id ? "active" : null;
isHome = false;
}
@foreach (var childPage in selection.Where("Visible"))
{
if (childPage.Children.Any())
{
<li class="has-child @(childPage.IsAncestorOrSelf(CurrentPage) ? "selected" : null) dropdown">
<a href="#">@childPage.Name</a>
</li>
}
else
{
<li class="@(childPage.IsAncestorOrSelf(CurrentPage) ? "selected" : null) dropdown">
<a href="@childPage.Url">@childPage.Name</a>
</li>
}
@* Run the traverse helper again for any child pages
@Traverse(childPage, isHome) *@
}
</ul>
}
}
... and here's the unordered list that I'd like to target , or at least the html I'm trying to populate dynamically with the submenu items:
There's surprisingly very little information-documentation on this. Any insight, suggestions or links to other references-resources would be greatly appreciated. Thanks in advance for your help!
@* Helper method to travers through all descendants *@
@helper Traverse(dynamic node, bool isHome)
{
@* Update the level to reflect how deep you want the sitemap to go *@
var maxLevelForSitemap = 3;
@* Select visible children *@
var selection = node.Children.Where("Visible").Where("Level <= " + maxLevelForSitemap);
@* If any items are returned, render a list *@
if (selection.Any())
{
<ul class="nav navbar-nav">
@if(isHome) {
var cssClass = CurrentPage.Site().Id == CurrentPage.Id ? "active" : null;
isHome = false;
}
@foreach (var childPage in selection.Where("Visible"))
{
if (childPage.Children.Any())
{
<li class="has-child @(childPage.IsAncestorOrSelf(CurrentPage) ? "selected" : null) dropdown">
<a href="#">@childPage.Name</a>
@* Run the traverse helper again for any child pages
@Traverse(childPage, isHome) *@
}
else
{
I don't know why but I can't reply to your post, David, BUT ... that definitely helped. Moving the traverse helper up above the "} else {" and rearranging the html around it a bit did the trick. Works perfectly now.
Here's the revised-functional code block for anyone else looking for help creating dynamic dropdown menus (this one includes a searchbar and mobile-ready collapse menu functionality) in v7.6 and using bootstrap ... just make sure to implement umbracoNaviHide in your document types so you filter pages out of the nav as needed :
@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@*
This snippet makes a list of links of all visible pages of the site, as nested unordered html lists.
How it works:
- It uses a custom Razor helper called Traverse() to select and display the markup and links.
*@
@{ var selection = CurrentPage.Site();
var isHome = true;
}
<nav class="nav navbar navbar-default">
<div class="container navWrap col-centered">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
@* Render the sitemap by passing the root node to the traverse helper, below *@
@Traverse(selection, isHome)
</ul>
<form class="navbar-form navbar-right">
<div class="form-group has-feedback">
<input type="text" class="form-control" placeholder="Pesquisar"><i class="form-control-feedback glyphicon glyphicon-search"></i>
</div>
<!-- REMOVE BUTTON <button type="submit" class="btn btn-default">Enviar</button> -->
</form>
</div>
</div>
</nav>
@* Helper method to travers through all descendants *@
@helper Traverse(dynamic node, bool isHome)
{
@* Update the level to reflect how deep you want the sitemap to go *@
var maxLevelForSitemap = 3;
@* Select visible children *@
var selection = node.Children.Where("Visible").Where("Level <= " + maxLevelForSitemap);
@* If any items are returned, render a list *@
if (selection.Any())
{
if(isHome) {
var cssClass = CurrentPage.Site().Id == CurrentPage.Id ? "active" : null;
isHome = false;
}
foreach (var childPage in selection.Where("Visible"))
{
if (childPage.Children.Any())
{
<li class="has-child @(childPage.IsAncestorOrSelf(CurrentPage) ? "selected" : null)">
<a class="dropdown-toggle menuTextMain" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false" href="#">@childPage.Name</a>
<ul class="dropdown-menu navItems">
<li class="dropdown">
@* Run the traverse helper again for any child pages *@
@Traverse(childPage, isHome)
</li>
</ul>
</li>
}
else
{
<li class="@(childPage.IsAncestorOrSelf(CurrentPage) ? "selected" : null)">
<a class="menuTextMain" href="@childPage.Url">@childPage.Name</a>
</li>
}
}
}
}
I really appreciate your help David. So far the Umbraco developer community has definitely lived up to it's reputation. Thanks again!
Umbraco v7.6 Dynamic Dropdown menu -- populating submenu items dynamically
I'm trying to create a dropdown navigation that's dynamically populated-updated by the backoffice.
I can correctly populate all of the navigtation items ... even remove a few unwanted items as needed. The only thing I can't figure out is how-where to include a foreach loop that will populate the submenu items inside of the correct html tags (the toggled dropdown
).
The code is currently determining if there are children ... if it does not have children a link to that page will be included ... if it DOES have children the link needs to be disabled to allow the dropdown toggle and only the items in the submenu should have links.
Here's the code:
... and here's the unordered list that I'd like to target , or at least the html I'm trying to populate dynamically with the submenu items:
There's surprisingly very little information-documentation on this. Any insight, suggestions or links to other references-resources would be greatly appreciated. Thanks in advance for your help!
Try:
@* Run the traverse helper again for any child pages @Traverse(childPage, isHome) *@
} else {
} } }
I don't know why but I can't reply to your post, David, BUT ... that definitely helped. Moving the traverse helper up above the "} else {" and rearranging the html around it a bit did the trick. Works perfectly now.
Here's the revised-functional code block for anyone else looking for help creating dynamic dropdown menus (this one includes a searchbar and mobile-ready collapse menu functionality) in v7.6 and using bootstrap ... just make sure to implement umbracoNaviHide in your document types so you filter pages out of the nav as needed :
I really appreciate your help David. So far the Umbraco developer community has definitely lived up to it's reputation. Thanks again!
is working on a reply...
This forum is in read-only mode while we transition to the new forum.
You can continue this topic on the new forum by tapping the "Continue discussion" link below.
Continue discussion