You’re no doubt used to seeing URLs to open a document that look like this:
http://www.server.com/db.nsf/myPage.xsp?action=openDocument&documentId=0123456789ABCDEF0123456789ABCDEF in XPages. The
action URL parameters are used by each document data source by default. In this post, I’ll show how you can use the
requestParamPrefix property to define a separate set of URL parameters for an additional data source.
By default, a document data source will use the
action parameters to determine the document to open and the edit mode. However, if you have more than one document data source on a page, this may not be the behavior that you want.
For example, I have a database with a simple XPage that has two document data sources for the Person form.
<xp:dominoDocument var="document1" formName="Person" action="openDocument"> </xp:dominoDocument> <xp:dominoDocument var="document2" formName="Person" action="openDocument"> </xp:dominoDocument>
If I open the page with a standard URL, both display the same document.
If I change the
action parameter to
editDocument, then both change to edit mode. Sounds like a great way to generate a save conflict!
Of course, this isn’t really what I want. One option to work around this is to set the
ignoreRequestParams property of the document data source to
true and compute the
documentId property (and, optionally, the
This is the method that I am in the habit of using and it works well when putting the ID in a scope variable and using that for the computed property value.
ignoreReuqestParams property tells the data source to ignore the
action properties in the URL and leaves it up to you to manage them.
(Note: Even if you compute the
documentId, it will not matter if you don’t set
ignoreRequestParams to true; the URL parameters will still override the property value.)
However, there is another way to handle this situation without computing the data source properties — the
You can set this on a data source and it will look for a separate copy of the
action parameters and use them for that specific data source.
For example, if I set the
doc2_, then it will look for URL parameters named
doc2_action and use those for this data source.
You can add the parameter directly in the page source or find it in the properties panel under All Properties > data > data > [data source]. (This assumes the data source is at the page level. If it’s on a panel, then that would be your starting point to find the data source properties.)
Now, I can open two different documents on the same page with a URL like this:
With this approach, you do not need to set
true. In fact, if you do, then the URL parameters will be ignored — even if they contain the specified prefix.
xp:button. In this post, I’ll document both the order of execution and which ones execute for each refreshMode option.
The easiest way is the “Client” event tab. Use the script editor to add code.
There are also 3 callbacks on the event handler (
xp:eventHandler tag, and then find them in
All Properties under the
Here’s an example:
view.postScript('alert("server event - view.postScript");');
Here’s an example of a button that makes use of all 5 options.
xp:this.script is the client-side event.
xp:this.action is the SSJS event code with the
onStart are part of the
Order of Execution
The callbacks that run very based on the
refreshMode property of the event.
If the page is fully refreshed, then none of the event handler callbacks are triggered. If the event is set to No Update or No Submission, then
view.postScript will not run.
Here is the order of execution for each event and callback (with the exception of
onError, because it would break the flow) that runs, based on the refreshMode:
- Full Refresh — client event, view.postScript
- Partial — client event, onstart, view.postscript, oncomplete
- No Update — client event, onstart, oncomplete
- No Submission — client event
The only way they all run is with a partial refresh.
Generated Code in the Browser
Here’s what gets generated and passed to the browser for our sample button (when set to partial refresh). The client-event code is defined in its own function. In the XSP.attachPartial() call, the client side event handler function and the callback functions are all passed (along with the button ID, refresh target ID, etc)
Of particular interest to me is the distinction between the
I like the concept of the
onStart callback, because your code can be consistent if you’re also running code
onComplete, however, the client-side JS event is easier to get to and it also has the ability to return false and cancel execution of the server-side event. (The
onStart callback throws an error if you try to return false, because it’s not a function.)
If you have any other insight into the differences or a benefit to using the onStart callback of the event handler, I’d love to hear it.
If you’ve used custom properties, then you’re aware that the
compositeData object provides access to those properties within the custom control. However, you can also access those properties from outside of the custom control. In this post, I’ll show how.
Accessing a Custom Property from Within a Custom Control
Let’s start with a custom control named
myCC that has a custom property named
myProperty. Here’s what it looks like to include it on an XPage and pass in a value of myValue:
On the custom control, you can refer to that value as
compositeData.myProperty. Here’s an example of a computed field that displays the property value.
Accessing a Custom Property from Outside of a Custom Control
If you have a need to access the a value passed to a custom property of a custom control from outside if the custom control, there are two steps to take:
- Add an id to the custom control instance on the page (so you can refer to it)
- Get the custom control component, retrieve a map of its property values, and then access the property that you need
Here’s an updated example of the custom control implementation on the XPage, with an id attribute added.
<xc:myCC myProperty="myValue" id="ccID"></xc:myCC>
Here’s how to refer to the custom property from the XPage:
This concept will work fine with multiple instances of the same custom control within a page because each instance would be required to have its own unique ID.
A Use Case
Here’s an example where I’ve recently found this useful. I have an application where I have a flexible grid custom control that takes a parameter with the URL for a REST service to supply the data. When I execute a search, I don’t want to reload the entire page — I just want to call the REST service to get the updated results and apply them to the grid.
But the search field exists as part of the application layout, so it’s outside of the grid custom control. Since the grid control is used for several types of grids, the REST service will vary, so I need to read a custom property of the custom control from another place on the page. This allows the Search feature to be reusable like the custom control.
The second part of a 2-part series on localization that Kathy Brown and I co-wrote has been published in The VIEW journal (subscription required). Part 1 showed how to get started with XPages Localization and part 2 shows how to extend XPages localization to handle things that the built-in localization functionality does not handle.
The enterprise is global; business doesn’t only happen in your native language. It is not practical to expect everyone to speak the same language to use your applications.
The first article in this series showed how to enable localization and use the built-in features of XPages to set up translations for all hard-coded values. Part 1 demonstrated a few features that browsers handle for you automatically and explained how to enable and use the built-in features of XPages.
When you started developing in XPages, you likely saw the blue diamond next to virtually every property to compute it. Unfortunately, built-in localization features do not handle those computed values. This article shows how to enhance localization and provides additional tips and tricks for localization support.
Due to David Leedy’s generosity, I now have a simple demo application set up at demo.xcellerant.net. Currently, there are samples of several Dojo widgets about which I’ve recently blogged and I will add to it over time.
Each page has a sample that corresponds with one blog post, along with a button to link to the blog post in order to learn more about it and get the code.
Dojo in XPages Series
I recently completed reading Mastering XPages, Second Edition. I read the previous edition cover to cover and did the same for this edition — it reinforced my understanding of a many topics, corrected my understanding of a few topics and opened my eyes to some features I had not yet tried. In short, this extremely thorough reference covers everything from <a> links to z-index; it is a worthy successor to the original book and a valuable addition to any Notes developer’s library.
I love giant tech books, so this 1000+ page tome makes me hearken back to the days of plowing through several large volumes (in addition to the yellow books!) to learn everything I could about earlier versions of Notes and Domino. In recent years, lots of great information has been disseminated in smaller chunks via blogs and articles, but XPages as a platform is so broad that there is absolutely a place for such an in-depth authoritative reference.
Mastering XPages starts at the beginning, dipping its toes in the water with the history and foundation of XPages. It progressively builds from explaining the basics the Notes schema and JSF through to simple actions and programming, then wading into deeper waters of partial refreshes and mixing client- and server-side code, before diving into the deep end of advance performance tuning.
Even though XPages has only been around for 5 years, it was interesting to review the history and gain a renewed sense of appreciation of how far the platform has come in just a few years. (Remember the days of creating, saving, then cleaning up temporary documents just to exchange information with LotusScript agents?)
Why Read the Second Edition if You’ve already Read the First Edition?
Even if you’ve read the first edition, it is worthwhile to read the second edition, for several reasons:
- It is updated for Notes 8.5.3 and 9.x, with numerous tips and descriptions of new and updated properties and features, including the Extension Library that is now built into core Notes. (Examples include Data Views and mobile development design patterns and enhancements, including the new DeviceBean and touch-based events.)
- It contains several new chapters (and additional information in existing chapters), including mobile controls and tons of great information about performance and scalability.
- If you’ve been working with XPages for awhile since you read the first edition, you’ll find that your additional experience provides a stronger foundation to get more out of the book. Several years after reading the first book, I can much more easily grasp the more complicated topics.
Even though it’s a massive book, the writing style is fairly colloquial, making it easier to read than you might expect.
There’s a reminder not to execute admin commands on a production server ‘willy nilly’ and a demo of customizing a pager to spoof the Goooogle results pager with “Loooootus”. Bonus points for referring to the use of $$Return fields as a “black magic” practice!
It definitely does not read like a stuffy manual; the authors clearly explain topics from the most basic (view panels) to the inkhorn (advanced performance analysis and tuning).
Okay — it’s not quite that simple, but the new chapters on performance tuning are well worth the price of the book alone. Two new chapters dive deep into the bowels of the JSF lifecycle and heap dumps to provide critical information about application performance and scalability. Many other tips throughout the book also show how to build performant applications by efficient use of partial refreshes and partial execution, as well as XPiNC enhancements to optimize initial load time and the use of applications with a shared design.
Things I Learned
Even after working with XPages heavily for the past 4-5 years, there are a myriad of features that I either learned about or gained a better understanding of as a result of reading this book.
It was a refresher on features that I was aware of but rarely use:
- navigation rules
- the ability to assign access control to a panel
- the In Place Form control
- mask converters
createFormproperty of an XPage
- control declaration snippets
requestParamPrefixproperty of a document data source
- the generic
viewEntryobject that you can use to get the current view entry (based on the context) just like
currentDocumentgets the closest document data source
- the ability to programmatically get/set the custom properties of a different custom control from outside of that custom control
- the ability (since 8.5.3) to use
searchproperties of a view data source together (and the fact that column sorting icons are no longer disabled post-8.5.2 after a search was executed because now search and sort can work together)
I learned about some features that I wasn’t aware of:
- making Dynamic Content facets available to web crawlers
skipContainersproperty of a radio button
- the fact that IE11 does not work with the version of CKEditor in 9.0.1
I also learned more about a new feature that I’m well aware of but haven’t tested even though I complained for a long time that it was desperately needed:
- *cough* the SSJS debugger *cough*
And there’s plenty more where that came from. If you don’t know all of this already, it will be well worth your time to read this book. I still refer to the original Mastering XPages book from time to time and I’m sure I will refer to this edition numerous times in the future.