How to display sibling menu items in a menu object in DDRMenu

280 Views Asked by At

I'm working with nav.cshtml in DNN's DDRMenu. On pages for this website, I'd like to display a menu at the top of the page that only shows the child pages of the current page, if there are any, and if not shows the sibling pages of the current page.

Here's the code:

@using DotNetNuke.Web.DDRMenu;
@using System.Dynamic;
@inherits DotNetNuke.Web.Razor.DotNetNukeWebPage<dynamic>

@{
 var root = Model.Source.root;
}

@helper RenderNodes(IList<MenuNode> nodes)
{
if (nodes.Count > 0)
{
  <ul class="navbar-nav ml-auto">
   @foreach (var node in nodes)
   {
    String isActive = "";
    string isDisabled = "";
    if (node.Selected) { isActive = "active"; }
    if (!node.Enabled) { isDisabled = "disabled"; }

    if (node.HasChildren())
    {
     <li class="nav-item parent">
      <a href="@node.Url" class="@isActive @isDisabled nav-link">@node.Text</a>
      <button class="submenuButton" onclick="$(this).toggleClass('active'); return false;">
       <i class="fa fa-caret-down" aria-hidden="true"></i>
      </button>
      @RenderChildNodes(node.Children)
     </li>
    }
    else
    {
     <li class="nav-item"><a href="@node.Url" class="@isActive @isDisabled nav-link">@node.Text</a></li>
    }
   }<!-- ./ for loop -->
  </ul>
}<!-- ./ node count -->
}<!-- ./ helper -->

@helper RenderChildNodes(IList<MenuNode> nodes)
{
if (nodes.Count > 0)
{
  <ul class="children bg-primary text-white rounded list-unstyled text-left ml-0">
   @foreach (var node in nodes)
   {
    String isActive = "";
    string isDisabled = "";
    if (node.Selected) { isActive = "active"; }
    if (!node.Enabled) { isDisabled = "disabled"; }

    if (node.HasChildren())
    {
     <li class="nav-item px-1">
      <button class="submenuButton" onclick="$(this).toggleClass('active'); return false;">
       <i class="fa fa-caret-down" aria-hidden="true"></i>
      </button>
      <a href="@node.Url" class="@isActive @isDisabled nav-link">@node.Text</a>
      @RenderChildNodes(node.Children)
     </li>
    }
    else
    {
     <li class="nav-item px-1 "><a href="@node.Url" class="@isActive @isDisabled nav-link">@node.Text</a></li>
    }
 

<!-- begin snippet: js hide: true console: true babel: false -->

Essentially, I need to figure out how to display the siblings, if the current page is selected but doesn't have children:

if (!node.HasChildren() && node.Selected) {
    <!--Display Sibling nodes-->
}

Any help will be much appreciated.

2

There are 2 best solutions below

0
On

I'm not perfect in scripting Razorpages, but I'll give it a try:

@using DotNetNuke.Web.DDRMenu;
@using System.Dynamic;
@using System.Linq;
@inherits DotNetNuke.Web.Razor.DotNetNukeWebPage<dynamic>

@{
   var root = Model.Source.root;
}

@helper RenderNodes(IList<MenuNode> nodes)
{
   if (nodes.Count > 0)
   {
      //Check if the selected node is in the nodes & hasChildren.
      var activeNode= nodes.FirstOrDefault(n=>n.Selected);
      if(activeNode != null && activeNode.HasChildren())
      {
         <li class="nav-item parent">
              <a href="@node.Url" class="@isActive @isDisabled nav-link">@node.Text</a>
              <button class="submenuButton" onclick="$(this).toggleClass('active'); return false;">
              <i class="fa fa-caret-down" aria-hidden="true"></i>
              </button>
              @RenderChildNodes(node.Children)
         </li>

      }
      else
      {
        <ul class="navbar-nav ml-auto">
            @foreach (var node in nodes)
            {
                String isActive = "";
                string isDisabled = "";
                if (node.Selected) { isActive = "active"; }
                if (!node.Enabled) { isDisabled = "disabled"; }

                if (node.HasChildren())
                {
                    <li class="nav-item parent">
                        <a href="@node.Url" class="@isActive @isDisabled nav-link">@node.Text</a>
                        <button class="submenuButton" onclick="$(this).toggleClass('active'); return false;">
                            <i class="fa fa-caret-down" aria-hidden="true"></i>
                        </button>
                        @RenderChildNodes(node.Children)
                    </li>
                }
                else
                {
                    <li class="nav-item"><a href="@node.Url" class="@isActive @isDisabled nav-link">@node.Text</a></li>
                }
            }<!-- ./ for loop -->
        </ul>
      }
   }<!-- ./ node count -->
}<!-- ./ helper -->

Is this what you need, or is there anything missing?

0
On

Here's what we ended up with.

@using DotNetNuke.Web.DDRMenu;
@using System.Dynamic;
@using DotNetNuke.Entities.Portals;
@inherits DotNetNuke.Web.Razor.DotNetNukeWebPage<dynamic>

@{
 var root = Model.Source.root;
}

@helper RenderNodes(IList<MenuNode> nodes)
{
 if (nodes.Count > 0)
 {
  <ol class="breadcrumb">
   @foreach (var node in nodes)
   {
    foreach (var child in node.Children)
    {
     if (child.Text == PortalSettings.Current.ActiveTab.TabName)
     {
      if (node.Parent.Children.Count > 0)
      {
       @RenderChildNodes(node.Children)
      }
     }
    }

    if(node.Selected && node.Depth == 0 && node.HasChildren())
    {
     @RenderChildNodes(node.Children)
    }
   }<!-- ./ for loop -->
  </ol>
 }<!-- ./ node count -->
}<!-- ./ helper -->

@helper RenderChildNodes(IList<MenuNode> nodes)
{
 if (nodes.Count > 0)
 {
  foreach (var node in nodes)
  {
   string isActive = "";
   string isDisabled = "";
   if (node.Selected) { isActive = "active"; }
   if (!node.Enabled) { isDisabled = "disabled"; }

   <li class="breadcrumb-item @isActive">
    <a href="@node.Url" class=" @isDisabled">@node.Text</a>
   </li>
  }
 }
}

@RenderNodes(root.Children)

<script>
 if ($('.breadcrumb-item').length > 0)
  $('.breadcrumb').show();
 else
  $('.breadcrumb').hide();
</script>