Fixing the Tooltip function in XPages

A colleague noticed that the tooltip function on a Xpage stopped working after submitting the page to the server and when the validation did not pass. The same behaviour occurred when I added a computed text control that would spit out an anchor reference using a tooltip. Odd.

I found an old post of mine where I described the use of the xe:tooltip control. This control seems to keep working even when the XPage fails to validate. So that is a win.

However, in my case I would have to apply the control on many places which does not make me happy.

I also wanted to alter the layout of the tooltip a bit via a template so I found this piece of code. To my delight I noticed that the tooltip also kept working after a failed validation!

So a simple bit of code can fix tooltip again:

So after applying a template for the tooltip and applying some CSS my tooltip looks a bit more readable and less boring:

Note that I have to set the xp:this.title property for the inputTextArea control. Adding an additional attribute for the placeholder won’t do for the template.

RAD Table walker

For a project I received some very unclear description for a change. After a conversation I came up with the suggestion to rebuild the UI and present a Bootstrap table with add and delete buttons. Something what developers would call a table walker.

So how did I do this?

First I had to extend the Model object of my MVC model. The table repeats rows with persons details so I added:

The Person class is simplified as followed:

On my model object I also added getters and setters and and an add method:

Then I had to build the table with the following important elements:

  • a repeat control to represent my arraylist of Person objects
  • input fields bounded to the Person name and email
  • a button for each row to remove the Person from the arraylist
  • a button to display a new blank row to register a new Person

The code is not that long or complicated. I highlighted the important parts with bleeding yellow:

In the next phase I decided to replace the input field the name field with namespickers (by first name or by last name) wrapped as Bootstrap field add-ons. Here is the rough code:

This all resulted in a nice BS table with add / remove buttons:

Now I am just waiting for customer approval. That is mostly the longest part in Rapid Application Design.

Data for Bootstrap Treeview from a Notes View?

In a modernization project (increase of browser compatibility) I needed to find a solution for a list of links, categorized and sorted like a Notes View.

Since I already use Bootstrap as CSS framework I decided to check the following Bootstrap Treeview project: https://github.com/jonmiles/bootstrap-treeview .  I was satisfied with the following example(s):

treeview_ex.png

The initialisation is pretty simple:

snipp01

Now I just needed to set up a REST service to provide me the data. The service is setup on an XPage and bounded to a Java class:

snipp02

The Java class I will reuse for providing multiple data streams so it detects the different method parameters:

snipp03

As mentioned the data for the list comes from a Notes View. As you all know views entries have different characteristics which I have to bear in mind:

  • Documents can land anywhere in the view since it is categorized on a text field where the multiple levels can set individually eg Europe\\Sweden\\Stockholm or Afrika\\Johannesburg.
  • The view also holds links for other menus organized under a category so I decided to us a viewnavigator and start collecting data from a specific category.
  • For each entry in the view I have to check what type it is: category, document or total. The last one is not of my interest so I have to skip if that option occurs.
  • The columnindentlevel tells me all about where I am in the view in comparison with the columnindentlevel of the previous entry. Here are the scenarios:

// case 1: current indent level < columnindentlevel
// -> new category, propobably start situation
// case 2: current indent level = column indentlevel
// -> new category (sibling) but close the previous
// one first (just one level)
// case 3: current indent level > column indent
// level -> new category but closes the previous
// one(s) first. how many depends on difference curr
// and column level

Ofcourse categories behave different that documents.

So here is the code:

serv01.PNG
serv02
serv03.PNG

Some notes:

  • I have set the header of the REST service to text/html and the plugin needs a JavaScript object. Therefor capture my data response in an eval() method.
  • A target attribute is not provided by the plugin, so I add one myself. Categories have the # as href so based on that info I include a target attribute or not. I do this via a function:
snipp04
  • If the treeview is collapsed there is no anchor element for underlying list-items so you cannot add the target for all links.
  • Also when collapsing and expanding a category the added target attributes are gone. So for opening of every category you need to re-apply the href attribute for underlying anchors.
  • A category can be opened via a ‘twistie’ image or the text link so we need to register an action on these onclick events
snipp05
snipp06

The result is a nice looking ‘Notes View data-driven’ treeview with Bootstrap styling:

snipp07

Happy coding 🙂

PS. I noticed I have a lot of unused local variables in my code, you may clean that up 🙂

Workaround for updating the styleClass property of a button when using BS theme

In my application I am using the Bootstrap theme that comes with the extension library. In the application I have a button with which I want to enable/disable the appearance of the debugtoolbar plugin for the end-user so it will be easier to handle incident reports when they should occur.

So in my application layout control I added the toolbar and compute the appearance:

debuglayout

Now somewhere in my application I have in a dialog a button to show/hide the debug toolbar:

debugBtn In the browser it looks as followed:

debugDlg

At first when I pressed the button the styleClass would update ONLY when I totally refreshed the page which was undesired.

The trick here is to disable the theme for the button:

debugTheme

I then have to surround the button with additional HTML span element:

<span class=”btn-group”><xp:button…/></span>

As a result the button changes styleClass correctly:

debugSwinging.JPG

Want to know more about XPages dev item? Just drop a question below…

A generic approach to display Notes data via a Bootstrap table

This week I became inspired by a question I noticed on Stackoverflow regarding collecting values from Java objects.

For a project we were discussing what to use for display “Notes View data”:

  • jQuery DataTables plugin and use a customRestService via a Java class as data provider for the JSON.
  • a Repeat control and display an Arraylist of Java objects.

Some of the participants liked the jQuery approach because it provides a lot of functionality out of the box (sorting, search, responsiveness,…) and their lack in knowledge regarding Java.

Others were questioning of the Repeat control approach would be flexible enough so we could display easy different sets of data with different number of columns.

So… to the drawing board.

Mostly in Notes views (e.g. via the View Panel control) one column serves as link (often the first) and all others just display data of all kind. In the DataTables plugin the display is flexible because you can define a custom render function for each column which is great. So you could display a button that will call a dialog to interact with the underlying document for example. However this custom render definition resides in a CSJS library so becomes part of the design.

I had already a custom control that could consume properties for the data and how to set a fixed set of columns. So the last part I needed to make flexible.

Because I have an arraylist of Java objects as source for my Repeat control I need to access the fields “on the fly” when rendering the column values. This turned out to be quiet simple because the fields are already in my Java object.

In my approach I provide the columns via a JSON object that could look as followed:

dyntable00

 

And for my columns I repeat it and collect the value from my underlying Java object:

dyntable01

Note: my code is not final, I would to define more types of data and the option to provide a custom render function for each column. So far I only have computation for string and date fields.

I also applied some basic functionality as Pager controls (top + bottom), a Page Sizer control, icon display and row numbering.

Here is what a result might look like:

dyntable001

Nothing special but now now I have just one custom control to display 80% of my tables/views.

Here are the GIST files for the custom control and its configuration xml file.

IBM Champion Nomination

Is this blog-article useful to you? Perhaps you can nominate me as IBM Champion.

XPages sufficient for line of business type of applications?

Hi there, currently I am following another Angular course since it seems to have become the leading development framework at work. So back to learning all the rules within Angular.

At the moment I am modernizing a Domino application with the help of XPages which:

  1. Implements Model-View-Controller architecture, mostly inspired by the guys at Pipelia since IBM never told us to do so.
  2. Is written in Java to support the MVC architecture and to have close integration with XPages runtime.
  3. Is using Expression Language wherever possible to avoid usage of SSJS.
  4. Uses the lifecycle of JSF in XPages at the max.
  5. To cover support for different devices I am using Bootstrap as front-end framework. So I miss some native behavior which I do not tend to cover-up.

So far so good and I think I have come quiet long in my project so I still dare to call it rapid application development.

The code-base has been reduced dramatically and all exotic upcoming JavaScript libraries from the early 2000 I have been able to replace with just XPages. With my latent UX skills and extending the out of the box Bootstrap I might now even call this application ‘sexy’ 🙂

I know I haven’t touched many areas discussed in the XPages community such as:

  • Websockets (I do not see a use-case yet).
  • Writing Java servlets (please pass me a demo NSF).
  • Watson services (cloud is still a sensitive topic).
  • set up micro-services with smartNSF and consume them in my Java code with an mapper library (requires changes in the environment).
  • Integration with IBM Connections.
  • Redefining my data with the help of a Graph DB.

Either I see little usage, it is not possible or there is no-one to guide me (the information is certainly not provided by the vendor).

So now back to Angular. Learning all these rules, technologies and new tools setup I was wondering what new technical options this framework will bring me at work. Reflecting on the type of customer-orders I receive I am wondering:

Is XPages not sufficient for most of your line of business apps?

Perhaps you have a though about this?

Happy development & enjoy your summer 🙂

Nice reversible cards in a IBM Verse style

In an application I am displaying objects with cards. Because the type of objects may differ in type and amount of data (text, images, tables, dates) the cards to display them differ.

Some cards have interaction (popup, dialogs, reversible) and some are just static. In this post I will discuss the reversible card type.

The reversible card has as features:

  • a front card with a folded corner, if you move over the fold an info icon appears which you can click to see the card’s back.
  • when you flip over to the back or front it is all nicely animated.
  • on the back of the card there is another icon to switch back to the card’s front.

The purpose of this reversible card is to save space in my UI, and to provide layout for secondary information, which is more important if you want to look at more detailed information.

It could also be a placeholder for data that, when placed in the front of the card, ask for too much landscape (e.g. a chart).

Things become much clearer with images so here are a few:

card-default

Image: Default presentation.

card-mouse-over-fold

Image: Expand folding (animation) when mouse-over.

card-flipped

Image: animation when flipping over a card.

card-back

Image: the back of the card.

I use the cards within a repeat control and with Bootstrap they align nicely and are responsive:

cards

I have no idea when Bootstrap 4 will be released with it’s card component but according to my experience cards are … less useful without interaction.

I made a small video to demonstrate the reversible cards feature:

If you want to implement the card yourself here is the code:

card-code

Most of the chemistry is performed with CSS so you also want that:

body{
padding:20px;
}

.flip {
-webkit-perspective: 800;
perspective: 800;
position: relative;
text-align: left;
min-height:200px;
margin-bottom:20px;
}

.flipped {
height: 100%;
background-color:#efefef;
-webkit-transform: rotateY(-180deg);
transform: rotateY(-180deg);
}

.card {
height: 100%;
-webkit-transform-style: preserve-3d;
-webkit-transition: 0.5s;
transform-style: preserve-3d;
transition: 0.5s;
}

.card .face {
-webkit-backface-visibility: hidden ;
backface-visibility: hidden ;
z-index: 2;
}

.front {
/*position: relative;*/
background-color: #FFF;

height:200px;
position: absolute;
width: 100%;
z-index: 1;
border: 1px solid #e3e3e3;
box-shadow: 5px 7px rgba(0, 0, 0, 0.15);
transition: background 0.4s ease;
}

.front-content, .back-content {
padding: 20px;
}
.front-content:before {
content:””;
width: 80px;
height: 80px;
float: right;
}
.corner-tip:before, .corner-tip:after {
background-color: #FFF;
position: absolute;
display: block;
z-index: 2;
border-top-right-radius: 60%;
width: 50%;
height: 50%;
content: “”;
}
.corner-tip:before {
right: 100%;
top: 0%;
background: -webkit-radial-gradient(-180% 200%, circle, rgba(255,255,255,0) 80%, rgba(0,0,0,.2) 100%);
}
.front:hover .corner-tip:before {
border-right: solid 1px #fff;
}
.front div.corner:hover .corner-tip:before {
border-right: solid 2px #fff;
}
.corner-tip:after {
top: 100%;
right: 0%;
background: -webkit-radial-gradient(-250% 320%, circle, rgba(255,255,255,0) 80%, rgba(0,0,0,.2) 100%);
}
.front:hover .corner-tip:after {
border-top: solid 1px #fff;
}
.front div.corner:hover .corner-tip:after {
border-top: solid 2px #fff;
}
.corner { /* edit these sizes for the default revealing corner size */
height: 20px;
width: 20px;
right: 0;
top: 0;
position: absolute;
overflow: visible;
}
.front:hover .corner { /* edit corner size (First animation, when the whole page is rollovered) */
height: 30px;
width: 30px;
}
.front div.corner:hover { /* edit corner size (Second animation, when the corner itself is rollovered) */
height: 50px;
width: 50px;
}
.corner:before {
position: absolute;
top: 0;
right: 0;
content: “”;
display: block;
width: 133%;
height: 133%;
}
.corner-contents:after {
position: absolute;
top: 0;
right: 0;
content: “”;
background: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0) 37%, #DDD 62%, rgba(230, 230, 230, 0.1) 64%, rgba(255, 255, 255, 0) 67%), -webkit-radial-gradient(-50% 150%, circle, transparent 74%, rgba(0, 0, 0, 0.2) 74%, transparent 81%);
display: block;
width: 133%;
height: 133%;
}
.corner-tip {
position: absolute;
top: 0;
right: 0;
content: “”;
background: -webkit-linear-gradient(45deg, #ddd 17%, #dfdfdf 18%, #f5f5f5 30%, #f8f8f8 34%, #eee 39%, rgba(200,200,200,0) 41%);
display: block;
width: 100%;
height: 100%;
}
.corner-button {
position: absolute;
top: 0;
right: 0;
color: #fff;
text-align: center;
padding:5px;
display: inline-block;
font-size: 1.6em;
color:black;
}
.corner-contents {
width: 125%;
position: absolute;
display: block;
overflow: hidden;
-webkit-mask: -webkit-linear-gradient(45deg, transparent 49%, #000 53%);
top: 0;
right: 0;
height: 125%;
}
._corner-contents:before {
content: “”;
position: absolute;
top: 0;
right: 0;
content: “”;
display: block;
width: 100%;
height: 100%;
background-color: #eeeef4; /* Match this background color to #fpc_effect-back */
}
.corner, .corner-contents, .corner-tip {
-webkit-transition-property: all;
-webkit-transition-duration: .3s;
-webkit-transition-timing-function: cubic-bezier(0, 0.35, .5, 1.7);
}

.back {
height:200px;
width: 100%;

-webkit-transform: rotateY(-180deg);
transform: rotateY(-180deg);
border: 1px solid #e3e3e3;
box-shadow: 5px 7px rgba(0, 0, 0, 0.15);
transition: background 0.4s ease;
}

.imgThumb{
width:66px;
height:66px;
}

.card blockquote {
border-left: none;
margin: 0;
}

.card blockquote img {
margin-bottom: 10px;
}

.card blockquote p:before {
content: “\f10d”;
font-family: ‘Fontawesome’;
float: left;
margin-right: 10px;
}

Okay, you are now all powered to impress your customers. Happy development 🙂

Bootstrap Greenhouse

I collected some code examples for plugins to Bootstrap in XPages in a GitHub project so I have them for convenience stored in one place.

bootstrap-greenhouse

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 !

I Like Bubble Commenting

Strange subject title isn’t?

I have created a repository of my bubble/social speech layout, so if you want to have a closer look and implement it yourself then you are free to go.

I updated the @mention implementation so you get a nice icon in front of the name:

mention20

In order to have icons I updated my LotusScript agent to add a URL to an image in the PhotoURL field of the Person form in the FakeNames.nsf. For now I stored the icons in the NSF but in case you have a directory you use the reference to images from there.

I have also added an updated version to Like/Unlike comments, in stead of SSJS now most of the logic resides in the LikeController class. When you hover over the icon you get a list presented with people who have liked the comment.

likes_hover_icon

Ofcourse nothing is stress-tested but I have not seen major issues so far. I hope you like it and get inspired to modernize your IBM Notes applications !

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 !