Subscribe via FeedJeremy Hodge, Oct 4, 2009 12:42:45 PM
Over on Jake Howlett's Blog about Restricting View To Mutliple Categories With Flex I posted a comment on how to do the same thing in XPages. After I posted the "how to" I thought this was probably a good enough tip to post here versus getting lost in the comments out there, so here goes.
The idea is to be able to select multiple categories, then display the documents from those categories in the view. To accomplish this with XPages, I don't use the standard "categoryFilter" property that restricts a view to a single category. Problem with that is, its a SINGLE category.

What I use, is the seach parameter. This allows us to create a full text search query that will filter the view for us.
To accomplish, this, I add a List box to the XPage, that contains the list of category values. I then bind the listbox to a variable in the viewScope:

After binding the variable, I change the onchange event of the listbox to do a partial refresh on the appropriate region of my XPage:
(In this image, you can ignore the Execute Script action I have added, it serves a different purpose than this example)
Then to actually perform the filter, I added the following code to the 'search' property of the data, which is a Domino View defined at the XPage level.
try {
return "FIELD ProductKeywords CONTAINS " + viewScope.selectedTag.join(' OR ');
} catch (e) {
return "FIELD ProductKeywords CONTAINS " + viewScope.selectedTag
}
The try { } catch (e) { } block is an error handling block that attempts to execute the code in the try { } block, and if it generates an error, it executes the code in the catch { } block. The reason for this is if the user has selected a single field, the value of viewScope.selectedTag is just a simple variable, but if the user has selected multiple values, then viewScope is an array. So we first attempt to join selectedTag, treating it as an array. If it's not an array, an error is generated, and the catch block is executed, which treats selectedTag as a simple variable.
Here is where the search property is located:

The database must be full text indexed in order for this to work.
You can view a demo of this working on the test YellowBubble.org site.
Happy Coding...
Oh, and one more thing ... this works in 8.5 and 8.5.1 ...
11 responses to Restricting a View to Multiple Categories in XPages
Elijah Lapson, April 12, 2010 5:39 PM
Hi there attempting to recreate your example. Any hints on setting the default value or selected values in the Listbox?
Thanks,
Elijah
Jeremy Hodge, March 16, 2010 4:30 PM
Sean, You might want to look at this, you may get better performance with it:
<xp:repeat id="repeat1" rows="999" var="filteredDocs"
indexVar="filteredIndex">
<xp:this.value><![CDATA[#{
var masterCollection = cview.getAllEntries();
if (viewScope.filterSelection != null) {
var xem:NotesViewEntryCollection = masterCollection.cloneCollection();
if (viewScope.filterSelection != null) {
if (viewScope.filterSelection.constructor == Array) {
for (i=0;i<viewScope.filterSelection.length;i++) {
xem.subtract(cview.getAllEntriesByKey(viewScope.filterSelection[i], true))
}
} else {
xem.subtract(cview.getAllEntriesByKey(viewScope.filterSelection, true));
}
}
if (xem != null)
if (xem.getCount() > 0) {
var nve:NotesViewEntry = xem.getFirstEntry();
while (nve != null) {
if (masterCollection.contains(nve))
masterCollection.subtract(nve);
nve = xem.getNextEntry(nve);
}
}
}
return masterCollection;}]]></xp:this.value>
Sean Cull, March 16, 2010 4:17 PM
I had a go at this and it sometimes works well but I have been surprised by the delays in indexing that sometimes occur. You can force a re-index via SSJS but that seems like overkill.
Shame as this is one area where the likes of Flex really beats Xpages hands down.
Elijah Lapson, October 12, 2009 11:48 PM
This is great! Any chance of making a download available? Sometimes it is hard for me to wrap my head around where things need to go until I can play around with a working model.
Elijah
homeopathie, October 7, 2009 4:43 AM
Hello
You have given good method and it is very interesting.I will try this method.Thank you very much for sharing this demo with us.Keep doing good work.
Stephan H. Wissel, October 5, 2009 7:05 PM
@Tommy: nope. Fulltext Index is like the highlander: there only can be one. Speed differences get visible when you have a lot of reader fields.
Jeremy Hodge, October 4, 2009 4:01 PM
@stephen ... I put together a sample ... here's a database with 18,432 documents in the view ... the slowpart seems to be the inital load, coming in at around 20 - 30 seconds ... however after that, single category selection happens usually in well less than 500 ms round trip, and multiple category selection takes anywhere from 2 to 5 seconds round trip (note that I am on the same LAN as the server so it may take a bit longer across the inet) ..
BUT all that being said, this server is no barn burner either ... its a sub $1000 Server "Appliance" with a dual core E2160 processor and 2 GB ram running OpenSuSe 11.x ...
you can view the results yourself @ http://beta219er.yellowbubble.org/YellowBubble/yb-test.nsf/Providers-TagList.xsp
Mark Hughes, October 4, 2009 3:55 PM
I use this method allot and it is very fast, but i use something more like whats in the help file search example.
Tommy Valand, October 4, 2009 3:51 PM
@Stephan: Doesn't the view have it's own index used for FTSearch (pre-filtered according to view-selection)? If there are readers fields involved, it's another story, of course.
One thing lacking in this XPages version of category restriction is sorting the results.
Karsten Lehmann, October 4, 2009 3:32 PM
Interesting idea. Only one thing: Your demo produces an error if no category is selected in the list.
Stephan H. Wissel, October 4, 2009 2:39 PM
Interesting approach. I would be curious how that performs. When you run a FTQuery against a view Notes needs to execute the query (which is fast) and then compare every found document against the view selection formula (which will be freakingly slow when you have *a lot* of documents, not even talking about reader fields).