Using SharePoint Willingly: Filtering Using Multiple Field Lookup Lists. Reply

misc2There are many times we have a list of ids and fields that we want to filter.For example, we may have a list of documents we want to filter on. Listing ALL the items in the document is easy, using built in SharePoint Designer functionality.

This can be done using:

<xsl:template name="dvt_1.body">
...
  <xsl:for-each>
 <xsl:call-template name="dvt_1.rowview" />
 </xsl:for-each>
 ...
</xsl:template>

But what if you want to filter this list?

A list lookup field, which allows multiple fields, may define the items to filter on.

It may take the form of ID and value:

 '10;#Title of 10;#20;#Title of  20;#30;#Title of  30'

How can we filter on these values?

  • One approach is to filter the list, and then go through each item based on this filtered list. This could be done by parsing this string, and iterating through each item.  In our case this would be: 10,20,30,

There are probably many techniques of doing this.  A few come to mind:

  • Creating a custom web part could handle this, but it may be overkill.
  • Creating a custom Xsl template could be created that would basically act like a recursive function that strips off one item at a time. (This will be covered in a later post).
  • Another approach way would be to turn the question around.  In this case, the entire list is iterated through, and then each item in the list is compared to see if it in the filtered field.

Rather than filter the list and then go through each item,  we will go through each item in the list and see it in in our filtered field.

This is a very simple solution in terms of it having very few additional lines added to the code.

This can be done using:

<xsl:template name="dvt_1.body">

...
<xsl:for-each>
   <xsl:if test="contains(concat('#',$DocumentList), concat('#', @ID, ';#'))">
 <xsl:call-template name="dvt_1.rowview" />
</xsl:if>

</xsl:for-each>
 ...
</xsl:template>

What this does:

Assume:

$DocumentList contains the filtered field.  In our case it is:  ’10;#Title of 10;#20;#Title of  20;#30;#Title of  30′

The list has these @ID:  5,10,15,20,25,30,35,40,45,50

Lets break down the logic:

The ‘for-each‘ will iterative through all the rows, one at a time, with @ID equal to each of the following ‘5,10,15,20,25,30,35,40,45,50’

concat('#',$DocumentList)

will add a ‘#’ to the front of the list.  So now it contains: ‘#10;#Title of 10;#20;#Title of  20;#30;#Title of  30’

concat('#', @ID, ';#')

will take each @ID and add ‘#’ to the front, and ‘;#’ to the back.  During the iterations, it will look like:

#5;#,#10#,#15#,#20#,#25#,#30#,#35#,#40#,#45#,#50
contains(concat('#',$DocumentList), concat('#', @ID, ';#'))

here we are just checking to see if each one of these items are in the filtered field:

Is '#5;#' in '10;#Title of 10;#20;#Title of  20;#30;#Title of  30'
Is '#10;#' in '10;#Title of 10;#20;#Title of  20;#30;#Title of  30'
...
Is '#50;#' in '10;#Title of 10;#20;#Title of  20;#30;#Title of  30'

Refinement:

This works fine, however the only issue is that the ‘position()’ value would not be what you would expect.  It would be the position in the original list.

One further refinement handles that by putting the check in the ‘for-each’ section.

This can be done using:

<xsl:template name="dvt_1.body">
...
 <xsl:for-each>
 <xsl:for-each select=""$Rows[contains(concat('#',$DocumentList), concat('#', @ID, ';#'))]"">
 <xsl:call-template name=""dvt_1.rowview"" />
</xsl:for-each>
</xsl:for-each>
...
</xsl:template>

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s