Copied to clipboard

#### Flag this post as spam?

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

• Lee 1123 posts 3059 karma points
Jan 13, 2010 @ 17:29
1

## Dynamic / Conditional Sorting?

If I do ever get my head round why we use this XSLT I'll buy everyone a beer... But as I can't I'm sorry no Beers for now!

Yet again (Can you sense my frustration) something that should be simple, is insanely complicated with XSLT... How on earth do you get round conditional sorting?  Say based on QueryString value..

For example, I want the users to be able to choose how to sort some data either via date or via a nodename or another property - The value is then posted as a QueryString.

I have tried <choose> using a $variable but still it doesn't work?? Choose says invalid XSLT and if I stuff it in a variable it just doesn't work!? Please can someone put me out of my misery and show me how you get round conditional sorting? :( • Chris Houston 533 posts 978 karma points Jan 13, 2010 @ 17:49 0 Hi Lee, Have a look at this post here: Which should help you. Cheers, Chris • Chriztian Steinmeier 2731 posts 8338 karma points Jan 13, 2010 @ 20:31 0 Hi Lee, The problem is (as you may or may not have found out) that it's not allowed to use a variable or parameter in the select attribute of a sort instruction, so the way to get around it is to use a choose statement and test for all the possible values: <?xml version="1.0" encoding="utf-8" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:umbraco.library="urn:umbraco.library" exclude-result-prefixes="umbraco.library" > <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" /> <xsl:param name="currentPage" /> <xsl:variable name="sortby" select="umbraco.library:RequestQueryString('sortby')" /> <xsl:variable name="nodes" select="$currentPage/node" />

<xsl:template match="/">

<xsl:choose>

<!-- Sort by name? -->
<xsl:when test="$sortby = 'name'"> <xsl:apply-templates select="$nodes">
<xsl:sort select="@nodeName" data-type="text" order="ascending" />
</xsl:apply-templates>
</xsl:when>

<!-- Sort by id? -->
<xsl:when test="$sortby = 'id'"> <xsl:apply-templates select="$nodes">
<xsl:sort select="@id" data-type="number" order="ascending" />
</xsl:apply-templates>
</xsl:when>

<!-- More ways to sort... -->

<!-- Just take the Umbraco Content order then... -->
<xsl:otherwise>
<xsl:apply-templates select="$nodes" /> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- Template for how a single node should be output --> <xsl:template match="node"> <p> Name: <xsl:value-of select="@nodeName" />, Id: <xsl:value-of select="@id" /> </p> </xsl:template> <!-- No output for hidden nodes --> <xsl:template match="node[data[@alias = 'umbracoNaviHide'] = 1]" /> </xsl:stylesheet>  /Chriztian PS: I hope you get to like XSLT some day, 'coz I loooove beer :-) • Lee 1123 posts 3059 karma points Jan 13, 2010 @ 21:11 0 Thanks for the help chaps, very, very appreciated :) @ Chris - I actually found that page, but couldn't quite get my head round the Xpath in the sort select=""? I understand what she is saying and tried this  <xsl:sort select="./data [@alias = 'distance']" data-type="number" /> <xsl:sort select="./data [@alias='eventDate'][$resultsort = 'date']" data-type="text" order="ascending" />

But it didn't do anything :S   Do I just add the condition after the XPath?  And is this right?  I want to sort on this

./data [@alias='eventDate']

So added the following condition afterwards, which based on that ladies code should say if the variable $resultsort is equal to 'date' then apply the sort? [$resultsort = 'date']

Which gives me

./data [@alias='eventDate'][$resultsort = 'date'] @ Chriztian - Thanks for the code, I'll have a good look at it in a minute and see if I can use it if I can't get the XSLt working based on the link Chris gave. The problem I have is the XSLT is quite complex already and I'm worried about adding all that extra code :( But if thats the only way to do it, then so be it ;) If it works, yet another person I'll owe beer too :) • Lee 1123 posts 3059 karma points Jan 13, 2010 @ 21:40 1 # IT'S ALIVE I TELL YA, ALLLIIIIIIIIIVVEEEE Thanks for the help again everyone, I used idea from the link Chris put up and think I have it working now Pretty fiddly, will double check in the morning when I have had a break from this screen...lol Thanks again :) • Chriztian Steinmeier 2731 posts 8338 karma points Jan 13, 2010 @ 21:54 1 Yeah - I had a "Weee" moment too - the template with the choose an' all in my example can actually be written llike this, using Jeni's trick from the link above:  <xsl:template match="/"> <xsl:apply-templates select="$nodes">
<xsl:sort select="@nodeName[$sortby = 'name']" data-type="text" order="ascending" /> <xsl:sort select="@id[$sortby = 'id']" data-type="number" order="ascending" />
</xsl:apply-templates>

</xsl:template>


/Chriztian

• Lee 1123 posts 3059 karma points
Jan 14, 2010 @ 07:29
1

Hey Chriztian, thats 99% the same way I have done it on the page - But my sorts are for a number or by a date and the date is a DocType property

<xsl:for-each select="$searchResults"> <xsl:sort select="umbraco.library:FormatDateTime(./data [@alias = 'eventDate'] [string($resultsort) = 'date'], 'yyyyMMdd')" order="ascending" />
<xsl:sort select="./data [@alias = 'distance'] [string($resultsort) = 'distance']" data-type="number" /> ..... ..... </xsl:for-each> Hope this thread helps someone else • kentiler 76 posts 69 karma points Feb 15, 2010 @ 18:26 0 I'm having a tough time with this. I have a property named sortOrder which is a numeric type. When I put this inside my for-each loop, <xsl:sort select="./data [@alias = 'sortOrder'] [string($resultsort) = 'sortOder']" data-type="number" />

But when I put this line in, I get this error:

Error occured

System.Xml.Xsl.XslLoadException: The variable or parameter 'resultsort' is either not defined or it is out of scope. An error occurred at D:\www\beta.bayarts.net\html\xslt\634018299623240000_temp.xslt(25,3).
at System.Xml.Xsl.XslCompiledTransform.LoadInternal(Object stylesheet, XsltSettings settings, XmlResolver stylesheetResolver)
at umbraco.presentation.webservices.codeEditorSave.SaveXslt(String fileName, String oldName, String fileContents, Boolean ignoreDebugging)

Any ideas?  I thought ResultSort is a variable created by the sort.

Thanks!

--Kent

• Nik Wahlberg 639 posts 1237 karma points
Feb 15, 2010 @ 18:42
0

Hi Kent, can you post your entire XSLT here? resultsort would need to be defined in the your XSLT manually. With the rest of your file, I should be able to help out.

Off the bat, if you are simply tring to sort by that property it should look like this:

<xsl:sort select="data [@alias = 'sortOrder']" data-type="number" />

Thanks,
Nik

• organic 108 posts 157 karma points
Dec 16, 2011 @ 19:46
0

I'm trying to do the same task, sort based on a column if that coumn is specifed in the Url as the 'sort' querystring, but it's not working. The basic sort on 'lastName' works if I remove:

[string($sortby)='lastName'] Any ideas? ...<xsl:variable name="sortby"select="umbraco.library:RequestQueryString('sort')"/><xsl:template match="/"><!--The fun starts here --><table border="1" cellspacing="0" cellpadding="2"><tr class="gridHeader"> <td><b><a href="?sort=number">#</a></b></td> <td><b><a href="?sort=lastName">Player</a></b></td> <td><b><a href="?sort=position">Position</a></b></td>...</tr><xsl:for-each select="$currentPage/node [string(data [@alias='hide'])!='1']"><xsl:sort select="data [@alias='lastName'][string(\$sortby)='lastName']" data-type="text" order="ascending" />...