Show / hide columns dynamically

To show or hide columns dynamically is a nice feature in the jQuery dataTables component. With a few simple steps you can deliver something similar in your XPages application as I demonstrate in the video.

The technologies used: XPages, Extension Library, Bootstrap.

Add 20 years of experience to your workforce

You can 20 years of experience within IBM Notes and Web development to your workforce by hiring me.

Interested? Read my curriculum vitae on LinkedIn: http://www.linkedin.com/in/patrickkwinten and get in contact.

I am happy to work WITH you !

FlipSwitch style for your checkboxes

A flip switch is an alternative look for a checkbox or the two-option select menu. It can be toggled by a click or a swipe.

flipswitchoff

I am not sure if it’s originated from mobile interfaces, at least it is there where they are most common. So if you modernize an application and optimize it for mobile access you might consider adding flip switch behaviour to these form elements.

Here is an example how to do this with XPages:

htmlswith

 

Ofcourse you have to provide the CSS. The CSS depends on your theme. There are handy sites that might help you with it.

Here is my CSS:

.onoffswitch {
position: relative; width: 90px;
-webkit-user-select:none; -moz-user-select:none; -ms-user-select: none;
}
.onoffswitch-checkbox {
display: none;
}
.onoffswitch-label {
display: block; overflow: hidden; cursor: pointer;
border: 2px solid #999999; border-radius: 20px;
}
.onoffswitch-inner {
display: block; width: 200%; margin-left: -100%;
transition: margin 0.3s ease-in 0s;
}
.onoffswitch-inner:before, .onoffswitch-inner:after {
display: block; float: left; width: 50%; height: 30px; padding: 0; line-height: 30px;
font-size: 14px; color: white; font-family: Trebuchet, Arial, sans-serif; font-weight: bold;
box-sizing: border-box;
}
.onoffswitch-inner:before {
content: “ON”;
padding-left: 10px;
background-color: #34A7C1; color: #FFFFFF;
}
.onoffswitch-inner:after {
content: “OFF”;
padding-right: 10px;
background-color: #EEEEEE; color: #999999;
text-align: right;
}
.onoffswitch-switch {
display: block; width: 18px; margin: 6px;
background: #FFFFFF;
position: absolute; top: 0; bottom: 0;
right: 56px;
border: 2px solid #999999; border-radius: 20px;
transition: all 0.3s ease-in 0s;
}
.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-inner {
margin-left: 0;
}
.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-switch {
right: 0px;
}

I hope you find this tip useful…

flipswitch

 

Add 20 years of experience to your workforce

 

You can 20 years of experience within IBM Notes and Web development to your workforce by hiring me.

Interested? Read my curriculum vitae on LinkedIn: http://www.linkedin.com/in/patrickkwinten and get in contact.

I am happy to work WITH you !

Draggable modal

For a project a request was to make a Bootstrap modal (a Dialog control in the Extension Library) as draggable. By default, the modal does not have that feature. So can you make it draggable again?

In xsp-mixin stylesheet the class xsp-responsive-modal is using !important for the left and top properties which prevents that the modal is draggable. A work-around can be achieved by replacing these class properties with your own that does not use !important.

To replace the default class add for the onShow event of the dialog:

<xe:this.onShow>
<![CDATA[
x$(“#{id:dialog1}”).removeClass(“xsp-responsive-modal”).addClass(“draggable-responsive-modal”);
]]>
</xe:this.onShow>

Your custom class could look as followed:

.draggable-responsive-modal {
display: block;
width: auto;
left: 0;
top: 0;
z-index: 1050 !important;
}

The x$() function is the infamous utility function from Mark Roden to work with JQuery.

I added the code to GitHub Gist: https://gist.github.com/PatrickKwinten/1d442e28ff0d59f8e01728bffab13e4f

Add 20 years of experience to your workforce

 

You can 20 years of experience within IBM Notes and Web development to your workforce by hiring me.

Interested? Read my curriculum vitae on LinkedIn: http://www.linkedin.com/in/patrickkwinten and get in contact.

I am happy to work WITH you !

Question: Is it possible to set via a resource via a theme so it is applied to any XPage in an application?

I received a question if it is possible to set (or add) a resource via a Theme resource so it will become available to any XPage or Custom control?

Yes ofcourse you can e.g. via:

<resource>
<content-type>text/css</content-type>
<href>custom.css</href>
</resource>

but you should keep in mind is that a Theme is ONLY applied in the Render Response phase. So if for example you include an SSJS library to the Theme, you will not be able to use it in the beforePageLoad or afterPageLoad event. A mistake that is common made.

My recommendation would therefor be to use a Theme more for applying default settings or to overwrite properties to a specific type of component, e.g. a default pageName property on the ViewRoot component.

In terms of adding resources I would advice to use a Custom control design element. SSJS that will be computed dynamically only run once per page load / refresh in a theme (just in Render Response), compared to every phase of the lifecycle in a Custom control.

Happy development =)

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.

 

 

 

Building a search function with DataTables plugin

Introduction

In Domino you have multiple options how to provide a search function for an application. I have seen many examples where a FT search query is build for a database, where the form type is defined, which fields should be used in the search etcetera. Most of them are a maintenaince nightmare, layout is little flexible and usability is lacking (e.g. perform a search towards a query which will result in zero hits).

What if you make it easier to maintain, more flexible for user specific desires and add facetted search principles? A win situation?

DataTables

In the following posts I will write how to use the jQuery DataTables plugin to provide a quick search function for your Domino apps. I assume you use XPages.

Stage 1 – Getting & presenting the data

In the initial stage we just try to get and present the data we need. As example I will be using the FakeNames application. I have created a public repo which has at the moment:

  • an xpage to present the data (dtPersons.xsp)
  • an xpage (api.xsp) which will contain rest services
  • a Java class that generates the data in JSON format
  • a CSJS library to transform the HTML table on dtPersons.xsp to  DataTables object
  • the required resources from DataTables.net
  • a Theme resource to have the resources available
  • a Notes view to use as data source.

In order to create some fake documents I have set up an LS agent to do so.

If you bind this all together, you have already a search function:

datatables01

Right on top you have a search field where you can query the columns in the table. The columns are sortable too. Probably it is matching most of the search functions you have seen for Domino. But wait! There is more possible…

 

JavaScript Internationalization & placeholders

Introduction

Some time ago I wrote about moving a Teamroom application up to IBM Bluemix. This month the XPages runtime is now general available.

In the post I mentioned I would come back on some design gotchas I saw while analyzing and preparing the Teamroom application for staging it to Bluemix. So here is (at least9 a first post.

What I noticed for example was the usage of the l18n library in SSJS and placeholders in properties files.

i18n formatting

This is a server script library with methods to format messages for localization, display dates in a locale-specific manner and miscellaneous Internationalization utilities.

So how does this works?

Create two or more strings properties file e.g.

  • strings.properties
  • strings_sv.properties

The strings.properties file content:

compliment=Handsome

hello.world=Hello {0}

The strings_sv.properties file content:

compliment=Snygging

hello.world=Hejsan {0}

Now create an XPage and place e.g. a Computed Field control on it and calculate it’s value:

<xp: text><xp: this.value><![CDATA[#{javascript:compliment = strings.getString(“compliment”);

return i18n.format(strings.getString(“hello.world”), compliment);}]]></xp: this.value></xp: text>

(Do not forget to enable Internationalization for your application in the Application Properties under section International Options)

Placeholders

Notice in the properties file the usage of a placeholder: hello.world=Hello {0} and how it is being referred: strings.getString(“hello.world”), compliment. Here the variable compliment (another string property value) is put in the placeholder.

As a result in the default language I get returned “Hello Handsome” and when I choose Swedish as default language in my browser I get returned “Hello Snygging”.

By wrapping it and formatting it with the L18n library you ensure it is fitted according the active language. This is very handy for dates, amounts etcetera.

Links of interest

More details about JavaScript Internationalization can be found in the IBM Notes Domino Application Development wiki.

 

Questions and Answers from deploying a Teamroom application on Bluemix

Introduction

write once, run everywhere

Thise WORE slogan is used often in cross-platform solutions, also in IBM Domino. But what if you move your XPages application from an on premise Domino installation to the cloud, more specific IBM Bluemix?

Teamroom

To gain some experience in this area I decided to take a well known application, IBM’s Teamroom and deploy it on Bluemix. I will spare you the details of creating a Bluemix account, setting up Domino Designer, deploying the Design application and binding it to a XPages NoSQL Database service. I will focus on adapting/preparing the Design of the XPages application and some areas I have not found an answer for (yet).

First consideration – Choose your data-binding

bluemixContext

Bluemix requires the separation of design and data so if you haven’t use this principle your applications yet, you must apply it now. Second, Bluemix will allow you also to run your XPages application in a mixed environment (part cloud / part on-premise) so if your application will do so the bluemixContext object will let you identify where your application is running and point to the corresponding data NSF.

DAO Bean

In my case the Teamroom application would only run in Bluemix so instead of applying bluemixContext.getDataService().findDatabaseName() I prefer to use Oliver Busse’s daobean which I have been using in other applications as well. This allows me to use the shorter dao.getDbpath() for xp:dominoDocument and xp:dominoView data-binding.

Remember: in the Teamroom design you need to set this property for every Document and View binding!

<xp:this.databaseName><![CDATA[#{javascript://bluemixContext.getDataService().findDatabaseName()
dao.getDbpath()}]]></xp:this.databaseName>

Use the search function in DDE to locate where these bindings are used.

Valuepickers

Value pickers are used throughout the Teamroom application and for the dataProvider property you need to calculate the location of the database.

Search after dataProvider and you will get the list of design elements where they are used. Look for the once who use the xe:dominoViewValuePicker since they are using a View as data-source. Again make the database location computed.

Addressbook

Some dataProviders use xe:dominoNABNamePicker and the location of the server is set via the Teamroom Setup function, which asks for the web server address. Default the web server address where the design resides is filled in. I tried to fill in the ip address of the server where the data resides (gathered via dao.getServer()) but this still did not allow me to open an NAB.

@dbcolumn @dblookup

What is an XPages application without the @dbcolumn and @dblookup functions? Use DDE to allocate in which design elements there are used and exchange the @DbName() function with bluemixContext.isRunningOnBluemix()? bluemixContext.getDataService().atDbName():@DbName or dao.getServer()+”!!”+dao.getDatabase()

database object

With the database object is you can make a quick reference to the NotesDatabse class, and so it is used throughout the Teamroom application. Mind a database.isFTIndexed() to check if the search bar will be displayed or not? Again do your search in DDE.

You can apply method chaining e.g. dao.getDatabase().isFTIndexed()

Run form validation

I noticed that I had to disable the option to validate the saving of documents using form validation (on document save option). Otherwise the operation failed silently.

Changing form name

Adding a team member via the browser resulted in a document created with the form reference of Team Member Profile   –   ParticipantProfile. If you add a member via the Notes client the form reference will be ParticipantProfile. This explains why newly created members did not appear in the list at first.

So I modified the form name as:
<xp:dominoDocument formName=”ParticipantProfile” …

I also set this alias as first in the Notes form. Not sure if that is necessary.

Wrap-up

So far so good. So how “Bluemix ready” is my Teamroom and what are my first thoughts?

Except the lookup to the name and address book I pressume my Teamroom is working as normal. I guess you can call this is major issue.

The tag cloud is not working, but that is due to the fact that the  xp:tagCoud control does not provide a database property (yet). Again I would call this a major issue.

Looking at the design of the Teamroom and counting the number of design elements I would think the development team has made the application design too complicated. I think the power of custom controls and property definitions is that you can re-use them in complete other ways and so reduce the amount of design elements.

I also notified almost no Java code in the design. Perhaps adding some classes for the objects can also reduce the amount of design elements dramatically. Also the application might get less spaghetti coded with logic stored in a central place.

Going through the code resulted in some new “discoveries” and was therefor fun to do. I will write another post about the things I haven’t used before.

Happy development and looking forward to next week’s Engage =)

 

 

Resource optimization for Anonymous users

The ‘Use runtime optimized … resources’ is a great XSP Properties property to downsize the amount of calls to the Domino server for downloading stylesheet and javascript resources.

In order to reduce the size of the download(s) the rendered property in a Theme design element can be handy.

For example resources that are used in Xpages that are not accessible by Anonymous users you can initially restrict via:

Screen Shot 2016-03-08 at 12.15.01

When they later logon and access XPages that use the resource, it will be available.

Just a simple tip. Happy development =)

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 =)