cloudscribe/cloudscribe.Web.Navigation

Can't get currentNode for sidebar

Closed this issue · 18 comments

Hi,

I have an issue for get the current node of the children of a children.

Let me explain, I have a sidenav and a topnav on my website. The topnav is just for the NavNode where parentKey="RootNode". The topnav is my principal nav and the sidebar is used to display their children when the user is in the current node of one of the tabs in the topbar.

Like this :

capture-1

capture-2

Now my issue is : I cant get the current node when I want to edit my table in another page with the project Id passed on URL like this :

capture-3

but I can go to this controller without an Id :
capture-4

I found the solution to Create or Edit with an Id when I remove the line :
if (node.EqualsNode(Model.CurrentNode))

But the issue is my sidebar display all childrens of xml navigation file like this :
capture-5

Those are the Shared files :

Topbar.cshtml : (I post th topbar file on pastebin because indentation is bad when i paste in there.)
http://pastebin.com/NiL5sBZw

Sidebar.cshtml :

`@if (Model.HasVisibleChildren(Model.RootNode))
{

foreach (var node in Model.RootNode.Children)
{
    if (!Model.ShouldAllowView(node)) { continue; }
    if (node.EqualsNode(Model.CurrentNode))
    {
        if (!Model.HasVisibleChildren(node))
        {
            @:
            <li class="@Model.GetClass(node.Value)">
                <a href="@Url.Content(Model.AdjustUrl(node))">
                    <i class="@node.Value.IconCssClass"></i><span>@Model.AdjustText(node)</span>
                </a>
            </li>
        }
        else
        {
            @:
            <li class="@Model.GetClass(node.Value)">
                @Model.UpdateTempNode(node)
                @Html.Partial("Partials/NodeSideNavPartial", Model)
            </li>
        }
    }
}

}`

NodeSideNavPartial.cshtml :

`@if ((Model.TempNode != null) && (Model.HasVisibleChildren(Model.TempNode)))
{
@foreach (var childNode in Model.TempNode.Children)
{
if (!Model.ShouldAllowView(childNode)) { continue; }

    if (!Model.HasVisibleChildren(childNode))
    {
        @:
        <li class="@Model.GetClass(childNode.Value)">
            <a href="@Url.Content(Model.AdjustUrl(childNode))">
                <i class="@childNode.Value.IconCssClass"></i><span>@childNode.Value.Text</span>
            </a>
        </li>
    }
    else
    {
        <li class="@Model.GetClass(childNode.Value)">
            <a href="@Url.Content(Model.AdjustUrl(childNode))">
                <i class="@childNode.Value.IconCssClass"></i><span>@childNode.Value.Text</span>
            </a>
            @Model.UpdateTempNode(childNode)
            @Html.Partial("Partials/NodeSideNavPartial", Model) @* recursion *@
        </li>
    }
}

}`

And the navigation.xml :

`

<NavNode key="Saisie" parentKey="RootNode" controller="Saisie" action="TableauDeBord" text="Saisie">
  <Children>
    <NavNode key="TableauDeBord" parentKey="Saisie" controller="Saisie" action="TableauDeBord" text="Tableau de bord" iconCssClass="fa fa-tachometer">
      <Children />
    </NavNode>
    <NavNode key="Kanban" parentKey="Saisie" controller="KanbanBoard" action="Index" text="kanban" iconCssClass="fa fa-share-alt">
      <Children />
    </NavNode>
  </Children>
</NavNode>

<NavNode key="Administration" parentKey="RootNode" controller="Projet" action="Index" text="Administration">
  <Children>
    <NavNode key="Projets" parentKey="Administration" controller="Projet" action="Index" text="Projets" iconCssClass="fa fa-file-powerpoint-o">
      <Children>
        <NavNode key="Fiche" parentKey="Projets" controller="Projet" action="CreateEdit" text="CRUD" preservedRouteParameters="id" componentVisibility="false">
          <Children />
        </NavNode>
      </Children>
    </NavNode>
    <Children />
    <NavNode key="Utilisateurs" parentKey="Administration" controller="Utilisateur" action="Index" text="Utilisateurs" iconCssClass="fa fa-tachometer">
      <Children />
    </NavNode>
  </Children>
</NavNode>

<NavNode key="Déploiement" parentKey="RootNode" controller="Deploiement" action="Alive" text="Déploiement">
  <Children>
    <NavNode key="Alive" parentKey="Déploiement" controller="Deploiement" action="Alive" text="Alive" iconCssClass="fa fa-tachometer">
      <Children />
    </NavNode>
  </Children>
</NavNode>
`

Now my question is : How can i display just the children of the current NavNode like "Adminisitration" in previous exemples ?

Thanx for helping and grieve if you do not understand me ^^

the CurrentNode property of the viewmodel is intended to be determined from the current url, it could be null sometimes if it can't determine which navigation node should have that url. Are you saying it is null when it should be able to match?

are you saying that it works if the url matches a controller/action but it is null if the url has query string paramters like controller/action?param=foo
?

it is possible to specify a startingNodeKey when invoking the navigation, ie the key of a node from the navigation.xml

@await Component.InvokeAsync("Navigation", new { viewName = "ChildTree", filterName = NamedNavigationFilters.ChildTree, startingNodeKey = "Administration" })

it is also possible to filter out nodes from a particular view using a filter name as in this example:

<NavNode key="NewSite" 
                 parentKey="SiteList" 
                 controller="SiteAdmin" 
                 action="NewSite" 
                 text="New Site" 
                 componentVisibility="breadcrumbs,childtree" 
                 viewRoles="ServerAdmins">
          <Children />
        </NavNode>

if componentVisibility is blank then it will not be filtered from any view, but if you populate componentVisibility then it will only be visible when the filterName matches one of the items in that setting, so for the example above the node will be filtered unless the the filterName is either breadcrumbs or childtree, so this item will only be visible in breadcrumbs or childtree, it own't be visible in topnav for example. I tend to use filter names that are the same as the viewName, but there is no requirement for filtername to be the same as viewname

I'm looking into the issue about CurrentNode being null, I think there are some cases where it is not resolving that as it should

I would think that if your goal is to show children nodes of current node in the sidebar then the sidebar view should be like:

if(Model.CurrentNode != null)
{
    foreach (var node in Model.CurrentNode.Children)
    {
      ...
     }
}

instead of using RootNode

but again for this to work CurrentNode must not be null

can you try dotnet restore --no-cache to get the new version 1.0.2-rc20160822

and see if it solves the problem where CurrentNode is null

Okay, i try your answer and now i have the current node when i'm in CreateController but the children of topbar are not display.

I will explain you again because i think i hurt explain my issue, then you need to look my screen for a better comprehension.

capture-6

The red block is a tab of the topbar, in this tab of the topbar I have his children on green block which are displayed in the sidebar. In these children i can have children too, but they are not displayed in the sidebar because they are dependant of their father green block but i always want to display all children green block of the red block and display the father of blue block like the current tab of sidebar.

This is my goal, i hope my explain is better and you have an idea to help me otherwise no worries and thank you.

I think if you could make a sample project in a public git repo that demonstrates the problem, then I will understand it better and I could try to solve it

I'm sorry but it's a private project for a client, I will try to make a video of my issues in a few moment, maybe is can be better.

I don't mean for you to use your client's project, I mean try to make a small new project that illustrates the problem. that way I can see the actual code and I can try to fix it

Okay no problem i'll do this

maybe you could fork this project and create the problem in the demo app

I have done the project with your exemple, you can download in this url : https://github.com/alimtunc/CloudstribeBugTest/tree/master/cloudscribe.Web.Navigation-master

When you start the project, for test the bug you need to follow these instruction :

  • Click on administration Tab
  • Click on project tab
  • Click on "go to edit" button

Second bug :

  • Click on "utilisateur" tab and the tab of sidebar disappear

Sorry for the design of this project but it's not the principal problem, we can see carefully the issue. Maybe this project can show you my issues and thank for help.

I'm not sur I answer you this night but done what you have to do and I will see tomorrow. Good luck

your project is missing some files, project.json and other files are missing but I copied them from my project.
but also your custom navigation views are missing, isn't there supposed to be a custom sideNav.cshtml and TopNav.cshtml?
can you add those?

I did get the null exception on /Projet/Edit but I fixed that by editing the navigation.xml

I changed this:

<NavNode key="Fiche" parentKey="Projets" controller="Projet" action="Create" text="CRUD" preservedRouteParameters="id" componentVisibility="false">
        </NavNode>

to this:

<NavNode key="Fiche" parentKey="Projets" controller="Projet" action="Edit" text="CRUD" preservedRouteParameters="id" componentVisibility="ChildTree">
        </NavNode>

the if an action is not included in the menu then there is no currentNode for it to find so you need a node for the Edit action, then filter it out of what views you don't want to show it in

for any controller/action to be found as the CurrentNode it must exist in the navigation.xml

I have a similar situation in my main cloudscribe project where certain nodes for things like new site, edit site etc I don't want in the top navigation so I filter them for only childnav or breadcrumbs, you may get some ideas looking at the navigation.xml file I'm using there

Yes sorry my bad and the custom Topnav and Sidenav are the default name, I just put my code into them.
I see the navigation xml and again my bad, I forgot to replace the "action='Create'" to "action='Edit'" but yes now you can see the real issue to display the sidebar, I will try with your navigation.xml file now.

but TopNav and SideNav don't exist in your repository so I don't have your code for them and cannot see the problem as you do. I see you added me to the repo so I could commit, but for some reason I get an error when I try to clone the repo so I just download the zip

Hi, I have found a solution to my issue and it work good ! And I seen the file .gitignore have add these ligne :
src/cloudscribe.Web.Navigation/project.lock.json src/NavigationDemo.Web/wwwroot/lib* src/NavigationDemo.Web/wwwroot/js/* src/NavigationDemo.Web/wwwroot/css/site.min.css src/NavigationDemo.Web/project.lock.json test/cloudscribe.Web.Navigation.Test/project.lock.json src/cloudscribe.Web.SiteMap/project.lock.json src/cloudscribe.Web.SiteMap.FromNavigation/project.lock.json *.json src/cloudscribe.Web.SiteMap.FromNavigation/project.lock.json

Then It's why you don't have some files. Anyway, for explain my solution I modified the SideNav.cshtml to :
http://pastebin.com/haJhKt7G

The TopNav.cshtml to :
http://pastebin.com/DdKqtGw6

And the SideNavPartial.cshtml to :
http://pastebin.com/GNVyLgvY

I can manage specific cases now because you fix the bug to know where we are if we are a children from a children and it's great :)

## Thank's for your help again and for being patient !

ok, glad it is working for you, so this issue can be closed?

Yes, I close, good continuation ;)