collapsible menu with persistent state


For a project I needed to have collapsible menus where the state is persistent, in other words after a refresh or a reload it should now if the menu was opened or closed.

The content of the menu is dynamic and rather complicated containing sub levels with multiple actions in them. Each level item would trigger to rebuild the presented document collection via Java (perhaps more common known as a faceted search).


Since we are using the Extension Library I took a look at the controls but I could not find one that fulfills my requirements (accordion, dojo accordion pane, dojo tab pane, outline). To prevent to embed “another” Jquery plugin I looked across the Dojo site and found the titlePane dijit.

A TitlePane is a pane that can be opened or collapsed, with a title on top. The visibility of the pane’s contents is toggled by activating an arrow “button” on the title bar via the mouse or keyboard. It extends ContentPane but since it isn’t used inside other layout widgets it’s not in the dijit.layout module.

To be honest I am not a Dojo warrior and mostly are satisfied with jQuery plugins but this sounded like something that I could use. For now I only have to menu sections to collapse; a KPI section and a Filter section. Each section has there level 1 and level 2 items.

Since the application works as much as possible with partial refresh and each filtering affects the content of these 2 sections I also needed to save the state of the panes (open or closed). This sounded like a combination of client (open / close the pane) and server side (save the state in a scope variable) actions. Hmmm. From day 1 I have found this mixture of CSJS and SSJS a problem child which you tend to forget/mess up. I decided to implement the approach Oliver Busse promotes in the following post “Writing and reading scoped variables via client side Javascript“. This approach probably makes the code less cluttered with mixture of languages.

I also noticed that the titlePane dijit is not error-proof implemented in the Bootstrap4XPages project in the Extension Library but I found a fix described in the post “fix for down caret icon in dijit.TitlePane when using Bootstrap from ExtLib“. I got a response from Brian Gleeson (IBM): A fix for the dijit.TitlePane issue has been delivered, and should show up in the next Extension Library release. Great & thank you Brian!

So having conquered the circumstances described above what became the result and how did I implement it?


Let’s start with the result:


Image 1: first section opened.


Image 2: both sections opened.


Each of the KPI and Filter item (can) have sub levels with different presentation and functionality which I will not describe for simplicity reasons.


The titlePane dijit is not so hard to implement. Add the dojo module to your resources:

<xp:dojoModule name=”dijit.TitlePane”></xp:dojoModule>

Next add a div to your XPage and set the dojoType and title property. The mat-card styleclass provides a material design presentation.


Also define custom attributes for open and toggleble for the div element. These are properties of the titlepane dijit.

Event handler

The event handler checks the state of the pane and writes the state to a scoped variable when the title section of the pane is clicked. For a complete description how to implement Oliver Busse’s utility I would like to direct you to his site.

id=”titlePaneKPI”  dojoType=”dijit.TitlePane” title=”Sales KPI”  styleClass=”mat-card”>
<xp:attr name=”open” value=”false”></xp:attr>
<xp:attr name=”toggleable” value=”true”></xp:attr>
<xp:eventHandler event=”onclick” submit=”false”>
<xp:this.script><![CDATA[var KPI = dojo.dijit.byId(“#{id:titlePaneKPI}”);
if ({
setScopeValue(“view”, “MenuKPI”, “1”);
setScopeValue(“view”, “MenuKPI”, “0”);

</xp:div><!– /dijit.TitlePane –>

Odd behaviour

I also noticed a strange behaviour of the titlePane. At start I had multiple controls on my xpage to see their differences and capabilities. When I removed the Dojo Accordion Pane the carets for the dijitPane behaved odd:


Note the plus (+) and minus (-) signs after the caret :-?

So in front of the TitlePane dijit divs I placed a Dojo Accordion Pane and set the display style property to none (via a styleclass):

<xe:djAccordionPane id=”djAccordionPane1″


titlePane content

The content of the titlepane can be anything, in my case via a repeat controls a list group with list-group-items is generated.

  • Lead Flow

    <!– /col-xs-12 col-sm-12 col-md-12 col-lg-12 –>
    </div><!– /row –>

    Qualified Opportunities

    <!–/col-xs-12 col-sm-12 col-md-12 col-lg-12 –>
    </div><!– /row –>


  • Personally I find it a good practice to comment the closure of elements, especially when using Bootstrap nowadays.

    Event handler when loading the page/custom control

    The last thing to include is an event handler that opens or closes the titlePane dijits depending on their last states that are stored in scoped variables.

    I placed the event handler on the custom control where the titlepanes reside in so it gets initiated every time a partial refresh takes place for the custom control.

    <xp:eventHandler event=”onClientLoad” submit=”false”>
    <xp:this.script><![CDATA[function getMenuState(){
    var KPI = dojo.byId(“#{id:titlePaneKPI}”);
    var Filter = dojo.byId(“#{id:titlePaneFilter}”);
    var KPI_status = getScopeValue(“view”, “MenuKPI”);
    var Filter_status = getScopeValue(“view”, “MenuFilter”);

    I was not able to store the function in a CSJS library because it kept telling me then that dojo could not find any note to act upon, but this is probably due to my lack of guru knowledge of Dojo.

    Wrap up

    That is about it! With little programming and a couple of hordes I managed to apply a menu with a consistent state when performing partial refreshes!

    I am looking forward to hear what alternative solutions you have produced, perhaps they can serve me in the future. Happy coding!


    fix for down caret icon in dijit.TitlePane when using Bootstrap from ExtLib

    For unknown reason the dijit.TitlePane is not part of the Dojo controls in the ExtLib. You can implement your own version and Mark Roden posted a nice description how to achieve this. HOWEVER in case you are using the Bootstrap theme in the Extension Library you will notice when opening a pane the down caret icon can not be displayed.

    Here is the build up for 2 TitlePanes dijits:

    <xp:div id=”titlePaneGemCars” dojoType=”dijit.TitlePane” title=”German Cars”>
    <xp:attr name=”open” value=”false”></xp:attr>
    <xp:attr name=”toggleable” value=”true”></xp:attr>
    <xp:div id=”titlePaneJapBikes” dojoType=”dijit.TitlePane”
    title=”Japanese Bikes”>
    <xp:attr name=”open” value=”false”></xp:attr>
    <xp:attr name=”toggleable” value=”true”></xp:attr>

    Here is how it looks like in the browser:


    In case you choose another theme e.g. oneUI (*cough*) the panes are displayed as followed:


    Note the display of carets is different (no carets for closed panes).

    So how are we going to fix this? Via your friend CSS! Include the following CSS snippet at your page/stylesheet/theme:

    .xsp.dbootstrap .dijitTitlePane .dijitArrowNode::before {
    color: #428bca;
    font-family: “Glyphicons Halflings”;
    content: “\e114”;
    font-size: 12px;
    padding-left: 10px;
    position: relative;
    top: -1px;

    The definition is similar for a closed dijit but the content is set here to specific Glyphicon (the chevron down icon). The content is set to a hexidecimal value for an icon? On the glyphicons site you can search for halflings and it will tell for the chevron-down icon the value is UTF+e114.

    As a result your opened titlepane wil have the correct icon displayed:


    Happy coding!

    Ps I assume there is someone smart here to register this break as a request at IBM?

    Opening the Bootstrap modal (dialog) from a repeat control

    Here is a simple XPages development tip when working with Bootstrap:

    In an app we replaced the Dojo dialog from the Extension Library with the Bootstrap modal due to scrolling problems: When the dialog pane exceeds the content pane, scrolling in the dialog lead often to scrolling of the background content. This was with mobile devices often a crime.

    The Dojo dialog you can display in client side and server side JavaScript. The Bootstrap modal only in client-side.

    Since I am calling the modal from within a repeat control and I need to update the content of the modal with data from the document represented in the xp:repeat control I needed to first call a function to collect additional back-end document data & perform a partial refresh on the modal (which resides in an xp:panel). Then I needed to call the function to show the modal.


    Perhaps a bit well hidden is the onComplete property for the eventHandler. Here is the way I find it:

    • Find the element you want to define and action for (or already have).
    • Select/Highlight the event in the Outline control.
    • Open the Properties view for the Event handler.
    • Navigate to the onComplete property. Here is where you can open the editor.

    Here is how it looks like in some screen shots:




    The code looks as followed:

    <xp:link escape=”true” text=”Link” id=”link2″>
    <xp:this.action><![CDATA[#{javascript:var id:String = pix.docUNID;

    viewScope.put(“helloWorld”, “Hello World from ” +id)}]]></xp:this.action>

    As result my dialog is presented with updated content every time it is presented:


    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:dominoViewValuePicker databaseName=”FakeNames40K.nsf”
    <xe:tooltip id=”tooltip1″ for=”valuePickerTooltip”
    label=”Pick a Person from the Address Book” position=”after”>
    <div class=”row”>
    <div class=”col-sm-9 col-sm-offset-1″><button type=”submit” class=”btn btn-primary”>Send invitation</button>

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


    Single Page Application tutorial

    After watching the video on YouTube on the Single Page Application wizard I became curious and decided to take a test and mobilize an application myself. I choose the infamous “fake names” application for this.

    I have written a blog article/tutorial about it. Here you can read it: ‘Single Page Application Wizard‘.


    With the Single Page Application control you can rapidly mobilize a Notes application. The wizard is intuitive although you need to understand some basics of mobile development.

    Unfortunately the wizard is not complete and forces you to apply some coding.

    Infinite Scroll

    The infiniteScroll property for a Data View control is enabled by default in the Singe Page Application. This great new feature allows users to fetch new rows of data by scrolling down the list.

    You are almost stupid if you disable this feature.


    • Ability to apply basic CRUD Tab Bar Buttons to a Document Viewer Application Page.
    • On a Document Viewer page it would be easier to add fields instead of removing most of all the fields that would otherwise be applied by default. In mobile apps the number of fields you want to display is probably less than in a Notes client application.
    • Ability to re-open the wizard after you have pressed ‘Finish’.
    • It would be great to have message popups when a user performs an action that he/she is not allowed to do. At the current stage there is default no mechanism for this. Examples: “You are not authorized to perform this action”, “You have insufficient access rights”.




    Presentations from EntwicklerCamp 2012 available

    I have experienced that IBM has some problems linking to their material that lies out in the open, but I hope this post does not cause the same kind of trouble. I also know the solution in case needed: contact the content publisher to remove the files…

    Nevertheless Entwicklercamp sounds like a excellent technical conference and for those of you who have no problems with reading a bit of German (not all presentations are in German, by the way) here are some interesting presentations:

    Track 0 – Session 1 – Eröffnungssession – Rudi Knegt (link)

    Track 0 – Session 2 – Opening Session – Phil Riand (link)

    Track 0 – Session 3 – Speeddemoing – Diverse (link)

    Track 0 – Session 5 – Closing Session: Ein (grausamer Selbstversuch) – 5 Monate ohne Lotus Notes – Werner Motzet

    “Ein (Arbeits-)Leben ohne Lotus Notes” / “Ein (grausamer Selbstversuch) – 4 Monate ohne Lotus Notes” (link)

    Track 1 – Session 1 – XPages – 1 – Grundlagen – Ulrich Krause (link)

    Track 1 – Session 2 – XPages: Practical Ideas for Converting Existing Notes Applications – Matthew Fyleman (link)

    Track 1 – Session 3 – XPages – 3 – eXtension Library – Viagra für die XPages – Ulrich Krause (link)

    Track 1 – Session 4 – XPages – 4 – IBM oneUI + MyTheme = myUI – Manfred Meise (link)

    Track 1 – Session 5 – XPages – 5 – Wie mache ich meine XPages Applikationen ‘social’? – Niklas Heidloff (link)

    Track 1 – Session 6 – XPages – 6 – XPages Extensibility API – going deep – René Winkelmeyer (link)

    Track 1 – Session 7 – Zähme den Tiger – Java-Entwicklung in Notes und Domino – Bernd Hort (link)

    Track 1 – Session 8 – XPages – 8 – Nutzung des Dojo Toolkits zur Optimierung bestehender Notes-Web-Anwendungen – Matthias Bierl (link)

    Track 2 – Session 1 – Extending Lotus Notes – Widgets, Livetext, Plugins – Detlev Poettgen (link)

    Track 2 – Session 3 – Agile Softwareentwicklung mit LotusNotes – Werner Motzet (link)

    Track 2 – Session 4 – Ich weiß was du diesen Sommer tun wirst – Gregory Engels (link)

    Track 2 – Session 5 – Erfolgreiches Projektmanagement mit agilen Methoden – Christian Habermueller (link)

    Track 2 – Session 6 – Make the impossible possible with XPages – Frank van der Linden (link)

    Track 2 – Session 7 – Connect your Lotus Notes app to the Activity Stream with XPages – Frank van der Linden (link)

    Track 2 – Session 8 – Keine Angst vor großen Tieren – Peter Klett (link)

    Track 3 – Session 1 – Rediscover the Power of LotusScript in Notes/Domino 8.5 – Rocky Oliver (link)

    Track 3 – Session 2 – Die besten Open Source Projekte von OpenNTF – Niklas Heidloff (link)

    Track 3 – Session 3 – Richtig(er) Kommunizieren! – Wie bringe ich meine Botschaft rüber? – Jürgen Kunert (link)

    Track 3 – Session 4 – XPages und Domino App Dev Erweiterungen – Phil Riand und Niklas Heidloff (link)

    Track 3 – Session 5 – Turbocharge Development in Notes/Domino 8.5 – with @Formulas! – Rocky Oliver (link)

    Track 3 – Session 6 – Mobiler Zugriff auf Notes Daten – Matthias Schneider (link)

    Track 3 – Session 7 – Es gibt keine Ausreden mehr – eGit im DDE : Versionskontrolle leicht gemacht – Holger Chudek (link)

    Track 3 – Session 8 – Using the XPages Mobile Controls… and looking at alternatives – Rich Sharpe (link)

    Track 4 – Session 1 – Security in Notes – Manfred Meise (link)

    Track 4 – Session 2 – Workflow – Richtig analysieren, dokumentieren und schlüssig hinterfragen – Christian Habermueller (link)

    Track 4 – Session 3 – Lotus Protector programmieren – Matthias Schneider (link)

    Track 4 – Session 4 – WebServices unter Notes/Domino – Tim Pistor (link)

    Track 4 – Session 5 – Hilfe, ich habe geerbt! – Bernhard Köhler (link)

    Track 4 – Session 6 – NoSQL-Datenbanken – ein Überblick – Karsten Lehmann (link)

    Track 4 – Session 7 – Notes und die Zeit – Bernhard Köhler (link)

    Track 4 – Session 8 – Schnittstellendesign mit dem Tivoli Directory Integrator – Am Beispiel SAP – Andreas Artner (link)

    In case you are a bit lazy or dont care about bandwidth: <here> you can find the presentations archived together by track…

    There are also some hands-on sessions available:

    Hands-On 1 – Javascript – die ersten Schritten – Manuel Nientit (link)

    Hands-On 3 – XPages – the first Steps 1 – Howard Greenberg (link)

    Hands-On 4 – XPages – the second steps 2 – Howard Greenberg (link)

    Hands-On 5 – Signierung und Verteilung von Plugins für den Notes Client – Detlev Poettgen (link)

    Hands-On 6 – LotusScript – so einfach geht es los – Peter Klett (link)

    Hands-On 7 – Mobiler Zugriff auf Notes Daten – Matthias Schneider (link)

    Hands-On 8 – XPages Extensibility API – first steps – René Winkelmeyer (link)

    Btw, all links were collected from this source.

    Working with LinkedIn in XPages – People Search

    Here is another example for accessing LinkedIn’s API’s in XPages. This example contains code for performing a people search within your network.

    I will include the example later in the next release of LinkedIn controls.

    <?xml version=”1.0″ encoding=”UTF-8″?>
    <xp:view xmlns:xp=”;
    xmlns:xc=”; createForm=”false”>
    <title>LinkedIn JavaScript API Sample Application</title>
    <xc:ccLinkedInAPIKey key=”//your  domain key here”></xc:ccLinkedInAPIKey>
    <script type=”IN/Login”></script>
    <xp:scriptBlock id=”scriptBlock3″>
    <xp:this.value><![CDATA[function PeopleSearch() {
    // Call the PeopleSearch API with the viewer’s keywords
    // Ask for 4 fields to be returned: first name, last name, distance, and Profile URL
    // Limit results to 10 and sort by distance
    // On success, call displayPeopleSearch(); On failure, do nothing.
    var keywords = dojo.byId(“#{id:searchBox}”).value;
    .fields(‘firstName’, ‘lastName’, ‘distance’, ‘siteStandardProfileRequest’)
    .params({‘keywords’: keywords, ‘count’: 10, ‘sort’: ‘distance’})
    .error(function error(e) { /* do nothing */ }
    <xp:scriptBlock id=”scriptBlock4″>
    <xp:this.value><![CDATA[function displayPeopleSearch(peopleSearch) {
    var div = document.getElementById(“peopleSearchResults”);
    div.innerHTML = “<ul>”;
    // Loop through the people returned
    var members = peopleSearch.people.values;
    for (var member in members) {

    // Look through result to make name and url.
    var nameText = members[member].firstName + ” ” + members[member].lastName;
    var url = members[member].siteStandardProfileRequest.url;

    // Turn the number into English
    var distance = members[member].distance;
    var distanceText = ”;
    switch (distance) {
    case 0: // The viewer
    distanceText = “you!”
    case 1: // Within three degrees
    case 2: // Falling through
    case 3: // Keep falling!
    distanceText = “a connection ” + distance + ” degrees away.”;
    case 100: // Share a group, but nothing else
    distanceText = “a fellow group member.”;
    case -1: // Out of netowrk
    default: // Hope we never get this!
    distanceText = “far, far, away.”;
    div.innerHTML += “<li><a href=\”” + url + “\”>” + nameText +
    “</a> is ” + distanceText + “</li>”
    div.innerHTML += “</ul>”;


    <h1>Find People on LinkedIn</h1>
    <xp:inputText id=”searchBox” defaultValue=”xpages”></xp:inputText>
    <xp:button value=”Search” id=”button1″>
    <xp:eventHandler event=”onclick” submit=”false”>
    <div id=”peopleSearchForm”></div>
    <div id=”peopleSearchResults”></div>

    Custom control ccLinkedInAPIKey you can find in the LinkedIn controls project.

    Without any styling your result could look something similar like this: