navigationPath & selection properties

Introduction

Once in a while you move back in time and understand why you have forgotten certain rules. Mostly because you have stopped using them or you experience the same pitfalls as others do and you just want to forget them to move ahead.

navigationPath and selection properties

One of those things are the navigationPath from the Application Layout control and the selection property in it’s navigation nodes.

navigationPath

The navigationPath allows you to control the currently selected titlebar Tab and the selection appearance of any Navigator control on the XPage.

selection

The selection property is nothing more than a regular expression used to select an item. The expression is matched against the navigationPath, described above.

selected

Selected is a property that indicates if a node is selected or not. This property often causes confusion.

Mix them together

So if you mix these properties above you can establish some nice usability improvement for your app-user. It can visualize (via style classes) when a certain titlebar should be highlighted or not.

Example Aap Noot Mies

The follwoing example will demonstrate it’s basic feature (and shows some oddness in the Dutch education system while Mies is nothing more than a cat).

As titlebar tabs I have: Aap, Noot and Mies.

As Navigator nodes I have Aap, Noot, Mies and Apes/Gorilla, Apes/Chimp.

Each Navigator links points to an individual XSP but the last two nodes belong to the Aap titlebar tab.

ccLayout

I have a custom control with the application layout control on it. For the navigationPath property I have set up a propery definition so I can adjust it for eac XSP:

<xe:this.configuration>
<xe:oneuiApplication
navigationPath=”#{javascript:compositeData.navigationPath}”

The titlebar nodes are defined as follwed:

<xe:this.titleBarTabs>
<xe:pageTreeNode label=”Aap” selection=”/Aap/.*”
page=”/aap.xsp” selected=”true”>
</xe:pageTreeNode>
<xe:pageTreeNode label=”Noot” selection=”/Noot/.*”
page=”/noot.xsp” selected=”true”>
</xe:pageTreeNode>
<xe:pageTreeNode label=”Mies” selection=”/Mies/.*”
page=”/mies.xsp” selected=”true”>
</xe:pageTreeNode>
</xe:this.titleBarTabs>

Here I have set a regex for the selection property.

Navigator control

On the same custom control I also have a Navigator control:

<xe:navigator id=”navigator1″>
<xe:this.treeNodes>
<xe:pageTreeNode label=”Aap” page=”/aap.xsp”></xe:pageTreeNode>
<xe:pageTreeNode label=”Noot” page=”/noot.xsp”></xe:pageTreeNode>
<xe:pageTreeNode label=”Mies” page=”/mies.xsp”></xe:pageTreeNode>
<xe:basicContainerNode label=”Apes”>
<xe:this.children>
<xe:pageTreeNode label=”Gorilla”
page=”/gorilla.xsp”>
</xe:pageTreeNode>
<xe:pageTreeNode label=”Chimp” page=”/chimp.xsp”></xe:pageTreeNode>
</xe:this.children>
</xe:basicContainerNode>
</xe:this.treeNodes>
</xe:navigator>

Here I do not have to define anything. The control will know itself when a selected node needs to be highlighted.

Gorilla XPage

In the app I have multiple XPages, in the gorilla xpage I have set the navigationPath property as follwed:

<?xml version=”1.0″ encoding=”UTF-8″?>
<xp:view xmlns:xp=”http://www.ibm.com/xsp/core&#8221;
xmlns:xc=”http://www.ibm.com/xsp/custom”&gt;

<xc:ccLayout navigationPath=”/Aap/Gorilla”>
<xp:this.facets>
<xp:image url=”/aap.jpg” id=”image1″ xp:key=”facet_1″></xp:image>
</xp:this.facets>
</xc:ccLayout></xp:view>

As a result the Aap titlebar Tab is highlighted:

titlebarTabs

Not really something that opens your mind but at least I have written it down (with a repo) in the hope I won’t have to re-learn it next time I have to use the application layout control.

 

 

 

Another Graph sample from Domino Explorer

Introduction

In a previous post I dove into Domino Explorer, an XPages application that cans the Domino Directory and the Catalog by using the Graph capabilities in the OpenNTF Domino API.

In this post will describe another XPage in that application. Perhaps it helps to get a better picture on the Graph db and how to build an application around it using XPages, JavaScript, & Java.

Hopefully I will be ready writing before a European football final kicks off…

AllACL.xsp

The xpage I discuss is allacl.xsp. Basically it displays at start a table with ACL entries for the entire catalog. When I click on an entry or row in the table I get presented a list of applications where the selected ACL entry resides in the ACL.

The result of the scenario above captured in the following screen:

de_acl

As the image suggests the entry [Anonymous] resides in 4 applications. Let’s dive in a little deeper into the XPage to see how it’s done…

On document ready

The XPage contains a JS library whichs fires an AJAX call to collect the data for the DataTable object. The rest service resides on the XPage and is accessed via it’s pathinfo property. The restservice is bound to a custom servicebean which resides in the application.

The AJAX call does not provide a parameter to the restservice, so the java class will collect all the vertices of type DXACLEntry.class. For each vertice a JSONJavaObject containing name and level and placed in a JSONJAVAArray object. This array is placed in a JSONJavaObject and returned as a string to the restservice.

When the data is received in the DataTable object only the name property is placed.

The routing is visualized in the next image:

de_acl_rest

On row click

In the JS library for the DataTable object is also defined what should happen when a row in the table is clicked.

Here the name value for the selected row is used in a function that initiates a second DataTable object. Again a call is made to the same restservice. However now the name value is send as a parameter (“?name=” + name value).

The servicebean picks this parameter up (String name = request.getParameter(“name”)) and get’s all the vertices from the Graph with the provided name, matching the DXACLEntry (DXACLEntry aclEntry = graph.getElement(name, DXACLEntry.class)).

Similar as in the document ready event for each found DXACLEntry object a JSONJavaObject is created, now with some more properties (title,filepath, replicaId,server) and placed in a JSONJavaArray. This array is returned as a string to the restservice.

When the results are received by the DataTable object the four properties are displayed per column.

de_acl_rest2

Summary

The scenario is that simple. The DataTable plugin is really a great plugin that does a lot for you and can save you multiple design elements (view controls) by defining in your code what you want in it as result and in which order.

Now let me enjoy my evening of football with a cold beer! Happy development =)

 

 

Stress testing with ODA Graph

I am very interested in Graph data modelling and with the Graph capabilities in OpenNTF Domino API I decided to setup some demo environments just to get my head around the subject and how you can implement it in XPages and use Notes data.

To my opinion reading Notes data in the Graph database structure can bring interesting new opportunities, far beyond what we can deliver with Views and Collections today.

Oliver Busse has provided a great starting point with his SUTOL demo application so I started with that one.

Besides the implementation and Graph capabilities I am also curious about performance.  So I run some tests on my working demo app. With the help with a simple agent I decided to be gentle and create a set of only 20.000 user documents.

The first test was about returning user profiles (nodes) matching certain properties (relations), presented in a repeat control. Below the list the time to load the filtered set is displayed.

stress01

stress02.JPG

When I compare the result with a normal view filter (by category or FT search) the results where a bit disappointing.

I also noted that navigating through the list was very slow (20 seconds or more returning a new set of rows of 10 documents). More than I expected I received timeouts.

stress03

The reason for this performance is still unknown. I guess there is no index created yet for the user node in the graph db structure. Why navigating through the list is so latent in performance is also a mysterie.

Nevertheless, my demo is up and running so expect more results on Graph in XPages with Notes data in the future on this blog.

Below are sampels of performance using the “traditional” FT search filter capacity in Notes. Notice the difference.

stress04.JPG

stress05.JPG

I would like to thank Oliver Busse for his guidance getting the demo app up and running and for explaining some basic concepts of the implementation.

 

 

 

 

Styling the Pager control for Bootstrap UI

Many of us are acquainted with  Bootstrap in our XPages application. However if you place a Pager control on your XPage it does not render according bootstrap style.

So what can you do?

If you have the option to install the Extension Library with Bootstrap in it: DO IT.

If you don’t have that option you can place the Bootstrap resources in your NSF or use a CDN.

If you are using these last two options you will notice the Pager control is still non-Bootstrap styled. You can either:

  • Apply CSS yourself (link, link)
  • Apply your renderer (link)

I noticed in the first approach the … display for page numbering will not be proper styled:

Screen Shot 2016-03-01 at 10.46.13.png

If you are a CSS-wizard you probably can fix this (I can’t).

The second approach renders the Pager perfectly with Bootstrap style applied and hopefully the strange behaviours Frank van der Linden refers to do not appear.

Happy development =)

 

 

Born Social available on GitHub

A long, long time ago I wrote about a project to deliver small building blocks to deliver features from the IBM Connections in XPages application. The posting can be found here: https://quintessens.wordpress.com/2015/04/16/born-social-create-a-social-notes-application-from-scratch/ .

Here and then I was asked to share the project or asked about the progress but since I rarely work with the Connections  platform anymore I thought it could be helpful to upload the Born Social project on GitHub so people can make use of it if they like to.

Unfortunately in the meantime I did no hear or read so much about integration between Connections and IBM Domino so I am not sure if this is a (hot) topic anymore. My initial thought with the project was that it would be ‘cool’ to utilize data in Connections in XPages applications.

I also wrote a small document that helps you to get the application up and running and explains how to use the re-usable custom controls.

The project is available here on GitHub.

Carousel with dynamic content

Introduction

For an application I needed a carousel to display images on the frontpage. Since we go “all-in” Bootstrap the “natural choice” would be the Carousel component from the Extension Library. Unfortunately that control currently only accepts “static” slideNodes so I had to come up with something similar.

In the beginning…

First I just took the sample code from W3schools how to setup a basic Bootstrap Carousel component.

car_code01

Second I set up a Notes view that contains the data I need for my carousel. This view will be the source for an XPages Rest Service control (PDF alert) which I call after page load with an Ajax call using jQuery’s getJSON.

car_code02

car_code03

As you can see I update the Bootstrap sample code with the received result(s).

As a result I get the Carousel component from Bootstrap but now with ‘dynamic content’.

carousel

(for those who have never seen a Carousel)

The only complication I experienced was due to the fact that I separate the design from the data and accessing the data is easier in SSJS/Java then CSJS.

Here is the code: Link Dropbox

Happy development =)

Adding a Dojo tooltip to your XPages valuepicker

Here is a simple usability tip.

In some corporate organizations not all members are acquainted with modern, modest UI. For those an icon does not always tell them that an action lies underneath it.

For example the value picker from the Extension Library offers you a nice magnifier icon out of the box (which you can set to a custom icon in case desired). If you want to help your senior colleague that there lies no danger beneath clicking that icon you could provide an alternative tooltip for it.

Here is some sample code how you could do this:

<section class=”container”>
<div class=”row”>
<div class=”col-sm-1″><label for=”exampleInputName2″>Name</label></div>
<div class=”col-sm-2″><xp:inputText id=”inputText1″></xp:inputText></div>
<div class=”col-sm-9″>
<span id=”valuePickerTooltip”>
<xe:valuePicker id=”valuePicker1″ for=”inputText1″>
<xe:this.dataProvider>
<xe:dominoViewValuePicker databaseName=”FakeNames40K.nsf”
viewName=”People”>
</xe:dominoViewValuePicker>
</xe:this.dataProvider>
</xe:valuePicker>
</span>
<xe:tooltip id=”tooltip1″ for=”valuePickerTooltip”
label=”Pick a Person from the Address Book” position=”after”>
</xe:tooltip>
</div>
</div>
<div class=”row”>
<div class=”col-sm-9 col-sm-offset-1″><button type=”submit” class=”btn btn-primary”>Send invitation</button>
</div>
</div>
</section>

As a result the user will be presented something as followed when hovering over that icon:

tooltip

Building a Live Search function with Domino Access Services & jQuery Tokeninput

Introduction

A live search is a function where get search results returned while you type. In this post I will describe how you can add such a feature using the jQuery Tokeninput plugin and perform a full text search with Domino Access Services (DAS)as your data provider.

But first let’s take a look at how the end result looks like:

searchres

As in other examples we will apply the live search to the infamous fakenames application. You can grab this directory application from Codestore.

Step 1 – Download the resources and add them to your XPage

Add the following resources to a custom control:

Step 2 – Add the filter and search field

In the result screenshot you noticed the following elements:

  • A filter (People, Groups, Holidays)
  • A search field (with typeahead).
  • A (formatted) result list.

Therefor add the following HTML on your custom control:

As you notice we will be using Bootstrap to make the appearance a bit more attractive.

search_param

The hidden input element search_param will be the container for our selected filter.  The following code will set the value:

livesearch-input

The Tokeninput plugin will inject an (initially empty) unordered result list and input field in the livesearch-input input element.

Include a function to initiate the Tokeninput plugin:

Step 3 – Activate the plugin

In order to activate the Tokeninput plugin you need to include a script block control on your custom control and ad the following script:

function getObjType() {
var val = $(“#search_param”).val();
return val;
}

var restPrefix = “./api/data/collections/name/”
var hintText = “Enter text, use asterix(*) for Fulltext wildcards”;
var searchingText = “Searching…”;
var queryParam = “search”;
var propertyToSearch = “name”;
var searchDelay = 2000;
var minChars = 2;
var resultsLimit = 5; //not working??
var noResultsText = “No matches”;
var tokenLimit = 1;
var preventDuplicates = true;
var onAdd = function(item) {
var objType = getObjType();
var docID = item[‘@unid’];
var URL = “”;
switch (objType) {
case “Groups”:
URL = “Group.xsp?unid=” + docID;
break;
case “Holidays”:
URL = “Holiday.xsp?unid=” + docID;
break;
default:
URL = “Person.xsp?unid=” + docID;
}
window.location = URL;
};
var resultsFormatter = function(item) {
var objType = getObjType();
switch (objType) {
case “Group”:
sub = “dummy group sub”;
break;
case “Holiday”:
sub = “dummy Holiday sub”;
break;
default:
sub = “” + item.job;
}
if (sub == “”) {
sub = “No title available“;
}
if (sub.length > 30) sub = sub.substring(0, 30) + “…”;
var name = item.name;
if (name.length > 30) name = name.substring(0, 30) + “…”;
var img = ‘‘;
var text = ‘

‘ + name + ‘

‘ + sub + ‘


return ‘

  • ‘ + ‘
    ‘ + img + text + ‘

‘;
};

function setPlaceHolder() {
$(“#token-input-livesearch-input”).attr(“placeholder”, “Enter text”);
}

function init() {
$(“#livesearch-input”).tokenInput(restPrefix + getObjType(), {
hintText: hintText,
searchingText: searchingText,
queryParam: queryParam,
propertyToSearch: propertyToSearch,
searchDelay: searchDelay,
minChars: minChars,
resultsLimit: resultsLimit,
noResultsText: noResultsText,
tokenLimit: tokenLimit,
onAdd: onAdd,
preventDuplicates: preventDuplicates,
resultsFormatter: resultsFormatter
});
setPlaceHolder();
}

function re_init(objType) {
$(“#token-input-livesearch-input”).remove();
$(“.token-input-list”).remove();
$(“#livesearch-input”).tokenInput(restPrefix + getObjType(), {
hintText: hintText,
searchingText: searchingText,
queryParam: queryParam,
propertyToSearch: propertyToSearch,
searchDelay: searchDelay,
minChars: minChars,
resultsLimit: resultsLimit,
noResultsText: noResultsText,
tokenLimit: tokenLimit,
onAdd: onAdd,
preventDuplicates: preventDuplicates,
resultsFormatter: resultsFormatter
});
setPlaceHolder();
}

function submitSearch() {
//not required, overwritten by onAdd function.
}

As you see the Tokeinput plugin can be steered via diverse parameters. A clear description of the available options you can read here.

In our case we determine:

Data Provider

var restPrefix = “./api/data/collections/name/”

This defines we will be using Domino Access Services as data provider. We will use the names of the views People, Groups, Holidays which correspond with the options in our filter list.

Remember you need to enable DAS for the database AND the views.

onAdd = function(item)

The variable onAdd is a function that will be called when we select an item from the result list. We have set to allow only one item to be selected and the onAdd function will open a new window location with the corresponding object/document.

URL = “Person.xsp?unid=” + docID;
}
window.location = URL;

resultsFormatter = function(item)

This variable defines how the items in the collection provided by Domino Access Services will be presented in the UI. You can be as creative with it as you like. I choose for the option for an image, distinguished name and a sub-title e.g. the function for a person.

Ready

Are we done already? Yes we are! All the heavy lifting is done by the Tokeninput plugin and Domino Access Services.

Notice that Full Text search in Domino Access Services supports the usage of an asterix. Otherwise you get only results returned with an exact match.

firebugUse a plugin for your browser to check the URL call and response to DAS.

Some final thoughts

Do I found the live search feature useful?

– Yeah. Especially in mobile web applications you want to avoid that a user has to go back to home navigation each and every time. And with large data-sets infinite scrolling is a good option.

Do I find the Tokeninput plugin valuable?

– I find the plugin easy to understand but I noticed not all properties are implemented:-/  An example of something what I expected to be implemented is the number of returned results (fixed to max 10 items).

Can I recommend the plugin?

– In case you use Bootstrap applying a bootstrap theme meant mostly stripping the default style sheet. In case you use the Application Layout control from the Extension Library you will discover some problems:

  • When applying the live search in the search bar you get overlay with the Utility links.
  • When applying a filter option you get scrolling issues when opening the dropdown menu in the navbar section.
  • The result list can not be displayed direct under the search field due to the overlay of the navbar and it’s margins.

The consequence of these problems above made me decide to place the search bar in the main column section instead of the search bar and align it to the right via the pull-right class in Bootstrap. The result looks similar but I loose some white space. (perhaps the solution lies in understanding Bootstrap a bit more).

In case you can live with these conditions or restrictions I think you have an awesome desired feature!

Your turn!

What are your thoughts? In case you have provide a live search feature via some other plugin or custom code I am happy to hear from you.

I have uploaded a sample on Dropbox. I am happy to hear the improvements you have made.

Happy coding =)

Adding a sliding menu to your Bootstrap Application Layout control

Introduction

Since responsive webdesign (RWD) is on top of the list in most application development projects these days I assume most of us have been looking at the options within IBM Notes.

Bootstrap

In case you use the Bootstrap plugin in the Extension Library you have noticed that the menu in the left column get presented above the main column in smaller devices.

bs_desktop

Image: Display on desktop

bs_phone

Image: Display on phone

As you can see in a more advanced application the menu options already suppress the content too much at the bottom. So what are your options?

Off Canvas Slide Menu For Bootstrap

In this post I will describe how I implemented in XPages a slide menu which is described here. We still use the Application Layout control with the Bootstrap RWD functionality since it contains more functionality than just to provide a navbar.

Step 1 – Provide a Menu icon

We need something (text, button, icon) from where we can initiate the appearance of the menu. In our case I choose to include a ‘hamburger’ menu icon in the navBarLogo property:

<xe:this.configuration>
<xe:simpleResponsiveConfiguration navbar=”true”
loaded=”true” navbarLogo=”/1432224591_menu-alt.png”
navbarLogoStyleClass=”extraMenu” navbarText=”MyApp”>
</xe:simpleResponsiveConfiguration>
</xe:this.configuration>

For example iconfinder provide great icons.

Step 2 – Register Click event for Menu icon

I included “extraMenu” as an additional styleclass. This styleclass we will use when the document is ready. We do this in a Script Block control:

<xp:scriptBlock id=”onLoadScript” type=”text/javascript”>

<xp:this.value><![CDATA[
$(document).ready(function(){
$(“.extraMenu“).attr(“id”,”nav-expander“);
//Navigation Menu Slider
$(‘#nav-expander‘).on(‘click‘,function(e){
e.preventDefault();
$(‘body’).toggleClass(‘nav-expanded’);
});
$(‘#nav-close’).on(‘click’,function(e){
e.preventDefault();
$(‘body’).removeClass(‘nav-expanded’);
});

// Initialize navgoco with default options
$(“.main-menu”).navgoco({
caret: ‘<span class=”caret”></span>’,
accordion: false,
openClass: ‘open’,
save: true,
cookie: {
name: ‘navgoco’,
expires: false,
path: ‘/’
},
slide: {
duration: 300,
easing: ‘swing’
}
});
});]]></xp:this.value>
</xp:scriptBlock>

When the document is ready we assign the ID attribute to the navbarLogo since this ID is used to bind an click event on. We could have bind the event directly on the class but I am not sure if the ID is used in any other way (don’t break what isn’t broken).

Step 3 – Provide a menu that slides in.

In this example I simply provide the menu that is used in the demo:

<nav>
<ul class=”list-unstyled main-menu”>
<!–Include your navigation here–>
<li class=”text-right”>
<a href=”#” id=”nav-close”>X</a>
</li>
<li><a href=”#”>Menu One<span class=”icon”></span></a></li>
<li><a href=”#”>Menu Two<span class=”icon”></span></a></li>
<li><a href=”#”>Menu Three<span class=”icon”></span></a></li>
<li>
<a href=”#”>Dropdown</a>
<ul class=”list-unstyled”>
<li class=”sub-nav”><a href=”#”>Sub Menu One<span class=”icon”></span></a></li>
<li class=”sub-nav”><a href=”#”>Sub Menu Two<span class=”icon”></span></a></li>
<li class=”sub-nav”><a href=”#”>Sub Menu Three<span class=”icon”></span></a></li>
<li class=”sub-nav”><a href=”#”>Sub Menu Four<span class=”icon”></span></a></li>
<li class=”sub-nav”><a href=”#”>Sub Menu Five<span class=”icon”></span></a></li>
</ul>
</li>
<li><a href=”#”>Menu Four<span class=”icon”></span></a></li>
<li><a href=”#”>Menu Five<span class=”icon”></span></a></li>
</ul>
</nav>

Step 4 – Include the supporting files

The demo uses the following files which you should add to your application as resources:

js

<script
src=”/jquery.navgoco.js”>
</script>

css

<xp:this.resources>
<xp:styleSheet href=”/main.css”></xp:styleSheet>
</xp:this.resources>

The result

The image below gives you an indication what the result looks like. When you click the hamburger icon the menu appears from the right. With the X marker you can close the menu again.

result

Notice that my content is not suppressed below the menu as the Bootstrap plugin would do.

Download

An demo XPages application is available on my dropbox account

Delivering responsive web design in IBM Notes applications

The following is a re-post I originally posted on Infoware’s blog: link.

Introduction

Responsive web design (RWD) has been the talk of town the last years. In 2012 it was listed as #2 in ‘Top Web Design Trends’ by .net magazine and Mashable called 2013 the ‘Year of Responsive Web Design’. Many other sources have recommended responsive design as a cost-effective alternative to mobile applications.

responsive

While I assume that a large portion of the internet (and in some cases intranet) sites are nowadays optimized for the device that accesses them, but what about your company’s (internal) business applications? 

Business value

IT departments need to prioritize their activities and internal applications are most often accessed by a smaller audience than external applications. Historically the internal app was accessed with a desktop computer. With the trend of smartphones and tablets taking over the workspace this may no longer be the case in your company?

With a VPN connection users want to continue to execute their work on this new breed of devices, instead starting up a desktop computer for a single task. Here is where the business value of RWD comes in.

Continue to work on same device = More productive employees = Saving time and perhaps even hardware

Mobile first

A trend is to apply the progressive application strategy of ‘Mobile first’. Instead of designing a complex application for desktop computers first and thereafter gracefully degrade it for mobile devices, the user interface is initially designed for mobile devices and enhanced for desktops with more processing power.

mobile-first-icons

 

Many RWD frameworks embrace this ‘Mobile first’ concept nowadays.

Options in Notes

So what are your options in delivering RWD in your beloved Notes applications? Depending on your roadmap for the platform and personal preferences you have the following options.

  1. Build the application with XPages technologies.
  2. Build the application with common web technologies.

The XPages way

An approach for your Notes platform that is highly promoted by IBM is to deliver web interfaces for Notes applications with XPages. Not only bring you in Rapid Application Development (RAD) principles in your project also the range of capabilities is much more diverse.

Another benefit is that you can stay on the core technologies: JSF, JavaScript and Java. This you can combine with common web technologies like AJAX, HTML5, CSS and REST services. For the RWD you can use your favorite framework such as Bootstrap or Foundation.

Bootstrap framework

twitter-bootstrap

Bootstrap is a popular framework for developing responsive, mobile first projects on the web. It makes front-end web development faster and easier. Bootstrap is based upon HTML, CSS and JavaScript, technologies already well-known in Notes web apps.

Distribution

You have several options how you distribute the Bootstrap framework to your audience:

  1. Install the files on your Domino server.
  2. Embed the files in a Notes application.
  3. Install an additional XSP library on your Domino server.
  4. Install the latest extension library on your Domino server.

In case you do not utilize the OSGi runtime on your Domino server you can either install the files on centrally on the Domino server or embed the files in each Notes application. The installation on the Domino server makes the distribution of updates easier but the administrator is responsible for the distribution across servers. Embedding the files in a Notes application is less efficient (e.g. caching) but makes distribution of updates a task for the developer.

Probably the best approach would be to utilize the OSGi runtime on your Domino server and distribute the files as a library via an Update site Notes application across your servers. This makes the task even simple and small for an administrator.

If you choose to do so you have the option to either install bootstrap4xpages library as a separate library or you can install the latest extension library (from 10 november 2014). The latter give you several benefits:

  • Custom renderer for the Application Layout control, which makes it easy to define the layout structure of your application.
    • This renderer gives the control a Bootstrap look & feel, as well making the control responsive.
  • A newer version of jQuery.
  • Latest Bootstrap themes (3.2.0 normal or flat).
  • Additional configuration options in the Application Layout control wizard for the Bootstrap navigation components.

Separate Mobile devices UI alternative

The extension library (a library with additional XPages controls and functions) provides also so-called ‘Mobile controls’ which allow you to deliver a separate interface for mobile devices for your Notes apps. Via a wizard you can build a ‘single page application’ in a matter of minutes with full CRUD (create, read, update and delete) operations and infinite scrolling through document lists (aka views).

This approach does not deliver RWD but a separate user interface for mobile devices. At least it gives you the option to deliver a UI adapted for mobile devices in a very short time with little investment.

You can choose to make the UI of the app look like a native app for iPhone or Android. Alternatively you can choose to make the UI look in line with other IBM products (iNotes, Connections). A video that demonstrates the controls briefly you can find here: http://vimeo.com/99537780.

The WEB way

In case you do not walk the XPages path but instead you prefer the approach to deliver the application with more common web technologies like HTML, CSS, AJAX and REST services you can still install the files of your responsive web design framework of choice on the Domino server or embed them in a Notes application.

From there you can start to (re)write your ‘traditional’ Domino application as a Web project. In the latter case you use Notes only as a container for your data documents and design elements and use forms and views only as data schemes.

This approach dodges the RAD capabilities in Notes and will demand more development time. But you can apply this approach also to other platforms that you may have. You can later even debate why the data should be stored in Notes and not in a document-oriented database alternative? The layered security and replication capabilities are often good arguments.

Implementing RWD via the Extension Library option

In the following scenario we will describe the implementation of RWD with the Extension Library more in details.

  • Database enablement.
  • Application Layout.

Database enablement

Assuming you have installed the extensions for the Domino server and Domino Designer (DDE) client according the instructions in the readme.pdf file you can now enable a Notes application.

XSP properties

The XSP properties file allows you to configure parameters for the XPages framework. Open the file in DDE.

Screenshot_1

In the General tab you have now two more themes to select:

  • Bootstrap 3.2.0
  • Bootstrap 3.2.0 flat

The ‘flat’ theme delivers:

  • The resources and styling that comes with Bootstrap v3.2.0.
  • jQuery v2.1.1 resources.
  • Cleanup of specific XPages controls when using Bootstrap.
  • Glyphicon halflings.
  • dbootstrap resources, which provide Bootstrap styling for Dojo controls.

The ‘ordinary’ theme provides all of the same resources as the flat theme, and includes 3D effects to buttons and some other additional styling.

Select one of the two themes:

Screenshot_2

Application layout

The RWD plugin adds a new renderer for the Application Layout control which you normally use to structure the layout of your application. This renderer gives your application layout the Bootstrap look and feel, as well as responsive behavior. When the application is rendered on a smaller screen, such as on a mobile device, it will automatically re-organize the application contents for an optimal user experience.

The control also has new configuration options. Add the Application control on a custom control and open the All Properties tab. In the basics section you can choose now the xe:bootstrapResponsiveConfiguration option:

Screenshot_3

Note: in case you have already a configured Application Layout control you can change the configuration option directly in the Source panel to keep the rest of your configuration (e.g. xe:applicationConfiguration -> xe:bootstrapResponsiveConfiguration).

This configuration options give you several more properties:

  • collapseLeftColumn
  • collapseLeftMenuLabel
  • collapaseLeftTarget
  • fixedNavbar
  • invertedNavbar
  • pageWidth

With the first 3 properties you define how the left column should behave on smaller devices (collapsed for smaller devices, display text when collapsed, item the left menu should be attached to).

You can determine the behavior of the navbar (inverted, fixed (top or bottom)) and the width of the page e.g. fluid = use Bootstrap ‘fluid’ container (almost full width).

Wizard

When you initially drag on the Application Layout control on the custom control a two-step wizard is presented. In the first step you select one of available configurations. You can filter on responsive and non-responsive.

Screenshot_4

In the second you set the properties for the chosen configuration. In case you choose the Responsive Bootstrap option you will see the following screen:

Screenshot_5

Under configuration you can set the properties for the layout including the 6 additional properties mentioned earlier. Set also the other properties like you would normally do.

Voila! Your application is now ready for development.

Hiding elements for specific devices

The plugin provides only the resources and structure for responsive web design. In case you want to optimize the layout for devices by explicitly show or hide them you can use CSS classes.

Bootstrap provides some handful helper classes, for faster mobile-friendly development. These can be used for showing and hiding content by device via media query combined with large, small, and medium devices.

Classes Devices
.visible-xs Extra small (less than 768px) visible
.visible-sm Small (up to 768 px) visible
.visible-md Medium (768 px to 991 px) visible
.visible-lg Larger (992 px and above) visible
.hidden-xs Extra small (less than 768px) hidden
.hidden-sm Small (up to 768 px) hidden
.hidden-md Medium (768 px to 991 px) hidden
.hidden-lg Larger (992 px and above) hidden

Note that the elements that you hide are still being loaded, but simply not being displayed.

Data View control

Probably a typical use case is the display of table columns or lists. On a desktop you may want to show more columns than on a smaller devices.

Typical you use the Data View control from the extension library to display lists of documents. The information you want to display as a link is defined in the summaryColumn property.

Screenshot_6

Additional columns that are displayed on the right of the summaryColumn will be displayed via the extraColumns property. Each additional column is defined in a viewExtraColumn item which contains properties for styleClass and headerStyleClass. For example you could set these as followed:

<xe:this.extraColumns>

<xe:viewExtraColumn columnName=”Date” columnTitle=”Date” style=”width: 100px”  styleClass=” hidden-xs hidden-sm ” headerStyleClass=” hidden-xs hidden-sm“></xe:viewExtraColumn>

</xe:this.extraColumns>

This will show the extra column only for medium and larger devices since they will be hidden for (extra) small devices.

Screenshot_7

Wrap up

Delivering responsive web design on your Notes applications has never been as easy as it is nowadays with the RWD plugin in the extension library. It also respects the rapid application (web) development mantra of XPages.

In case you do decide to follow this path remember you need to check what information you want to show or hide for specific devices.

So what is keeping you from getting a bigger bang for the buck by delivering optimized user experiences for mobile, tablet and desktops for your Notes applications?