2

This is the first time I have ever posted a question so apologese in advance if I jibber here.

I am trying to put together a CQWP with jQuery tabs slider functionality. The HTML I want to output should be in the form of 2 UL's. The first with li anchor tags with #associated-ul-id

The second ul's should have ids that associate with the list items in the first. Eg

<div id="tabs" class="news">
    <div class="news-pagination">
        <a href="#" id="carouseltext-prev">&laquo; Prev</a>
        <ul id="carouseltext" class="horizontal-text order">
            <li><a href="#tabs-1">System</a></li>
            <li><a href="#tabs-2">School</a></li>
        </ul>
        <a href="#" id="carouseltext-next">&raquo; Next</a>
        <div class="clear">&nbsp;</div>
    </div>
    <ul id="tabs-1" class="feed order">
        <li>title 1</li>
        <li>title 2</li>
     </ul>
    <ul id="tabs-2" class="feed order">
        <li>title 3</li>
    </ul>
</div>

The original XML starts off in the form

My XSL goes through the XML twice to fill the 2 ul's. The first time it just adds a new list item when the __begincolumn and __begingroup variables are true. I striped down the functionality here to just output the header. Here's a stripped down version of the XSL

    <xsl:template match="/">
        <xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row" />
        <xsl:variable name="RowCount" select="count($Rows)" />
        <xsl:variable name="FirstRow" select="1" />
        <xsl:param name="ColNumber" select="1" />

        <xsl:for-each select="$Rows" >
            <xsl:variable name="CurPosition" select="position()" />
        <xsl:variable name="BeginNewsItemsList1" select="string('&lt;ul id=&quot;tabs-')" />
        <xsl:variable name="BeginNewsItemsList2" select="string('&quot;class=&quot;feed order&quot;&gt;')" />
        <xsl:variable name="BeginNewsItemsList" select="concat($BeginNewsItemsList1, $ColNumber, $BeginNewsItemsList2)" />

        <xsl:if test="($CurPosition &gt;= $FirstRow and $CurPosition &lt;= $LastRow)">
            <xsl:variable name="StartNewGroup" select="@__begingroup = 'True'" />
            <xsl:variable name="StartNewColumn" select="@__begincolumn = 'True'" />
            <xsl:when test="$StartNewGroup and $StartNewColumn">
                    <xsl:choose>
                <xsl:when test="$CurPosition = $FirstRow">
                    <xsl:value-of disable-output-escaping="yes" select="$BeginNewsItemsList" />
                </xsl:when>
                <xsl:otherwise>
                    <!-- other instructions -->
                </xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:when test="$StartNewGroup">
                <xsl:call-template name="OuterTemplate.CallFooterTemplate"/>
                <xsl:value-of disable-output-escaping="yes" select="concat($EndColumn, $BeginNewsItemsList)" />
            </xsl:when>
            <xsl:otherwise>
            </xsl:otherwise>
            </xsl:if>           
        </xsl:for-each>
    </xsl:template>

<xsl:template name="OuterTemplate.Count">
    <xsl:param name="ColNumber" />
    <xsl:value-of select="$ColNumber + 1" />
</xsl:template>

For the second for-each loop I'm having trouble setting up a counter so that I can add the number to the end of the id for each new list id="tabs-1", id="tabs-2", etc.

In theory I think I should set a parameter outside my for-each loop and then in the loop call a template that gets the parameter value and increments it. That would mean it would increment only when the template is called.

I can't use position() for this as it doesn't correspond to the values I want. I've tried to follow a couple a few blogs about recursive programming with xsl, but I can't seem to find anything that works. I'm sure I'm just writing the XSL wrong, but I'm having a bit of a brain dump now.

If anybody could point me in the right direction that would be awesome. Thanks very much.

Dee
  • 31
  • 6
  • Just to add, I know I can easily do this with jQuery, but I am trying to keep the client side scripting to a minimum. – Dee Mar 26 '12 at 06:02
  • It is not clear, whether you are trying to solve jQuery issue or xsl ) If second - just provide your xsl ) – Timur Sadykov Mar 26 '12 at 06:30
  • It's the XSL incrementing I'm struggling with. I just want to get the #tabs-1, #tabs-2 on the first list item anchors and then id=tabs-1, etc on the list items of the second list. Here's a stripped down version of the XSL – Dee Mar 26 '12 at 22:57
  • Sorry that took me so long to reply, I thought there was automatic emails when somebody replied. Was being a muppet! I have it open all the time now anyway :) Thank you for replying!! – Dee Mar 27 '12 at 00:02
  • much better, but still confusing ) Best way is to provide complete set of input and desired output data - to experiment with ) – Timur Sadykov Mar 27 '12 at 10:58

1 Answers1

1

You can't change variable's values after declaration. You can use them in expressions and/or pass as parameters. Thus, you can't use outside variable as counter explicitly. One available trick is recursive cycle like:

     <?xml version="1.0"?>

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:template match="root">
        <HTML>
           <BODY>
                <xsl:call-template name="for">
                    <xsl:with-param name="i" select="1"/>
                    <xsl:with-param name="n" select="5"/>
                </xsl:call-template>
           </BODY>
        </HTML>
     </xsl:template>

 <xsl:template name="for">
    <xsl:param name="i"/>
    <xsl:param name="n"/>
    <xsl:value-of select="$i"/>
    <xsl:if test="$i &lt; $n">
       <xsl:text>, </xsl:text>
       <xsl:call-template name="for">
            <xsl:with-param name="i" select="$i+1"/>
            <xsl:with-param name="n" select="$n"/>
       </xsl:call-template>
    </xsl:if>
</xsl:template>

result: 1, 2, 3, 4, 5

Timur Sadykov
  • 10,859
  • 7
  • 32
  • 45
  • Thank you Timur. It's similar to what I want to do, but I need to be able to just increment upon 2 different conditions (either when $StartNewGroup and $StartNewColumn are true and $CurPosition = $FirstRow or when $StartNewGroup = true). So I would need to call a template in the conditional statements inside the for-seach $Rows loop using a global parameter. It will be likely to be called every 10-20 rows, when ever the $NewGroup is true, so it wouldn't be able to be set up in a for 1-5 type structure. – Dee Mar 27 '12 at 23:10
  • It seems like it might be quite a complicated thing to do for the sake of avoiding using jQuery to try and keep things server-side. The other option would be to add the numbers to the anchors and id's client side with jQuery once I have done everything else with XSL. Do you think that's a better way of doing it? – Dee Mar 27 '12 at 23:10
  • what's your server-side technology? Why are you so sticked to xsl? – Timur Sadykov Mar 28 '12 at 01:48
  • I'm using SharePoint 2010. I think I might have gone overboard with trying to use XSL for this. I'll use jQuery. Thought I might have just been not able to understand something that was simple in XSL, but I'm just being a plum when it's easy to do it with jQuery. Sorry Timur, and thanks very much for your help!! :) – Dee Mar 28 '12 at 11:08