Thursday, October 25, 2007

Exposing a Connected Property on the Data View Web Part (DFWP) to pass in CAML Queries

The Data Form Web Part (called Data View in SharePoint Designer) is a very versatile web part. While offering an XSLT transform for layout purposes, there are various features such as sorting, filtering and paging. However, when it comes to content management, all of the configuration is in the page layout which requires interaction with SharePoint Designer. This makes it difficult for a content editor to configure things such as filtering from the browser.

You have a few options here:
  1. You can filter the web part by hand in the page layout (undesirable).
  2. You can build a custom web part (won't work if the project has to be out-of-the-box.
  3. You can add a CAML parameter to the Data View and allow the content editor to configure it!

Overview


Here's the concept. We're going to set up a Data Form Web Part within a page layout. We're going to point that at a specific list. We're going to add a parameter to the Data Form Web Part for use with connections and filtering. We're going to make two edits to the XML definition of the web part. Then we'll configure a Text Filter web part to allow the user to type in CAML. Finally we'll connect the two web parts up and watch the filtering work.

First Steps - SharePoint Designer

Let's open up SharePoint Designer and point it to our Microsoft Office SharePoint Server 2007 site. We will open up an existing page layout or new page layout. The first activity we will need to do is to create a web part zone. After that, click on the zone and go up to the Data View menu and click "Insert Data View..."
 
1
Then, in the right pane, under the "Data Source Library" tab, you'll see possible data sources. In this case, I'm going to choose a list I made. Since we are using CAML, this trick only really will work with SharePoint Lists and SharePoint Libraries. My list is called "My Custom List". After choosing my list, I will insert a multiple-row list INSIDE my web part zone. This is important as I will need the ability to create the connection between the filter and the web part.
 
2 
Once this is created, you'll want to open the "Common Data View Tasks" menu. This menu allows you to do filtering, grouping and paging. We're concerned most with simply adding Parameters.
 
3
In the Data View Parameters window, we need to create a "New Parameter." The name of this parameter is important. This parameter name will be used in making a connection between the filter and the data view. Additionally, it will be used within the XML in order to tailor the data source as we'll see momentarily. Make sure you choose "Control" as the source. You will ultimately be passing in the filter, but you don't want it tied to Query String or anything else.
4 Once we've added a new parameter, we can go back to "Source" view and see how SharePoint Designer has exposed our Parameter. In the image below, you can see that a new parameter was added to the node. Additionally, you can see that a parameter has been added to the stylesheet. Use the stylesheet parameter for debugging. You can expose the filter value to the web page by using an node.

5
Now, we need to add a "DataFormParameter" to the SelectParameters of the DataSources section of the SPDataSource. Yes, it sounds much more complicated than it is. Simply add a node configured as below.

6
 
Now that we have a "DataFormParameter", we can set up a new value for our select command within our SPDataSource. The original value below is simply <View></View>.
 
8 
All we have to do to pass in our CAML is to replace the with {CAML}. Once we've done this and saved it, we'll be done in designer. Save your Page Layout. It's time to go into the browser and create a page.
 
9
How it works
 
Basically what you're doing is adding a parameter to the web part. Therefore any connections will set that parameter. Then when you set up the you are mapping the web part parameter to something that can be available in the select command. The key here is the "ParameterKey" in the <WebPartPages:DataFormParameter> node. The key needs to map DIRECTLY to your ParameterBinding Name. If the key and the name don't match, the mapping will fail. Finally, the {CAML} that is used in the select command is simply shorthand for any of the using the name attribute. This allows the select command to receive any text connected through the CAML parameter.
Creating your filtered page
 
First, I'm going to use a Text Filter Web Part. This web part can only be found in MOSS and requires the Enterprise Site Collection features.
 
12
 
Create a page from your page layout. Once in edit mode, you'll want to "Add a Web Part" to your zone with the data form web part you configured. The web part you add is in the "Filters" group and is the Text Filter web part.
 
11
 
Once its configured it should look something like this:
 
13

You now need to configure your filter. Before you can enter text for your filter, you will need to give it a title. Once you've given it a title, then you will be allowed to enter text for the filter value.
 
15 
Once you have given it a title, you will be able to make connections. Click the "Edit" on the Data Form Web Part. THIS IS IMPORTANT, you want to make the connection from the DFWP the Filter. Therefore, you will click Connections -> Get Parameters From -> Filter: Filter (note, this name "Filter" is the name you used for your filter web part).

16
When you get the Provider/Consumer screen up, you'll want to pick CAML in the consumer and choose Finish. NOTE: If you don't see CAML here, your Data Form Web Part is not configured correctly.
 
17
We are going to create some CAML in order to only show 3 items. These items we'll filter by using the ID column on the list. I have taken a screen shot of the CAML with formatting. However, in order for this to work, you'll need to remove the formatting. Here's the CAML we will use:
 
14

Once the page is checked in, you'll see the filter and the list. As soon as you enter your CAML text into the filter text box and click away, the page should refresh and your filtering should work.
 
18

Things of Note
 
I used a Text Filter Web Part here. There are some drawbacks with the text filter. First, I don't believe you can hide the web part without an export/import. If you're using filters as configuration for content editors, you won't want to show the values or anything to the common visitor. Therefore, you'll want to hide it.
 
You might want to create a picker to look up values from a list to do precise filtering. I did this for a client and had great success with filtering using this method. This gives you the ability to filter down to individual items in an almost relational way.

Finally, here is a great link about dealing with Multiple OR and AND conditions in CAML. This article on the PluggedOut Development blog helped immensely on this.
 
Let me know if you have any questions!

6 comments:

Anonymous said...

It does not seem to work, it is strange that if you convert {CAML} in select command to any junk value the data form view still works and doesn't break, I thought it is caching issue but no luck with that as well....in the snapshot of yours it does not seem to be working either as I could see list items with other ids as well.

Anonymous said...

sorry my mistake, I do see in your snapshot data getting filtered. Please let me know what could be the reason that selectcommand is not working for me..

Isabel said...

Great post, except it didn't work for me. :(
Any tips on what to check?

Anonymous said...

Hi all, I havent tried this code directly, but have filtered the values changing the select query. You have to html encode the query as such:

& lt;View& gt;& lt;Query& gt;& lt;Eq& gt;& lt;FieldRef Name='Author' /& gt;& lt;Value Type='Integer'& gt;& lt;UserID Type='Integer' /& gt;& lt;/Value& gt;& lt;/Eq& gt;& lt;/Query& gt;& lt;/View& gt;

This filters for the author being the current logged on user. Maybe give this a go in the query place holder. remove the space in the qreater than html encoding, posting here would just display the chars.

decogzz said...

Thanks, worked for me, I did not used the text filter, I just got the parameters with a dll made by myself, I did a webpart with wspbuilder and implemented the class text filter, so I could create the CAML with server side code.

Anonymous said...

Anonymous, you don't have to HTML encode the query yourself, it automatically html encoded when the text filter sends the parameter value to the DVWP. Try it :).