Understanding XPages Views
Over the last few days my understanding of views and an XPages display of content has become much clearer. I don’t think I’m the only one who has confused the boundaries between the various moving parts and not fully understood the granularity involved. But the objects all have a clear place and function, and when you break down what’s being specified where, it’s all very logical and sensible. At that point, expectations become more realistic. The three elements are the View design element, the dominoView datasource and whatever representative component is used to display the content – a Repeat Control, View Panel, Data View etc. So let’s step through the elements.
View Design Element
The starting point for anything is the View design element, both the class that manipulates it and the Note that allows you to open it in Domino Designer. The View object remains the same and its properties are not modified by an XPage that accesses the view. The first View Entry in the View accessible via database.getView().getFirstEntry() is always the same for a given user, regardless of any properties set on a dominoView datasource or component use to change the start point or sorting order. The entry returned will only be different for different users because of Reader access. Basically, the entries you see when you open the view in Domino Designer is what you access via the View object. Remember in the Notes Client you can re-sort or move columns around, so not that is not necessarily a valid check.
At this point it’s worth pointing out something I’ve come across recently that View Navigators and View Entry Collections can be different. View.createViewNav().getCount() will return the number of View Entries of all type visible in the view, whereas View.getAllEntries().getCount() will get the number of View Entries of type Document.
The dominoView component is an easy way to get access to all or a subset of entries from a view defined by the viewName property. It is best to think of it as a ViewEntryCollection rather than something analagous to the backend View class. The default will be a ViewEntryCollection equivalent to view.getAllEntries(). But that there are properties available to refine the view entries returned. keys and keysExactMatch allow you to only return a certain category, equivalent to the programmatic method getAllEntriesByKey(). search allows you to perform a search and get a restricted collection. startKeys will allow you to get a ViewEntryCollection starting from a certain point.
And here is the key. Once those properties have been defined, you have a subset of the view. The dominoView component does not have access to any other entries outside the ones returned by those properties. If you have a view of 500 entries and set first to 200, the dominoView only has 300 entries in it – the last 300. The 190th entry in the backend View does not exist as far as the dominoView is concerned. The first entry for the dominoView is entry 200 from the backend View. It does not know about the previous 199 and nor does anything that uses the dominoView.
It is equivalent to using the following code to define the value property of a Repeat Control:
ViewEntry ve = view.getNthEntry(200);
ViewNavigator nav = view.createViewNavFrom(ve);
View Panel, Repeat Control, Data View
So now we know what View Entries are available to the display component. The View Panel or Repeat Control or Data View allows some additional display settings: what content from each View Entry is displayed, which columns the user can sort on, the number of rows to display at a time, the first row to display. Again, any properties defined here merely affect what is displayed. They do not affect what is available in the dominoView or underlying View.
The one caveat here is sortable columns. The property to define the sortable column does not affect what is available in the dominoView. However, it provides a hook to programmatically change what is available in the dominoView by manipulating the sortColumn and sortOrder properties of the dominoView.
So where does the Pager fit into this? The pager is in many ways a bridge between the dominoView and the View Panel / Repeat Control / Data View (subsequently I’ll just refer to Data View). It does not connect in any way to the backend View, and that is very important to know. The total number of entries available to the pager are only those available to the dominoView. The first entry available to the pager is the first entry in the dominoView not the first entry in the View.
The number of pages and the current page is based on the rows property and first property of the Data View. Clicking the pager changes the first property of the Data View. Clicking on the options of a Pager Sizes control changes the rows property, which subsequently changes the selected entry on a pager.
Hopefully that clarifies a lot. The one aspect I’m still a little stuck on is that there is no way from a View Navigator to work out the row in the overall View that the ViewEntry corresponds to, taking into account Reader fields. ViewEntry.getPos() gives a hierarchical layout, e.g. 12.3.6. But it doesn’t identify that that corresponds to e.g. the 140th row for User X and the 120th for User Y.
However, as you can probably see from this exposition, that is completely immaterial for XPages. Because that can only tell the developer it’s the 120th entry if no filters are used. The entry point to check against is the dominoView, not the View.