tags:

views:

55

answers:

1

Hi Guys,

I am using xslt and I want to implement sorting on my href link.

below is the xslt part where I need to implement sorting.

     <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:tlink="urn:TridionLinking" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:utils="urn:XSLTExtensions" exclude-result-prefixes="xsl xlink tlink msxsl utils">
  <xsl:output method="xml" version="1.0" encoding="UTF-8" omit-xml-declaration="yes" />
  <!--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        Title:              View All the Destinations XHTML
        Description:  Render view all the destinations control
        Author:           Manoj Singh
    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-->
  <xsl:include href="dynamic_linking.xslt"/>

  <!-- Translations are still loaded here because of XHTML content, research a way around that -->
  <xsl:key name="kCityById" match="city" use="@id"/>
  <xsl:variable name="vLocations" select="document(concat($publicationPath, /list/resources/@location))/list"/>
  <xsl:variable name="destination" select="/list"/>
  <xsl:param name="publicationPath"/>
  <xsl:param name="pubURL"/>
  <xsl:param name="pageURL"/>

  <xsl:param name="region"/>
  <xsl:param name="country"/>


  <!-- offset controls the starting position of the results to show -->
  <xsl:param name="offset">0</xsl:param>
  <!-- blockSize controls how many results to show on a single page -->
  <xsl:param name="blockSize" select="15" />

  <!-- Amount of page links to show by default -->
  <xsl:param name="pagesShown">20</xsl:param>

  <xsl:variable name="totalHits" select="count(/list/destination[contains(concat($pubURL,@url),substring-before($pageURL,'/index.aspx'))])" />

  <xsl:template name="calcStart">
    <xsl:choose>
      <xsl:when test="$offset = 0">1</xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="($offset * $blockSize) + 1"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template name="calcEnd">
    <xsl:choose>
      <xsl:when test="(($offset + 1) * $blockSize) > $totalHits">
        <xsl:value-of select="$totalHits"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="($offset + 1) * $blockSize"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  <xsl:template name="pageNavigation">
    <xsl:param name="pageCount"/>
    <xsl:param name="currPage"/>
    <xsl:param name="showPages">
      <xsl:choose>
        <xsl:when test="$pagesShown > $pageCount">
          <xsl:value-of select="$pageCount"/>
        </xsl:when>
        <xsl:when test="($pagesShown mod 2) = 0">
          <xsl:value-of select="$pagesShown"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$pagesShown + 1"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:param>
    <xsl:param name="currEntry" select="1"/>
    <xsl:param name="offset">
      <xsl:choose>
        <xsl:when test="($currPage &lt; $showPages) or ($pageCount = 1)">0</xsl:when>
        <xsl:when test="$currPage > ($pageCount - $showPages + 1)">
          <xsl:value-of select="$pageCount - $showPages"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$currPage - ($showPages div 2) - 1"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:param>

    <!-- Header Processing -->
    <xsl:if test="$currEntry = 1">
      <xsl:if test="($pageCount > $showPages) and ($currPage >= $showPages)">
        <li>... </li>
      </xsl:if>
    </xsl:if>

    <xsl:if test="not ($currEntry > $showPages)">
      <li>
        <xsl:choose>
          <xsl:when test="($currEntry + $offset) = $currPage">
            <strong class="thisPage">
              <xsl:value-of select="$currEntry + $offset"/>
            </strong>
          </xsl:when>
          <xsl:otherwise>
            <a href="{utils:GetHashedUrl(concat($pageURL,'?offset=',$currEntry + $offset - 1,'&amp;blockSize=',$blockSize,'&amp;pagesShown=',$pagesShown))}">
              <xsl:value-of select="$currEntry + $offset"/>
            </a>
          </xsl:otherwise>
        </xsl:choose>
      </li>

      <xsl:if test="not ($currEntry >=  $showPages)">
        <li class="separatorLine">|</li>
      </xsl:if>

      <xsl:call-template name="pageNavigation">
        <xsl:with-param name="pageCount" select="$pageCount"/>
        <xsl:with-param name="currPage" select="$currPage"/>
        <xsl:with-param name="showPages" select="$showPages"/>
        <xsl:with-param name="currEntry" select="$currEntry + 1"/>
        <xsl:with-param name="offset" select="$offset"/>
      </xsl:call-template>
    </xsl:if>

    <!-- Footer Processing -->
    <xsl:if test="$currEntry = 1">
      <xsl:if test="($pageCount > $showPages) and (($pageCount - $currPage + 1) >= $showPages)">
        <li> ...</li>
      </xsl:if>
    </xsl:if>
  </xsl:template>

  <xsl:template name="displayPageNavigation">
    <div class="continueBar">
      <div class="continueBarLeft">
        <xsl:variable name="displayStart">
          <xsl:call-template name="calcStart"/>
        </xsl:variable>
        <xsl:variable name="displayEnd">
          <xsl:call-template name="calcEnd"/>
        </xsl:variable>
        <strong>
          <xsl:value-of select="utils:TextFormatted('DisplayingDestinations2Arg', concat($displayStart, '-', $displayEnd), $totalHits)"/>
        </strong>
      </div>
      <div class="continueBarRight">
        <ul class="paginationLinks">
          <!-- Show a back button when available -->
          <xsl:choose>
            <xsl:when test="$offset > 0">
              <li class="noBorder first">
                <a class="iconButtonBackBar" href="{$pageURL}?offset={$offset - 1}&amp;blockSize={$blockSize}&amp;pagesShown={$pagesShown}">
                  <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
                </a>
              </li>
            </xsl:when>
            <xsl:otherwise>
              <li class="noBorder first">
                <span class="iconButtonBackBarOff">
                  <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
                </span>
              </li>
            </xsl:otherwise>
          </xsl:choose>

          <!-- Output the page navigation links -->
          <xsl:call-template name="pageNavigation">
            <xsl:with-param name="pageCount">
              <xsl:choose>
                <xsl:when test="$blockSize >= $totalHits">1</xsl:when>
                <xsl:when test="($totalHits mod $blockSize) != 0">
                  <xsl:value-of select="ceiling($totalHits div $blockSize)"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="$totalHits div $blockSize"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:with-param>
            <xsl:with-param name="currPage" select="$offset + 1"/>
          </xsl:call-template>

          <!-- Show a next button when available -->
          <xsl:choose>
            <xsl:when test="(($offset + 1) * $blockSize) > $totalHits">
              <li class="last">
                <span class="iconButtonForwardBarOff">
                  <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
                </span>
              </li>
            </xsl:when>
            <xsl:otherwise>
              <li class="last">
                <a class="iconButtonForwardBar" href="{$pageURL}?offset={$offset + 1}&amp;blockSize={$blockSize}&amp;pagesShown={$pagesShown}">
                  <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
                </a>
              </li>
            </xsl:otherwise>
          </xsl:choose>
        </ul>
      </div>

      <div class="clearBoth">
        <xsl:comment/>
      </div>
    </div>
  </xsl:template>

  <!-- root match -->
  <xsl:template match="/list">
    <!--<xsl:value-of select="$publicationPath"/>-->
    <div class="brownBarContainer">
      <div class="brownBar">
        All Destinations
      </div>
    </div>
    <table width="100%" cellspacing="0" cellpadding="0" border="0" class="displayTable">
      <tbody>
        <tr>
          <th scope="col" class="first sortSelected">
            <div class="thPadding">              
              <xsl:element name="a">
                <xsl:attribute name="href"></xsl:attribute>                
                <xsl:attribute name="class">iconDownSortArrow</xsl:attribute>                
              </xsl:element>Destination
            </div>
          </th>
          <th scope="col" class="sortHover">
            <div class="thPadding">         
              <xsl:element name="a">
                <xsl:attribute name="href"></xsl:attribute>
                <xsl:attribute name="class">iconSortArrowOff</xsl:attribute>
              </xsl:element>Country
            </div>
          </th>
          <th scope="col" class="sortHover">
            <div class="thPadding">            
              <xsl:element name="a">
                <xsl:attribute name="href"></xsl:attribute>
                <xsl:attribute name="class">iconSortArrowOff</xsl:attribute>
              </xsl:element>Region
            </div>
          </th>
        </tr>
        <xsl:choose>
          <xsl:when test="$region='' and $country=''">
            <xsl:apply-templates select="destination">
              <xsl:sort select="@title" order="ascending" />
            </xsl:apply-templates>          
          </xsl:when>
          <xsl:when test="$country!=''">
            <xsl:apply-templates select="destination[city/@id=$vLocations/region/country[@id=$country]/city/@id]">
              <xsl:sort select="@title" order="ascending" />
            </xsl:apply-templates>
          </xsl:when>
          <xsl:when test="$region!=''">
            <xsl:apply-templates select="destination[city/@id=$vLocations/region[@id=$region]/country/city/@id]">
              <xsl:sort select="@title" order="ascending" />
            </xsl:apply-templates>
          </xsl:when>
        </xsl:choose>
      </tbody>
    </table>
    <div class="horRuleWhite">
      <hr/>
    </div>
    <xsl:call-template name="displayPageNavigation" />
  </xsl:template>
  <xsl:template match="text()"/>
  <xsl:template match="destination">
    <xsl:variable name="vReverseURL">
      <xsl:call-template name="reverse">
        <xsl:with-param name="string" select="@url"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="vCountryURL">
      <xsl:call-template name="reverse">
        <xsl:with-param name="string" select="substring-after($vReverseURL,'/')"/>
      </xsl:call-template>
      <xsl:text>/index.aspx</xsl:text>
    </xsl:variable>
    <xsl:variable name="vRegionURL">
      <xsl:call-template name="reverse">
        <xsl:with-param name="string" select="substring-after(substring-after($vReverseURL,'/'),'/')"/>
      </xsl:call-template>
      <xsl:text>/index.aspx</xsl:text>
    </xsl:variable>
    <xsl:variable name="current" select="."/>    
    <xsl:for-each select="$vLocations">   
      <tr>
        <td class="detail first">          
          <a class="arrowSmallFront" href="{$current/@url}">           
            <xsl:value-of select="$current/@title"/>
          </a>
        </td>
        <td class="detail noLeftBorder">
          <a class="arrowSmallFront" href="{$vCountryURL}">
            <xsl:value-of select="key('kCityById',$current/city/@id)/../@name"/>
          </a>
        </td>
        <td class="detail noLeftBorder">
          <a class="arrowSmallFront" href="{$vRegionURL}">
            <xsl:value-of select="key('kCityById',$current/city/@id)/../../@name"/>
          </a>
        </td>
      </tr>
    </xsl:for-each>
  </xsl:template>
  <xsl:template name="reverse">
    <xsl:param name="string" select="''"/>
    <xsl:if test="$string != ''">
      <xsl:call-template name="reverse">
        <xsl:with-param name="string" select="substring($string,2)"/>
      </xsl:call-template>
      <xsl:value-of select="substring($string,1,1)"/>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

Now everything is working fine, however I want to implement sorting on the href link in above xslt.

 <tr>
  <th scope="col" class="first sortSelected">
    <div class="thPadding">              
      <xsl:element name="a">
        <xsl:attribute name="href"></xsl:attribute>                
        <xsl:attribute name="class">iconDownSortArrow</xsl:attribute>                
      </xsl:element>Destination
    </div>
  </th>
  <th scope="col" class="sortHover">
    <div class="thPadding">         
      <xsl:element name="a">
        <xsl:attribute name="href"></xsl:attribute>
        <xsl:attribute name="class">iconSortArrowOff</xsl:attribute>
      </xsl:element>Country
    </div>
  </th>
  <th scope="col" class="sortHover">
    <div class="thPadding">            
      <xsl:element name="a">
        <xsl:attribute name="href"></xsl:attribute>
        <xsl:attribute name="class">iconSortArrowOff</xsl:attribute>
      </xsl:element>Region
    </div>
  </th>
</tr>

1) Destinations.xml

<?xml version="1.0"?>
<list type="Destinations">
<resources location="include/xml/locations.xml">
<publication>481</publication>
</resources>
<destination id="594051" title="Sydney" url="/asiapacific/australia/sydney.aspx" >
<city id="192409" />
</destination>
<destination id="594088" title="Brisbane" url="/asiapacific/australia/brisbane.aspx" >
<city id="192397" />
</destination>
<destination id="594579" title="Dubai" url="/middleeast/uae/dubai.aspx" >
<city id="192855" />
</destination>
<destination id="594580" title="Abu Dhabi" url="/middleeast/uae/abudhabi.aspx" >
<city id="192851" />
</destination>
</list>

2) Locations.xml

<?xml version="1.0"?>
<list type="Locations">
<region id="192393" code="ASIA" name="Asia &amp; the Pacific" shortname="Asia &amp; the Pacific">
<country id="192395" code="AU" name="Australia" shortname="Australia">
<city id="192397" code="BNE" name="Brisbane" shortname="Brisbane">
<airport id="192399" code="BNE" name="Brisbane International Airport" shortname="Brisbane"></airport>
</city>
<city id="192409" code="SYD" name="Sydney" shortname="Sydney">
<airport id="192411" code="SYD" name="Kingsford Smith Airport" shortname="Sydney"></airport>
</city>
</country>
</region>
<region id="192847" code="MEAF" name="The Middle East &amp; Africa" shortname="The Middle East &amp; Africa">
<country id="192849" code="AE" name="United Arab Emirates" shortname="United Arab Emirates">
<city id="192851" code="AUH" name="Abu Dhabi" shortname="Abu Dhabi">
<airport id="192853" code="AUH" name="Abu Dhabi" shortname="Abu Dhabi"></airport>
</city>
<city id="192855" code="DXB" name="Dubai" shortname="Dubai">
<airport id="192857" code="DXB" name="Dubai International Airport" shortname="Dubai"></airport>
</city>
</country>
</region>
</list>

Please suggest!

Thanks.

A: 

Before each close tag </xsl:apply-templates> you need to include an <xsl:sort>, e.g.

      <xsl:when test="$region='' and $country=''">
        <xsl:apply-templates select="destination">
          <xsl:sort select="@href" />
        </xsl:apply-templates>          
      </xsl:when>

The above code assumes that @href is an attribute of the destination element, but that's just a guess, since you haven't told us where @href appears in the input. Unless I missed something.

If you need further help please post a sample of your input XML.

On second reading, I wonder if you mean that you want to sort based on which of the three a elements is clicked on? Please clarify, and edit your question to include a sample of your input XML.

OK, based on your comment it's clear that you want to sort based on whichever column the user clicked on last.

To expand on what Alejandro was saying, interactive behavior is outside the scope of XSLT. If you want XSLT to sort based on varying columns, you need to pass that column to the XSLT as an initial parameter. If the XSLT is running on the server, the whole page will reload when you change the sort order of the table. Do you want that?

For instant sorting you could call the XSLT within js on the client, but that's a bit hairy. Usually for interactive sorting, people just sort directly in javascript. Here are some tutorials and implementations:

LarsH
hi larsh thanks for your reply, I am having two xmls, I have updated the questions with it. Please suggest as above logic didn't worked for me!
MKS
And also I want sorting on the header section i.e. "Destination", "Country" and "Region", I mean when user clicks on "Destination" all the below list will be sorted according the destination List.
MKS
@Solution: any interactive behavior must be implement with javascript. There is no way with XSLT 1.0 to get the document URI for URL query extraction.
Alejandro
@Solution, I understand the question better now. You might want to put this comment about clicking on "Destination" into your original question. I'm now updating my answer.
LarsH