<xsl:for-each select="$sectionNode[($dirtype=businessType) and ($dirlocation=businessArea)]">
BUT -
I need to change the select so that it basically states that if the keyword field 'dirkeywords' is blank, filter results on dirtype and dirlocation as it is above. Else filter results based on dirkeywords only.
<xsl:for-each select="$sectionNode[
($dirtype = businessType)
and ($dirlocation = businessArea)
and (not(normalize-space($dirkeywords)))]
|
$sectionNode[(businessKeywords = $dirkeywords) and normalize-space($dirkeywords)]">
<!-- Do something -->
</xsl:for-each>
The normalize-space() function returns false() for empty or whitespace-only strings,
and the pipe (|) is a join operator - so you're joining two nodesets, but in effect you'll
only ever get one of them, since they're mutually exclusive (one of them requires
$dirkeywords to be empty, the other requires it to not be empty).
Yes that should work just fine - as long as you know there's no special characters going to appear in the keywords, and that the $dirkeywords variable is always uppercase.
Otherwise, you could use the uppercase() extension in the Exslt.ExsltStrings class to get the "correct" (even taking .NET culture into account) uppercase versions of the strings...
The keyword field could be either upper or lowercase. Also, I can't be certain that the comma separated keywords that the content managers add would all be lowercase. They might add them like:
design,develop,web Design,Develop,WEB
etc...
The xslt would need to pull back results regardless of the case.
I figured by using (businessKeywords, $uc, $lc) that results would write to screen regardless of case but i've just tested it and it doesnt work if the case doesnt match.
OK? So the last predicate will be false() if there was a value in the query string and subsequently, that nodeset will be empty; otherwise, if a query string value was not submitted, the predicate will be true() and thus, all the nodes returned. Effectively, we're combining two mutually exclusive sets, resulting in either the filtered set, or the complete set.
Help with XSLT search results filtering
Hi,
I have a search form and results page that all work great but I would like to select results based on EITHER the 2 search form fields or keywords.
I have this code that works great:
<xsl:variable name="dirtype" select="umbraco.library:RequestForm('dirtype')"/>
<xsl:variable name="dirlocation" select="umbraco.library:RequestForm('dirlocation')"/>
<xsl:variable name="dirkeywords" select="umbraco.library:RequestForm('dirkeywords')"/>
<xsl:for-each select="$sectionNode[($dirtype=businessType) and ($dirlocation=businessArea)]">
BUT -
I need to change the select so that it basically states that if the keyword field 'dirkeywords' is blank, filter results on dirtype and dirlocation as it is above. Else filter results based on dirkeywords only.
Can anyone help with this please?
Thanks!
Hi Roger,
You should be able to do something like this:
The
normalize-space()
function returnsfalse()
for empty or whitespace-only strings, and the pipe (|) is a join operator - so you're joining two nodesets, but in effect you'll only ever get one of them, since they're mutually exclusive (one of them requires$dirkeywords
to be empty, the other requires it to not be empty)./Chriztian
Hi Chriztian,
Can I also use 'contains' instead of = here?
Hi Chriztian,
I've combined your solution with 'contains' and also used uppercase and lowercase variables:
<xsl:variable name="lc">abcdefghijklmnopqrstuvwxyz</xsl:variable>
<xsl:variable name="uc">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable>
<xsl:for-each select="$sectionNode[($dirtype = businessType) and ($dirlocation = businessArea) and (not(normalize-space($dirkeywords)))] | $sectionNode[contains(translate(businessKeywords, $uc, $lc), $dirkeywords) and normalize-space($dirkeywords)]">
This seems to work fine. Unless you know of a better way of doing it?
Thanks
Roger
Hey Roger,
I was too slow :-)
Yes that should work just fine - as long as you know there's no special characters going to appear in the keywords, and that the
$dirkeywords
variable is always uppercase.Otherwise, you could use the
uppercase()
extension in the Exslt.ExsltStrings class to get the "correct" (even taking .NET culture into account) uppercase versions of the strings.../Chriztian
Hi Chriztian,
The keyword field could be either upper or lowercase. Also, I can't be certain that the comma separated keywords that the content managers add would all be lowercase. They might add them like:
design,develop,web
Design,Develop,WEB
etc...
The xslt would need to pull back results regardless of the case.
I figured by using (businessKeywords, $uc, $lc) that results would write to screen regardless of case but i've just tested it and it doesnt work if the case doesnt match.
Thanks
Roger
Hi Chriztian,
I've also just tried:
$sectionNode[contains(businessKeywords, $dirkeywords) and normalize-space($dirkeywords)]"
This also requires the case to be correct and fails if I use uppercase or capital first letter.
It really needs to pull back results on any case variation
thanks
Roger
Hi Roger - that's a very common problem - and you just need to compare the two in the same case, e.g. all lower or upper case.
Perform the case-change where you initially grab the variable(s):
And compare using the uppercase version:
/Chriztian
Hi Chriztian,
That makes perfect sense and it works great!
Many thanks for all the help as usual!
Roger
Hi Chriztian,
Just another one on search results please...
I have a page that displays results based on a filter 'ftype' this is a simple dropdown with a button.
<xsl:variable name="sectionNode" select="$currentPage/ancestor-or-self::*/Facilities/Facility"/>
<xsl:variable name="ftype" select="umbraco.library:RequestForm('filter')"/>
<xsl:for-each select="$sectionNode [($ftype=facilityType)]">
the filter works fine but when a user first hits the page, I need to show them all records and the for-each to ignore [($ftype=facilityType)]
What would i use to just show the values of $sectionNode?
Thanks!
Hi Roger,
There's a trick to do that - to understand how it works, you may need a little info on sets, though...
Let's select a set of all the Textpage children of the current page, like this:
Now we can filter that set of nodes by adding one or more predicates, e.g. let's filter the hidden pages out:
So the predicate needs to evaluate to either
true()
orfalse()
, right?Well, if you simply say
[false()]
you will get no nodes and likewise, if you supply[true()]
you will get all nodes.That was the first part - the second part is that any node can exist only once in a nodeset, so if you do this:
You will only get a set consisting of all the nodes in the $nodes variable - you won't get any duplicates!
So the trick is do this:
OK? So the last predicate will be
false()
if there was a value in the query string and subsequently, that nodeset will be empty; otherwise, if a query string value was not submitted, the predicate will betrue()
and thus, all the nodes returned. Effectively, we're combining two mutually exclusive sets, resulting in either the filtered set, or the complete set.Phew - hope that explains it :-)
/Chriztian
Thanks Chriztian, makes perfect sense!
is working on a reply...