Active navigation, that stays active in sub-pages?
I'm having a bit of trouble creating a navigation that applies an active class to the level 1 <li> when on one of it's sub pages. How would I go about doing so?
here's full xslt taken from sitemap that shows 'active' page [for ul/li collapsable site navigation]
slightly modified from what I'm using- should work fine in most cases also allows for custom 'this point down' menus by setting the xpath on the GetXmlNodeByXPath call
<xsl:template name="drawNodes"> <xsl:param name="parent"/> <xsl:if test="umbraco.library:IsProtected($parent/@id, $parent/@path) = 0 or (umbraco.library:IsProtected($parent/@id, $parent/@path) = 1 and umbraco.library:IsLoggedOn() = 1)"> <xsl:for-each select="$parent/* [@isDoc and @level <= $maxLevelForSitemap and string(umbracoNaviHide)!='1']">
<li onmouseover="$(this).addClass('over');" onmouseout="$(this).removeClass('over');" > <!-- duplicate ^ "over' class here to "open" class from below and you have a fully expandable/collapsable with active state hierarchical menu-->
I am having the same problem, but I am working in razor. So none of this is making any sense to me. Can someone please help me with this same issue? I also need the top nav to stay selected when I move onto a subnav.
I am using the topNavigation code that is commonly used in Umbraco (with some slight modifictaions):
Active navigation, that stays active in sub-pages?
I'm having a bit of trouble creating a navigation that applies an active class to the level 1 <li> when on one of it's sub pages. How would I go about doing so?
You may use the parentId attribute of the currentPage
<xsl:for-each select="$firstLevelMenuItems">
<li>
<xsl:if test="$currentPage/@id=@id or ($currentPage/@parentID=@id)">
<xsl:attribute name="class">current</xsl:attribute>
</xsl:if>
<a href="{umbraco.library:NiceUrl(@id)}">
<xsl:value-of select="@nodeName" />
</a>
</xsl:if>
</li>
</xsl:for-each>
If you are in a for-each loop on the first level you can test the node if one of his descendants is selected via
hth, Thomas
BTW: you can test it on every level ;-)
Thomas
Of course not. For lower levels you may use the path attribute
Try this (not tested)
Nice solution Thomas. I hadn't see your previous post and I thought you were asking if my previous solution works on any level.
here's full xslt taken from sitemap that shows 'active' page [for ul/li collapsable site navigation]
slightly modified from what I'm using- should work fine in most cases also allows for custom 'this point down' menus by setting the xpath on the GetXmlNodeByXPath call
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp " "> ]>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxml="urn:schemas-microsoft-com:xslt"
xmlns:umbraco.library="urn:umbraco.library" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets" xmlns:tagsLib="urn:tagsLib"
exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets tagsLib ">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:param name="currentPage"/>
<xsl:variable name="level" select="1"/>
<xsl:variable name="source" select="umbraco.library:GetXmlNodeByXPath('/root') [string(umbracoNaviHide)!='1']" />
<!--
update this variable on how deep your site map should be
-->
<xsl:variable name="maxLevelForSitemap" select="10"/>
<xsl:template match="/">
<ul class="nav_list">
<xsl:call-template name="drawNodes">
<xsl:with-param name="parent" select="$source"/>
</xsl:call-template>
</ul>
</xsl:template>
<xsl:template name="drawNodes">
<xsl:param name="parent"/>
<xsl:if test="umbraco.library:IsProtected($parent/@id, $parent/@path) = 0 or (umbraco.library:IsProtected($parent/@id, $parent/@path) = 1 and umbraco.library:IsLoggedOn() = 1)">
<xsl:for-each select="$parent/* [@isDoc and @level <= $maxLevelForSitemap and string(umbracoNaviHide)!='1']">
<li onmouseover="$(this).addClass('over');" onmouseout="$(this).removeClass('over');" >
<!-- duplicate ^ "over' class here to "open" class from below and you have a fully expandable/collapsable with active state hierarchical menu-->
<xsl:if test="contains( concat($currentPage/@path, ','), concat(',', @id, ',') )">
<xsl:attribute name="class">open</xsl:attribute>
</xsl:if>
<a href="{umbraco.library:NiceUrl(@id)}">
<xsl:value-of select="@nodeName" />
</a>
<xsl:if test="count(./* [@isDoc and string(umbracoNaviHide) != '1' and @level <= $maxLevelForSitemap]) > 0">
<ul>
<xsl:call-template name="drawNodes">
<xsl:with-param name="parent" select="."/>
</xsl:call-template>
</ul>
</xsl:if>
</li>
</xsl:for-each>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
I am having the same problem, but I am working in razor. So none of this is making any sense to me. Can someone please help me with this same issue? I also need the top nav to stay selected when I move onto a subnav.
I am using the topNavigation code that is commonly used in Umbraco (with some slight modifictaions):
@inherits umbraco.MacroEngines.DynamicNodeContext
@{
var level = String.IsNullOrEmpty(Parameter.Level) ? 1 : int.Parse(Parameter.Level);
var ulClass = String.IsNullOrEmpty(Parameter.UlClass) ? "" : String.Format(" class=\"{0}\"", Parameter.UlClass);
var parent = @Model.AncestorOrSelf(level);
if (parent != null) {
<ul@Html.Raw(ulClass) class="nav">
@if(level == 1 && parent.Where("Visible")) {
var selected = Model.Path.EndsWith(parent.Id.ToString()) ? " class=\"active\"" : "";
<li>
<a href="@parent.Url" @Html.Raw(selected)>@parent.umbracoUrlAlias</a>
</li>
}
@foreach (var item in parent.Children.Where("Visible")) {
var selected = Model.Path.EndsWith(item.Id.ToString()) ? " class=\"active\"" : "";
<li>
<a href="/@item.umbracoUrlAlias" @Html.Raw(selected)>@item.umbracoUrlAlias</a>
</li>
}
</ul>
}
}
Nevermind. I found it here: http://our.umbraco.org/forum/developers/razor/25086-Top-Menu-active-when-sub-page-selected
@inherits umbraco.MacroEngines.DynamicNodeContext
@{
var level = String.IsNullOrEmpty(Parameter.Level) ? 1 : int.Parse(Parameter.Level);
var ulClass = String.IsNullOrEmpty(Parameter.UlClass) ? "" : String.Format(" class=\"{0}\"", Parameter.UlClass);
var parent = @Model.AncestorOrSelf(level);
if (parent != null) {
<ul@Html.Raw(ulClass) class="nav">
@if(level == 1 && parent.Where("Visible")) {
var selected = Model.Path.EndsWith(parent.Id.ToString()) ? " class=\"active\"" : "";
<li>
<a href="@parent.Url" @Html.Raw(selected)>@parent.umbracoUrlAlias</a>
</li>
}
@foreach (var item in parent.Children.Where("Visible")) {
var selected = Array.IndexOf(Model.Path.Split(','), item.Id.ToString()) >= 0 ? " class=\"active\"" : "";
<li>
<a href="/@item.umbracoUrlAlias" @Html.Raw(selected)>@item.umbracoUrlAlias</a>
</li>
}
</ul>
}
}
is working on a reply...