Understanding XPages Views

  |   Blog   |   1 Comment

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.

dominoView Component

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.

AUTHOR - Paul Withers

Paul Withers is an IBM Lifetime Champion, has been an OpenNTF Board Member since 2013, has worked with Domino since R4.5, XPages since 2009, co-authored XPages Extension Library and was technical editor for Mastering XPages 2nd Edition. He is one of the developers on OpenNTF Domino API as well as contributor to a variety of other OpenNTF projects. For full bio, see

  • Jesse Gallagher | May 9, 2014 at 2:21 pm

    I’ve found it helpful to reorient my conceptual model of what a Domino view is. It consists of three main components:

    1) The selection and column definitions (the “map” part of map/reduce).
    2) Some incidental visual-design information used for legacy clients (and dynamicViewPanel’s customizers).
    3) One or more indexes (one default, plus one per user-sortable column+direction combo), containing what can be thought of as a List of Maps representing documents, categories, and totals (a poor man’s “reduce”). These are visible as the $Collation and $Collation(N) fields in the view design note

    The dominoView data source lets you connect to the third: you pick an index/collation (sortColumn+sortOrder) and then filter it in some way (categoryFilter, keys, startKey, search, and so forth). All of these parameters have the result of providing a potentially-different List of Maps to whatever control uses it.

    Any of the other controls – viewPanel, dataTable, dataView, repeat – float entirely above all of this. They ask for one thing: a collection of stuff to iterate over, and in the case of viewPanel and dataView, that stuff should also be ViewRowData. However, they have no concern for HOW that data got there – so if you got your List of Maps by using dominoView, by writing your own model framework with the same sort of output (as I do), or by just hard-coding constructed objects directly on the page, the result is the same. The display controls can find out how many rows they’re iterating over and pick individual ones, but the way the data got there is lost to it.

    Pagers connect to the data controls and tell them to shift their slice of the conceptual List around.

Post A Comment