Modernizing A Notes App With XPages (MANA-X) Part 1 – Introduction

A few weeks ago, I started a new position. For this position, I was hired specifically to lead the transition of a key Lotus Notes client application into the XPages world, where modern capabilities and UI can be merged together to create a great user experience and better support the business processes going forward.

Actually, this application is more than just a “key” application. It is THE application. Well, technically, it is several applications, or modules, all tied together under one umbrella, which have supported just about every aspect of a business that has tripled in size in the last 10-15 years.

While there is an urge to jump right in and start coding, there are many things to consider ahead of time:

  • Technical – Which framework(s) to use? Getting the development team up to speed on source control for better code management. Developing for IE9/IE11.
  • Cultural – How to introduce users to a modern web application when they are used to working in the Lotus Notes client?
  • Infrastructure – Keeping users productive with high availability. Making sure remote users do not have performance issues.

This is in no way intended to be a comprehensive list; These are just a few of the issues we’ve started to discuss as a team in the early stages of project planning.

Over the course of the coming months (years?), I’m hoping to share our experiences of moving this massive application to XPages and all of the successes and challenges that come with that (as much as I can, anyway).

Disclaimer: Any opinions and views expressed are my own and not necessarily those of my company. This series is intended as one company’s experience of moving an application to XPages and not a definitive guide on how to migrate an application to XPages.

XPages tip: Using jQuery class selectors with hidden inputs

If you cut your XPages teeth by using the out-of-the-box-included dojo libraries, then you are probably intimately familiar with dojo.byId(“#{id:myElementID}”) to locate elements on your XPage based on the id attribute.

After starting to weave jQuery into your projects, you probably realized pretty quickly that the jQuery id selector syntax of $(“#myElementID”) does not work well with XPage component ids. But of course there is a solution for that – Marky Roden’s XSnippet which wraps the jQuery ID selector function in a XPage version.

Due to the above issues with getting elements by ID in jQuery, you probably started using class selectors such as $(“.myClassName”). This is all fine and good – until you go to add a class to the properties panel of a hidden input control:

As you can see from the screenshot above, there is no place to enter a class name in the properties for a hidden input control. Seems kind of silly, doesn’t it? It’s a field. Fields have classes. I should be able to add a class to a hidden field. Apparently not.

Luckily, there is an incredibly simple way to do this using the attrs properties in the basics section of the properties panel:

  • Add a new attribute by clicking the plus sign
  • In the name field, enter “class” (do not add the quotes)
  • In the value field, enter the name of your class, for example, “myClassName” (again, no quotes)

Now, you should be able to access your hidden input using a jQuery selector.

My first OpenNTF project – Dojo Name Picker

A few years ago I created a Name Picker for an XPages project I was working on at the time.  The application had several fields that required the selection of users from the address book, but the available options at the time did not fit the bill.  In addition, this was the first XPages application for this user base after being firmly entrenched in Notes Client applications for many years.  As a result, there was a need to provide some functionality that helped build a bridge from Notes Client to web/XPage applications.  Being able to select users from an address book in a similar manner as the Notes Client was a good place to build this bridge.

Multi Select Name Picker

Multi Select Name Picker

Single Select Name Picker

Single Select Name Picker

Why not just use the ExtLib version?

When I first started building this control, the ExtLib version did not exist yet.  Even after ExtLib was released, the environment where this was born did not have ExtLib installed on their servers.  In my testing against the ExtLib name picker, this version outperformed it using the 40k entry address book, fakenames.nsf, as well as provides functionality that does not exist in the ExtLib version.

The key features of Dojo Name Picker 1.0 include:

  • Ability to choose People, People & Groups, or just Groups.
  • Multi Select via a dual column dialog.
  • Single Select via a single column dialog.
  • Lazy loading of additional entries when scrolling up or down.
  • Only creates one dojo dialog widget no matter how many names fields are needed on a form.
  • In Firefox and XPiNC the dialog will also display the associated icon for an entry (IE and Chrome do not support option tag background images).
  • Ability have the name picker execute a function with the selected value(s) being passed to the function as a parameter.
  • Ability to specify a partial refresh target on dialog close.
  • No dependency on ExtLib.
  • Will work on 8.5.3 and above (will probably work on 8.5.2 but this release has not been tested on that version).

You can test the name picker for yourself via a live demo here.

You can view this project on OpenNTF here.

Future Enhancements

While I feel this is a good, solid release, there are some improvements I would like to make:

  • Bootstrap version (coming soon!) .
  • Improved caching.
  • Ability to return selected items as a JSON string.
  • Ability to define additional fields to pull from the NAB
  • Support multiple address books

Thanks for checking it out!

Copying Custom Controls

This tip is pretty simple, and it might be common knowledge to most people, but I stumbled onto it pretty much by accident.

Copying a custom control from one XPage to another is fairly common, but when you do so and go to build your new page, you get the message:

The prefix “xc” for element “xc:ccTest” is not bound.


Previously, I never really bothered to look into this message any further.  I took the easy way out and simply dragged a new copy of the custom control onto the XPage, copied any custom properties (if any), and went on my way.  However, this can get annoying REAL fast if you have a lot of custom controls that need to be copied.

Luckily, there is a ridiculously easy way to quickly get rid of the above message.

When you create a new Xpage, the standard markup looks like this:

<?xml version="1.0" encoding="UTF-8"?> 
<xp:view xmlns:xp=""> </xp:view>

Look what happens as soon as you drag a custom control on to your XPage:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp=""

Adding the bolded line above to the xp:view tag of your page will allow you to copy custom controls to your XPage without frustration.  At the end of the day is it really a big time saver?  No.  But at least you have a better understanding of the error message.


SSJS variables vs. scope variables

Recently, I ran into a strange issue that had me scratching my head for longer than I’d care to admit.  I created a server side javascript object that contained a function, something like this:

var myVar = {
	load : function() {
		print ("performing some sort of function");

This ssjs object contained a set of functions that were used in conjunction with one another to perform various functions.

In some cases, these functions needed to grab some data from a viewScope variable, so I figured it made perfect sense to have a key name that was consistent with my ssjs object. I had a button that was setting the value like so:

viewScope.myVar = "foo";

Innocent enough, right?

According to the XPages runtime, apparently not, because I ended up with a message like this:

Error calling method 'load()' on an object of type 'String [JavaScript Object]'

OK, so what happens if we change our scope variable from viewScope to sessionScope?

sessionScope.myVar = "foo";

Same result:

Error calling method 'load()' on an object of type 'String [JavaScript Object]'

My assumption is, this has something to do with the way these objects are serialized. If someone has a better explanation, I’d love to hear it.

In the meantime, don’t give scope variable keys the same name as server side javascript variable.