Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • syn-rg 282 posts 425 karma points
    May 12, 2011 @ 09:41
    syn-rg
    0

    Classes for first and last item menu and submenu items

    I'm trying to add classes for my first and last items in my menu.

    It's for my main menu which a horizontal menu, with drop downs. Each drop down is a submenu of the main nav item. I currently have 5 items in the main menu, with a max-limit of 7 items. Each item applies a "current' class when on that current page.

    I'll describe the 5 items as "level 1" and their submenu as "level 2". I want the 1st and 7th item to have the class "first" and "last" respectively. But not for this to follow into the level 2.
    I want it to retain it's "current" class as well when on that page, and when viewing pages within it's submenu.

    I want level 2 to apply the class "last" to any link which is the last link. I don't want level 2 to have a "first" class applied.

    As you can see below, my menu is being populated by the same code. I need to it differentiate between a child and a parent node.

    Can anybody suggest a way of doing this? I've viewed the following pages already: classes for first and last item and is it possible to specify a class for fist and last navigation item?

    Cheers,
    JV

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]>
    <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"
      exclude-result-prefixes="msxml umbraco.library">


    <xsl:output method="xml" omit-xml-declaration="yes"/>

    <xsl:param name="currentPage"/>

    <!-- update this variable on how deep your navigation should be -->
    <xsl:variable name="maxLevel" select="5"/>

    <xsl:template match="/">

    <div class="ddsmoothmenu" id="global_nav">
    <ul>
    <xsl:call-template name="drawNodes"> 
    <xsl:with-param name="parent" select="$currentPage/ancestor-or-self::node [@level=1]"/> 
    </xsl:call-template>
    </ul>
    </div>
    <xsl:variable name="ddlevel">//ddlevelsmenu.setup("ddtopmenubar", "topbar");</xsl:variable>
    <xsl:value-of select="umbraco.library:RegisterClientScriptBlock('ddlevel', $ddlevel, true())"/>
    </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/node [string(./data [@alias='topMenu']) = '1' and @level &lt;= $maxLevel and (umbraco.library:IsProtected(@id, @path) = false() or umbraco.library:HasAccess(@id, @path) = true())]">

    <xsl:variable name="liId">
        <xsl:call-template name="replaceCharsInString">
          <xsl:with-param name="stringIn" select="@nodeName"/>
          <xsl:with-param name="charsIn" select="' '"/>
          <xsl:with-param name="charsOut" select="'_'"/>
        </xsl:call-template>
      </xsl:variable>

    <li>
    <xsl:attribute name="id"><xsl:value-of select="$liId" /></xsl:attribute>

    <a href="{umbraco.library:NiceUrl(@id)}">
    <xsl:if test="$currentPage/ancestor-or-self::node/@id = @id">
      <xsl:attribute name="class">current</xsl:attribute>
    </xsl:if>
    <xsl:if test="count(./node [string(./data [@alias='topMenu']) = '1' and @level &lt;= $maxLevel]) &gt; 0">
      <xsl:attribute name="rel"><xsl:value-of select="@id" /></xsl:attribute>
    </xsl:if>

            <xsl:choose>
               
    <xsl:when test="position() = 1">
                   
    <xsl:attribute name="class">first</xsl:attribute>
               
    </xsl:when>
               
    <xsl:when test="position() = last()">
                   
    <xsl:attribute name="class">last</xsl:attribute>
               
    </xsl:when>
           
    </xsl:choose>
           
    <xsl:value-of select="@nodeName" />

     </a> 
    <xsl:if test="count(./node [string(./data [@alias='topMenu']) = '1' and @level &lt;= $maxLevel]) &gt; 0">  
      <ul class="ddPageTools_submenustyle" id="{@id}">
        <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:template name="replaceCharsInString">
      <xsl:param name="stringIn"/>
      <xsl:param name="charsIn"/>
      <xsl:param name="charsOut"/>
      <xsl:choose>
        <xsl:when test="contains($stringIn,$charsIn)">
          <xsl:value-of select="concat(substring-before($stringIn,$charsIn),$charsOut)"/>
          <xsl:call-template name="replaceCharsInString">
            <xsl:with-param name="stringIn" select="substring-after($stringIn,$charsIn)"/>
            <xsl:with-param name="charsIn" select="$charsIn"/>
            <xsl:with-param name="charsOut" select="$charsOut"/>
          </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$stringIn"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>

    </xsl:stylesheet>
  • Stuart Burrows 61 posts 110 karma points
    May 13, 2011 @ 14:11
    Stuart Burrows
    1

    Hi there,

    You could try replacing the anchor code with this:

    <a href="{umbraco.library:NiceUrl(@id)}">
      <xsl:if test="count(./node [string(./data [@alias='topMenu']) = '1' and @level &lt;= $maxLevel]) &gt; 0">
        <xsl:attribute name="rel"><xsl:value-of select="@id" /></xsl:attribute>
      </xsl:if>
      <xsl:attribute name="class">
        <xsl:if test="$currentPage/ancestor-or-self::node/@id = @id">
          <xsl:text>current</xsl:text>
        </xsl:if>
        <xsl:choose>
          <xsl:when test="position() = 1 and @level = 2">
              <xsl:text> first</xsl:text>
          </xsl:when>
          <xsl:when test="position() = last() and @level = 2">
              <xsl:text> last</xsl:text>
          </xsl:when>
        </xsl:choose>
      </xsl:attribute>
      
      <xsl:value-of select="@nodeName" />
    </a>

    Using only one attribute statement with nested conditions means that you can and will get some empty attributes being drawn. To counter this you can wrap the attribute in an if statement that encompasses all nested conditions. Like so:

    <xsl:if test="$currentPage/ancestor-or-self::node/@id = @id OR position() = 1 OR position() = last()">
      <!--code pasted above -->
    </xsl:if>

    I hope that helps!

     

  • syn-rg 282 posts 425 karma points
    May 16, 2011 @ 02:15
    syn-rg
    0

    Thanks Stuart,

    That works really well!

    I have added the following code as I have a limit of 7 items on level 1 menu.

    <xsl:variable name="maxItems" select="6"/>

     

    <a href="{umbraco.library:NiceUrl(@id)}">
    <xsl:if test="count(./node [string(./data [@alias='topMenu']) = '1' and @level &lt;= $maxLevel]) &gt; 0">
    <xsl:attribute name="rel"><xsl:value-of select="@id" /></xsl:attribute>
    </xsl:if>
    <xsl:attribute name="class">
    <xsl:if test="$currentPage/ancestor-or-self::node/@id = @id">
    <xsl:text>current</xsl:text>
    </xsl:if>
    <xsl:choose>
    <!-- Main menu -->
    <xsl:when test="position() = 1 and @level = 2">
    <xsl:text> first</xsl:text>
    </xsl:when>
    <xsl:when test="position() &gt; $maxItems and @level = 2">
    <xsl:text> last</xsl:text>
    </xsl:when>
    <!-- Submenu -->
    <xsl:when test="position() = last() and @level = 3">
    <xsl:text> last</xsl:text>
    </xsl:when>
    </xsl:choose>
    </xsl:attribute>
    <xsl:value-of select="@nodeName" />
    </a>

    Thanks for your help Stuart!

  • Stuart Burrows 61 posts 110 karma points
    May 16, 2011 @ 09:44
    Stuart Burrows
    0

    No worries, glad it worked for you :)

Please Sign in or register to post replies

Write your reply to:

Draft