Copied to clipboard

Flag this post as spam?

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


  • Streety 358 posts 568 karma points
    Jan 19, 2011 @ 17:27
    Streety
    0

    Setting a class attribute to a ul li within XSLT

    Hello,

     

    I am trying to mimic a jquery nav applet I have used before within a Umbraco site using XSLT. I am nearly there but its not working as expected.

     

    The heirarchy I am trying to create is this:

                      <ul id="main-nav">
                        <li><a class="main-link" href="">Home</a>
                          <ul class="sub-links">
                                <li><a href="" title=""><img src="Images/arrow.png" />Item1</a> </li>
                                <li><a href="" title=""><img src="Images/arrow.png" />Item1</a> </li>
                            </ul>
                        </li>
                        <li><a class="main-link" href="">About</a>
                          <ul class="sub-links">
                                <li><a href="" title=""><img src="Images/arrow.png" />Item1</a> </li>
                                <li><a href="" title=""><img src="Images/arrow.png" />Item1</a> </li>
                            </ul>
                        </li>
                        <li><a class="close" title="Click to Collapse" href="#">X</a></li>
                      </ul>

    Note the classes for the top ul "Main-nav", the li "main-link" and the second ul "sub-links"

     

    I have a bit of Jquery that opens the slide panel (sub-link-bar) and shows the subordinates

    <script type="text/javascript">
       
        $(document).ready(function(){
            $("#main-nav li a.main-link").hover(function(){
                $("#main-nav li a.close").fadeIn();
                $("#main-nav li a.main-link").removeClass("active");            
                $(this).addClass("active");          
                $("#sub-link-bar").animate({
                    height: "40px"       
                });
                $(".sub-links").hide();
                $(this).siblings(".sub-links").fadeIn();
            }, function(){});
            $("#main-nav li a.close").hover(function(){
                $("#main-nav li a.main-link").removeClass("active");                      
                $(".sub-links").fadeOut();
                $("#sub-link-bar").animate({
                    height: "3px"       
                });  
                $("#main-nav li a.close").fadeOut();
            });
           
           
        });
       
        </script>

     

    HOWEVER!

    The bit of XSLT i am using doesn't let me style the second ul as it calculated:

    <?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" 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:PS.XSLTsearch="urn:PS.XSLTsearch"
      exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets PS.XSLTsearch ">

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

    <xsl:param name="currentPage"/>

    <!-- update this variable on how deep your site map should be -->
    <xsl:variable name="maxLevelForSitemap" select="4"/>

      <xsl:template match="/">


        <div id="sitemap">
          <xsl:call-template name="drawNodes">
            <xsl:with-param name="parent" select="$currentPage/ancestor-or-self::* [@isDoc and @level=1]"/>
          </xsl:call-template>
        </div>
      </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)">
         
    <ul id="main-nav">

            <xsl:for-each select="$parent/* [@isDoc and string(umbracoNaviHide) != '1' and @level &lt;= $maxLevelForSitemap]">
              <li><a class="main-link" href="{umbraco.library:NiceUrl(@id)}"><xsl:value-of select="@nodeName"/></a>
                <xsl:if test="count(./* [@isDoc and string(umbracoNaviHide) != '1' and @level &lt;= $maxLevelForSitemap]) &gt; 0">
                  <xsl:call-template name="drawNodes"><xsl:with-param name="parent" select="."/></xsl:call-template>

                  </xsl:if>
        </li>


            </xsl:for-each>
     <li><a class="close" title="Click to Collapse" href="#">X</a></li>

          </ul>

        </xsl:if>
      </xsl:template>
    </xsl:stylesheet>

     

    I appreciate that this may be rudimentary XSLT but I am struggling with it.

    I did modify the Jquery to look at the li ul nodes and this sort of works:

     

    <script type="text/javascript">
       
        $(document).ready(function(){
            $("#main-nav li a.main-link").hover(function(){
                $("#main-nav li a.close").fadeIn();
                $("#main-nav li a.main-link").removeClass("active");            
                $(this).addClass("active");          
                $("#sub-link-bar").animate({
                    height: "100px"       
                });
                $("li ul").hide();
                $(this).siblings("li ul").fadeIn();
            }, function(){});
           
     $("#main-nav li a.close").hover(function(){
                $("#main-nav li a.main-link").removeClass("active");                      
                $("li ul").fadeOut();
                $("#sub-link-bar").animate({
                    height: "3px"       
                });  
                $("#main-nav li a.close").fadeOut();
            });
           
           
        });
     
        </script>

    However the on:hover does not persist allowing me to select the subordinates.

     

    In a bit of a pickle.

     

    Can anyone help?

     

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 8x admin c-trib
    Jan 20, 2011 @ 00:19
    Chriztian Steinmeier
    1

    Hi Streety,

    I'm skipping all the jQuery stuff above - guessing you want the HTML output showed at first?

    Here's a no-frills, walk-in-the-park, simple XSLT template that does the trick, utilizing the built-in traversal techniques (apply-templates) and clean, short templates for the differing output versions of links:

    <?xml version="1.0" encoding="utf-8" ?>
    <xsl:stylesheet
        version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:umb="urn:umbraco.library"
        exclude-result-prefixes="umb"
    >
    
        <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
    
        <xsl:param name="currentPage" />
    
        <!-- Assuming the site root is at level 1, otherwise modify -->
        <xsl:variable name="siteRoot" select="$currentPage/ancestor-or-self::*[@level = 1]" />
    
        <xsl:template match="/">
            <ul id="main-nav">
                <xsl:apply-templates select="$siteRoot/*[@isDoc][not(umbracoNaviHide = 1)]" />
            </ul>
        </xsl:template>
    
        <!-- Template for top level nodes -->
        <xsl:template match="*[@isDoc]">
            <li>
                <a class="main-link" href=""><xsl:value-of select="@nodeName" /></a>
                <xsl:if test="*[@isDoc][not(umbracoNaviHide = 1)]">
                    <ul class="sub-links">
                        <xsl:apply-templates select="*[@isDoc][not(umbracoNaviHide = 1)]" mode="sub" />
                    </ul>
                </xsl:if>
            </li>
        </xsl:template>
    
        <!-- Sub levels -->
        <xsl:template match="*[@isDoc]" mode="sub">
            <li>
                <a href="">
                    <img src="/Images/arrow.png" />
                    <xsl:value-of select="@nodeName" />
                </a>
            </li>
        </xsl:template>
    
    </xsl:stylesheet>
    

    /Chriztian

  • Streety 358 posts 568 karma points
    Jan 20, 2011 @ 11:29
    Streety
    0

    Hi Chriztian,

    Thank you for your efforts. Unfortunately I get the top level links shown and not the sub links.

    Also the anchor hrefs don't seem to be wired up. Have I missed a stage?

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 8x admin c-trib
    Jan 20, 2011 @ 11:51
    Chriztian Steinmeier
    0

    Hi Streety,

    The anchors I left for you to fill in :-) - just use <a href="{umb:NiceUrl(@id)}">

    Are you not getting the correct HTML or does the jQuery stuff just not work? (The jQuery snippet seem to target some elements that are not in the HTML you supplied - e.g. the id "sub-link-bar" isn't provided anywhere, which could be a reason)

    How are you Content nodes structured? I was assuming something like:

    Content
    - Home
      - Item 1
      - Item 2
    - About
      - Item 1
      - Item 2

    /Chriztian

Please Sign in or register to post replies

Write your reply to:

Draft