Getting the most out of the XPages View Panel Control – Part 2: Adding a dynamic ‘Jump To’ feature
In part 1 of this series, I showed how you can pass client-side JavaScript through a view column in a standard View Panel control. In this post, I’ll demonstrate is how to provide “jump to” capability in a view, with a dynamically-built list of options.
The startKeys property
If you’ve used the view panel, you may be aware that it has a startKeys property. To locate it, select the view panel, click on the All Properties subtab, and you’ll find it under data > data > startKeys.
Enabling the user to jump to a selected starting value
In the screen shot above, I hard-coded it to the letter ‘C’. When I load my view, it will start with the first value that begins with that letter.
Of course, we need to make this dynamic so the user can update the view as needed. The simplest way to do so is to set the startKeys property to the value of a scope variable and then add a drop-down list that is bound to that scope variable.
To set the startKeys property to the value of a scope variable, click on the blue diamond in the startKeys property and add this server-side JavaScript statement:
return viewScope.get('viewStart');
Next, create a combobox above the view panel and give it a few hard-coded values, such as A, B, C, and D. The key is to click on the Data tab for the combo box and set the data binding to the same scope variable that startKeys property will return.
Finally, update the onchange event of the combo box to trigger a partial refresh on the view panel.
So, when the user selects a letter to jump to, the selected letter is stored in a scope variable. The view panel is refreshed and it looks to that scope variable to determine where to start the display of the view.
Populating the list of Jump To options dynamically
This is all well and good, but let’s take it a step further. You can provide all of the choices in the alphabet by manually populating the drop-down list. However, if your data doesn’t have all of the options, this may provide unexpected results. For example, if the user selects X, but there aren’t any rows in the view that start with X, the view will start at the beginning.
To eliminate potential confusion, we can dynamically populate the list with only valid options, based on our view data.
To do so, we can run a script that builds a list of valid options and stores it in a scope variable, then update our Jump To combobox to get its list of options from that scope variable.
Execute the below code on the beforeRenderResponse event of the XPage or custom control that contains the view. This allows the code to have access to the view, but still execute before the page is displayed to the user. (It will fail on the getComponent() statement if run on the beforePageLoad event, because the view isn’t yet available at that point.)
var viewName = getComponent('viewPanel1').getData().getViewName(); var vw = database.getView(viewName); var colNum = 1; var cols:Vector = vw.getColumns(); for (var i=0; i < cols.length; i++) { if (cols[i].isSorted() && !cols[i].isHidden()) { colNum = i + 1; break; } } var letters = @DbColumn(null, viewName, colNum); var options = @Trim(@Unique(@UpperCase(@Left(letters, 1)))) viewScope.put('jumpToOptions', options);
Line 1 gets the name of the view that is the source of the view panel’s data. It is important to note that the data source must be defined within the view panel in order for getData() to work.
Line 2 gets a handle to the back end view. This can be enhanced if the source view exists in a separate database
Lines 3-10 look for the first visible, sorted column in the view. If the view doesn’t have any hidden columns, it would work to assume the first column is the key column, but this code is more dynamic so it can be reused across more views.
Lines 11-12 get a list of unique options, based on the data in the first column of the view.
Line 13 stores that list of options in a scope variable.
The last step is to set the combo box’s value to this computed formula:
return viewScope.get('jumpToOptions');
The result is that the Jump To list only includes valid options in the view.
Caveats
Be aware that once a starting value is selected, the user will not be able to page backward to see any data in the view before that point. A good way to work around this is to include a blank option at the top of the Jump To list, which will reset the view to start at the beginning.
Of course, performance is also a concern. There may be a noticeable lag when this logic is used on a large data sets or a view with documents including Readers fields. The performance could be improved by caching the values in a sessionScope variable or by running a background agent that stores the list of available options on a configuration document and updates it periodically throughout the day.
Alternatives
Have you implemented similar functionality in a different way? Let me know — I’d love to hear about it.
Up Next
In the next post in this series, I’ll show how to implement field-specific full-text searching across a view.
This is a great series. I’m really looking forward to your next, as the field-specific search is exactly what I’m needing for a project. See you at LotusSphere, and I’ll buy you a beer.
Cheers,
Brian
Thank you, Brian! Unfortunately, I won’t be making it to the conference this year, but maybe next time around.
Nice series Brad! Enjoying it…
Thanks, John — I appreciate it. I remember reading your blog heavily when I started learning XPages!
Great detailed walk through !!! Very nice functionality to add to app navigation !!!
Thanks, Paul! I’m sure you noticed that my code snippets start with ‘return’ and end with semicolons for optimum compiler efficiency. 😉
Nice post! Just like to give a plug for the custom control I created on openntf http://www.openntf.org/Internal/home.nsf/project.xsp?databaseName=CN=NotesOSS2/O=NotesOSS!!Projects%5Cpmt.nsf&documentId=CDCE10DE5BAE3E41862578DB005CF636&action=openDocument