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 🙂

Where are we?

Today I received a question on a post I wrote some time ago. I had to start up my local development environment just to see if I remembered where I placed the code that was asked for.

So where are we? Or what are we doing?

Still Domino. Still XPages. But then mainly in Java. The story about application development with XPages that IBM did NOT tell you. Why? You may tell.

I was thinking about gathering my past experience and ideas and combine it into a ‘product’ but workload and a private life with small kids is preventing me from this.

OpenNTF? Naaa. Too tired.

CU at Engage? Probably not (I am a developer and development sessions are scarce).

CU at GraphConnect? Good chance!

This blog? Yes, probably some new posts soon.

Something in the pipeline? Yes, tomorrow a presentation for colleagues on using Java in XPages development.

For now: time to watch some CL football 🙂

Capture

Quick responsive type-ahead function

For an XPages form I needed a workaround for a combobox with a large data-set. At first I tried the select2 jQuery plugin so I could also have a filter option as some form of type-ahead. However it turned out that my select2 list became quiet unresponsive when an entry far in the list was selected (generating the list and filtering was fine).

So my next option was to go for a type-ahead approach. First hit on Google was a NotesIn9 vid about a fancy type based upon the original post of Tim Tripcony (hello 2009).

Due to the large data-set instead of the getAllEntriesByKey method I decided to go for a getEntryByKey method and from the found view entry continue with createViewNavFrom. This turned out to be extremely responsive!

Further I noticed in the original code a hash object is used so that does not guaranteed me a correct order of my result list so I added an additional array, just for a returning a list with correct sort order.

I like especially in this approach the option to control the returned markup so think here about Bootstrap Media object lists. And of course the ease to set the value that you want to have returned in the edit box.

This is not my first blog-post on delivering search function to your application so now you have just another solution available for your toolbox.

The script is available as a gist.

Happy development =)

 

Get rid of “Infinity” as the result of a @DbColumn in a combobox – Quicktip

Who has not experienced the following:

XPages has a 32 or 64 ( can’t remember which ) limit for the lookup formula whereas in Notes the limit is only for the whole of the formula e.g. after @unique is applied.

It makes it very hard to have meaningful drop downs for filtering data.

Instead you can use SSJS e.g.:

var lookupView:NotesView = database.getView(“<LOOKUPVIEW>”);
lookupView.getColumnValues(0)

This is the equivalent to:

@DbColumn( “”,”<LOOKUPVIEW>”, 1 );

and returns you the full result without the limit.

But this also brings me to the following problem:

When I enable Select2 on a loooong combobox the list is populated the type-ahead / filtering works fine BUT when I select a value long down the list the response of the select2 combobox becomes really sloooow.

Does anyone has an approach to this?

Display JSON pretty in a textarea control

In an application I am using heavily JSON default as the data-format. To make debugging a bit more easy I am working on a toolbar to be able to check the content of the JSON objects.

Normally I use JSONLint most of the time to prettify (and validate) the JSON so it becomes a bit easier to read and check. But this copy and paste habit becomes more and more obnoxious so there I wanted to have a toolbar (like the debug toolbar) to have a good overview of the JSON objects.

However if you write the JSON object to a computed field or text area field (inputTextarea control in the XPages world) it is just plain, unformatted text. Not pretty for the eye and not much helpful for the brain.

So I tested a simple approach which turns out to run just fine. I display the json object in a textarea input control and then with CSJS I format the content. Here is some sample code:

<xp:inputTextarea id=”input-fieldx” defaultValue=”#{javascript:App.currCollection}”>
</xp:inputTextarea>
<xp:button value=”Make Pretty” id=”button1″>
<xp:eventHandler event=”onclick” submit=”false”>
<xp:this.script>
<![CDATA[var name = x$(‘#{id:input-fieldx}’).attr(“name”);
prettyPrint(name);]]>
</xp:this.script>
</xp:eventHandler>
</xp:button>
<xp:scriptBlock id=”scriptBlock1″>
<xp:this.value>
<![CDATA[function prettyPrint(id) {
var obj = dojo.byId(id);
var ugly = obj.value;
var json = dojo.fromJson(ugly);
var pretty = JSON.stringify(json, undefined, 4);
obj.innerHTML = pretty;
dojo.setAttr(id,”rows”,10);
}]]>
</xp:this.value>
</xp:scriptBlock>

Here is what it looks like:

json-before

The content how it looks initially.

json-after

The content how it looks like after running the code.

Note I had to include the [ ] signs in my code to make the JSON valid due to circumstances in my code, I removed it from the sample code above.

At least now I understand my JSON objects again and I can avoid some copy and paste to JSONLint 🙂

This is probably my last blog of this year so I would like to wish you some wonderful Christmas days. Take care and best wishes for a healthy 2017!

 

 

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 🙂

I am a certified Graphista

Sweden has many IT solutions to be proud of. I assume you are using/have used Spotify or Skype.

Perhaps you are not aware but another “Swedish” product you might have been using is Neo4j, a graph database management system. Graphs are all around us. Typical use cases are recommendation systems, fraud detection and social networks.

You can also make your IBM Notes data more ‘connected’ by using the Graph DB capabilities available in the OpenNTF Domino API.

I chose to walk the easiest path to learn about Graph data modelling and that was to learn the probably most documented, described, leading Graph Db: Neo4j. After a while I felt comfortable with all the terminology, concepts and programmatic use so I felt confident to take the test to become a Neo4j Certified Professional.

And voila!, here is the result:

neo4jcertificate

The test was harder than expected, the time pressure was significant and some subjects out of scope of my experience (administrator experience in a Production environment) but with logic and wishful thinking I came to a positive result 🙂

So far I have not read too many use-cases where IBM Notes data was used within Neo4j or applications written in XPages using the graph db of Neo4j. But what is not is yet to come…

 

Adventurer

I have always known that I am an adventurer. My Lotus/IBM Notes career started as a adventure into an international professional working-experience and the people who know me will probably say that it will be very hard to make an ordinary “9 to 5” office guy out of me.

I could never resist the call of the trail – Buffalo Bill

So far about me as person. The occasion of this post are several calls in the community to take a look at Salesforce as an application development platform.

So I took the time to take a look at it to find out if it would be of interest of me. As suggested my journey started with Trailhead. My journey, so far has lead me to finish the developer beginner trail.

I will write about my first experience and will not do any comparison, simply because my knowledge on Salesforce is limited to do so.

If you read this trail description it tells you it will take you up to 15 hrs and 45 minutes. Well I can tell you: it took me much more time. There is a LOT of text to read, video’s are  included and there are challenges to complete modules and to earn points for badges. A challenge can be a list of questions or an exercise.

So let’s assume all the effort and time-investment does contribute to your understanding of the platform.

Before starting, a couple of developers told me about the similarities with Notes and XPages and I have to say it is nice to recognize that building XPages applications have brought Notes developers closer to genuine application development (as far as it compared with Salesforce).

Salesforce biggest ugliness at start is of course it is not NonSQL as Notes is.

A nice feature is Salesforce web enabled development interface. I have not come to the Eclipse IDE yet. I have used the classic web interface, since in Trailhead the examples and screenshots are from the classic interface. I can not say I am in love with a web interface since I noticed some genuine lags compared to the XPages IDE (autocomplete for example). Also getting into read mode after performing a save action I found annoying.

I admit there are similarities programming in Salesforce compared to Notes and XPages, but I guess this comparison is similar with other programming languages. When it regards to building custom user interfaces Visualforce reminds me a lot about XPages.

So after completing this first trail I find the learning curve not that steep. Using Trailhead is just very time-consuming. An instructor or video-learning would have been much more time efficient. But if you want to gain some deep knowledge it doesn’t hurt to spend time on the approach.

A quote I heard is that Salesforce is the platform Notes should have been (if IBM would have prioritized it more) and that there are many more goodies to be found in the trail Develop for Lightning Experience so I am looking forward to take another hike. Ofcourse with my newly earned Adventurer badge on my backpack 🙂