In our intranet we were setting up a product catalog. The documentation for the products are stored in 1 document library. This doclib has a (multivalued) lookup field to the products list. We wanted to create 1 page per product in the same publishing site. This page will the the landing page for a product. It will show general information and the available documentation. To do this we added a lookup field to the Pages library to the same product list and added the PageFieldFilter webpart to the page. Turns out this does not work for a lookup field (the same applies to a user/group field).
Here is how you recreate this (it also shows the reasons why it doesn’t work):
- Create a Publishing site
- Create a list “Products” and add some items
- Create a document library “Documentation” and add some documents
- Add a (multivalued) lookup field to the document library
- Select product(s) for the documentation:
- Add a (singlevalued) lookup field to the Pages library
- Add a new page and select one of your products:
- Add the “Documentation” library to the page and show the name and product fields.
- Add the Page Field Filter webpart to the page and select the “Product” field.
- Connect the filter webpart to the Documentation list.
- Check-in and notice that the list shows no documents:
This shows our problem; the value is not the title of the selected item, but it is the value that SharePoint uses internally to store the value. This applies to both Lookup and Person or Group fields.
The solution
The solution for this is to build our own custom Page Field Filter webpart. You can do this by creating a new webpart that inherits from the ContextFilterWebPart in the Microsoft.SharePoint.Portal.WebControls namespace. Below I describe the most important bits to include in your code. My webpart is called “WebpageFieldFilter”.
- Create a private member and a property of type Guid (called “PageFieldID”)
- Create a new EditorPart that renders a dropdown showing all field in the pages library. These fields can be added directly from the context:
Also implement the ApplyChanges and SyncChanges methods:SPContext.Current.List.Fields
public override bool ApplyChanges()
{
WebpageFieldFilter webpart = WebPartToEdit as WebpageFieldFilter;
webpart.PageFieldID = new Guid(_selectField.SelectedValue);
return true;
}
public override void SyncChanges()
{
EnsureChildControls();
WebpageFieldFilter webpart = WebPartToEdit as WebpageFieldFilter;
_selectField.SelectedValue = webpart.PageFieldID.ToString("B");
}
- Implement the IWebEditable interface on your webpart. Implement CreateEditorParts. This should return the new EditorPart we just created, but also the EditorParts that are generated by the base webpart, otherwise we won’t have our filter options:
.cf { font-family: Courier New; font-size: 9pt; color: black; background: white; } .cl { margin: 0px; } .cb1 { color: teal; } .cb2 { color: blue; }
EditorPartCollection IWebEditable.CreateEditorParts()
{
List<EditorPart> newEditors = new List<EditorPart>();
EditorPartCollection editors = base.CreateEditorParts();
foreach (EditorPart part in editors)
newEditors.Add(part);
newEditors.Add(new SelectListFieldEditor());
return new EditorPartCollection(newEditors);
}
- In the webpart class, override FilterConfigured and return true if our PageFieldID has a valid Guid value.
- In the webpart class, override DesignTimeHtml to return the correct text for your webpart in design mode.
- Override GetRawFilterValues to return the values for the field that was chosen by the user:
In GetFieldValues I implemented the code to extract the value for the lookup and user field and return a string array with the value or the values in case of a multi valued field. You can find the code to do this in the ZIP file (see attachments).protected override string[] GetRawFilterValues()
{
SPListItem listItem = SPContext.Current.ListItem;
if (listItem != null && PageField != null)
{
SPField field = SPContext.Current.List.Fields[PageFieldID];
return GetFieldValues(listItem[PageFieldID], field);
}
return null;
}
And when we look at the page, the documentation is now filtered as expected:
http://www.tonstegeman.com/Blog/Lists/Posts/Post.aspx?ID=29
Print this post
No comments:
Post a Comment