Dynamically Selecting Nodeset Based on Form Variables
Hi,
I'm building a form to filter Customer nodes. I have three separate filters and I know how to get them to work independently but I', having gtrouble wrapping my mind around getting them to work together since I can't dynamically build a string to use in the for-each as the nodeset based on the form parameters. I have these three form controls:
The problem here is of course that not all of these form fields in the filter will be chosen/populated -- and I am selecting only those nodes which contain the selected value of ALL three filters , so I need a way of separating them. For example, if only $usecase and $product have a value, how NOT to include:
<xsl:template match="/">
<!-- Get all possible Customer nodes -->
<xsl:variable name="allCustomers" select="$currentPage/Customer[not(umbracoNaviHide = 1)]" />
<!-- Grab filter values -->
<xsl:variable name="usecase" select="umbraco.library:RequestQueryString('use-case')" />
<xsl:variable name="industry" select="umbraco.library:RequestQueryString('industry')" />
<xsl:variable name="product" select="umbraco.library:RequestQueryString('product')" />
<!-- Filter by use-case but let all through if the filter is empty -->
<xsl:variable name="usecasesNodes" select="$allCustomers[customerUseCases//nodeId = $usecase]" />
<xsl:variable name="industryNodes" select="$allCustomers[customerIndustries//nodeId = $industry]" />
<xsl:variable name="productNodes" select="$allCustomers[customerProducts//nodeId = $product]" />
<!-- Process them all - fallback to everything if no filters are specified -->
<xsl:apply-templates select="$usecasesNodes | $industryNodes | $productNodes | $allCustomers[concat($usecase, $industry, $product) = '']" />
</xsl:template>
<!-- Sample template for a Customer node -->
<xsl:template match="Customer">
<p>
<xsl:value-of select="@nodeName" />
</p>
</xsl:template>
Note, that no node can exist more than once in a nodeset, so when you join two nodesets (using the pipe character) you will never get any duplicates (awesome rule :-)
Another thing to notice - adding a [true()] or [false()] predicate to a selection, effectively works as an ON/OFF switch for the entire set, which is how I can just throw the $allNodes set into the mix, by adding a predicate which will resolve to true() only if all the filters are empty.
That said, I *will* mention that uComponents has a FilterNodes() extension, which lets you specify an XPath as a string (so you can build it dynamically).
As usual, I very much appreciate your time-- and your timeliness! This code isn't doing what I need it do, however.
I'll look into FilterNodes(); I do have uComponents.
Each of the filters here works fine independently (if I choose a Use Case and leave the other two filters empty I get the right data), but as soon as I mix two or more, I get the wrong data back (while leaving Use Case on Use Case 1 and then choose Product A, I get both nodes which have EITHER Use Case 1 OR Product A). Results are too generous. Seems to be doing an OR between the nodesets. I need only those nodes which have both -- any node which meets ALL criteria which are non-empty. What I need to do is to make the filter additive. In other words, each of the three filters must take the other two into consideration. Get me?
That's correct, this way of filtering will essentially work like OR operations.
Depending on your specific use case (no pun intended, or maybe a little :-), I think this is the case where I'd usually switch to a custom extension - there's only so much manipulation you should do in the View and this definitely starts to hit the wall, so to speak.
However, you can do something like this, to build the filter/query and then send it into the FilterNodes() extension:
This FilterNodes() method has, in less than 5 minutes, transformed my life and every future Umbraco project. I took a look at the uComponents documentation and this indeed is doing exactly what I needed to accomplish. I kept wanting a scripting language so that I could progressively build a filter string -- aaaand VOILA there it is.
I am very grateful for your help on this -- kind of speechless, actually. THANKS.
Dynamically Selecting Nodeset Based on Form Variables
Hi,
I'm building a form to filter Customer nodes. I have three separate filters and I know how to get them to work independently but I', having gtrouble wrapping my mind around getting them to work together since I can't dynamically build a string to use in the for-each as the nodeset based on the form parameters. I have these three form controls:
And then I compare these values to the ones stored in a field which utilizes an xPath CheckBoxList like so:
The problem here is of course that not all of these form fields in the filter will be chosen/populated -- and I am selecting only those nodes which contain the selected value of ALL three filters , so I need a way of separating them. For example, if only $usecase and $product have a value, how NOT to include:
[customerIndustries/XPathCheckBoxList/nodeId = $industry]
In the node selection? I'm missing a core concept here. How can I add this logic to the for-each? Only use this filter if it's not empty?
Thanks in advance,
Garrett
Hi Garrett,
Here's what I usually do:
That said, I *will* mention that uComponents has a FilterNodes() extension, which lets you specify an XPath as a string (so you can build it dynamically).
/Chriztian
Hi Chriztian--
As usual, I very much appreciate your time-- and your timeliness! This code isn't doing what I need it do, however.
I'll look into FilterNodes(); I do have uComponents.
Each of the filters here works fine independently (if I choose a Use Case and leave the other two filters empty I get the right data), but as soon as I mix two or more, I get the wrong data back (while leaving Use Case on Use Case 1 and then choose Product A, I get both nodes which have EITHER Use Case 1 OR Product A). Results are too generous. Seems to be doing an OR between the nodesets. I need only those nodes which have both -- any node which meets ALL criteria which are non-empty. What I need to do is to make the filter additive. In other words, each of the three filters must take the other two into consideration. Get me?
Thanks again,
Garrett
Hi Garrett,
That's correct, this way of filtering will essentially work like OR operations.
Depending on your specific use case (no pun intended, or maybe a little :-), I think this is the case where I'd usually switch to a custom extension - there's only so much manipulation you should do in the View and this definitely starts to hit the wall, so to speak.
However, you can do something like this, to build the filter/query and then send it into the FilterNodes() extension:
/Chriztian
CHRIZTIAN!
This FilterNodes() method has, in less than 5 minutes, transformed my life and every future Umbraco project. I took a look at the uComponents documentation and this indeed is doing exactly what I needed to accomplish. I kept wanting a scripting language so that I could progressively build a filter string -- aaaand VOILA there it is.
I am very grateful for your help on this -- kind of speechless, actually. THANKS.
//Garrett
is working on a reply...