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!