19 May 2015 Tuesday

XPages: Create Code39 Barcodes

Hi Folks,

a couple of weeks back a customers asked me how to do Barcodes in XPages as they needed them in their application to be printed to a document scanning system. After looking into the application, I realized that they had been using a Code39 barcode font in Notes previously to create barcodes in the Notes Client. So I went looking for an alternative for XPages and eventually came across Code39.js, a small JavaScript library that was able to do the trick. The JS library can be found here: http://www.lutanho.net/

For a quick sample, I just created a new CSJS library in an empty database and pasted the code from above into it. Then, additionally, I had to add the two gifs to the images resources:

Image:XPages: Create Code39 Barcodes

Both files are part of the zip package, you can download from the link above.

My sample XPage has an Input Control to enter text and a Script Block to show the code39 of the text the user enters:

Image:XPages: Create Code39 Barcodes

Here's the sample Code of the XPage:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">

             <xp:script src="/code39.js" clientSide="true"></xp:script>
     <xp:panel id="outerPanel">
                                     <xp:label value="Have a say !" id="inputLabel"></xp:label>
                                     <xp:inputText id="inputToCode39" defaultValue="Something to say" value="#{sessionScope.MyInput}"></xp:inputText>
                                     <xp:button value="Refresh !" id="button1">
                                             <xp:eventHandler event="onclick" submit="true"
                                     <xp:label value="Your say in Code39"
                                     <xp:panel id="outputPanel">
                                             <xp:scriptBlock id="scriptBlockCode39">
                                                     <xp:this.value><![CDATA[var text_entered = document.getElementById("#{id:inputToCode39}").value;
if(text_entered==null) {
     text_exntered = "Please enter some text !";


This is a very simple example to do the job. If you want to try out the live sample - here it is:  


regards, Heiko.
Heiko Voigt   |   19 May 2015 14:00:00   |    xpages  javascript  domino  barcode    |   Comments [4]

Hi again,

for the last couple of months my guys from SIT GmbH and Harbour Light have been working on an integration solution for Domino E-Mail into Adobe AEM. The Use Case is to enable E-Mail for intranet solutions of our customers, based on Adobe AEM. Our goal was to create an E-Mail Framework that would be extendible to other platforms (talking 'bout you, Exchange!) and that would be able to utilize a flexible UI to get adapted to the look and feel of our customers implementations easily.
And - we have done just that. The next screenshots show you a lightweight E-Mail Client that can be customized to any functional needs and esthetical requirements in a specific customer situation.

This Screenshot shows the inbox and the folder structure we have implemented.

Image:The voyage of IMPRISIS continues - IMPRISIS DA integrates Domino Mail with Adobe AEM

We also have fulltext search working:

Image:The voyage of IMPRISIS continues - IMPRISIS DA integrates Domino Mail with Adobe AEM

And finally, this is what an email can look like using IMPRISIS DA.

Image:The voyage of IMPRISIS continues - IMPRISIS DA integrates Domino Mail with Adobe AEM

In these Screen shots, we use a bootstrap theme as our basis for the UI but this can be changed to whatever framework is necessary. We deliver a JavaScript API that exposes the high-level functionality of the backend email services to the AEM components so any AEM component developer can alter the components or can create his/her own ones based on our APIs. The API also abstracts Single Sign On (SSO) headaches from the component developer as SSO can be configured centrally on an AEM instance using our IMPRISIS SSO Components and if needed our Secure Token Service IMPRISIS STS.

Right now, we are in beta with the E-Mail Services of IMPRISIS DA, next are Calendaring Services. Stay tuned !

Links & Resources:

[1] SIT GmbH
[2] Harbour Light Software Development Ltd.
Heiko Voigt   |   5 May 2015 14:15:00   |    Adobe  AEM  Domino  IMPRISIS    |   Comments [0]

Hi there,

it's been a while since my last coding post but over the past rainy weekend, I had a bit of time on my hands to build an XPages App that shows marker data coming from a Domino Database as Markers on an interactive map. I was looking for an open source solution, so after some research, I came across the beautiful JavaScript library leaflet.js (see resources [1]) and a very well done Tutorial on it (see Resources [2]). Leaflet is using OpenStreetMap data (Resources [3]), so you don't have to rely on Google or any other data provider and you can (and should) support this great project directly !

Attached, you will find a sample database that outputs something like this: https://sitlux02.sit.de/XPMapSample.nsf/Map.xsp

Image:XPages: Interactive Maps using OpentStreetMap and Leaflet.js

The Use Case:

In this sample, I want to show points of interest on a map, These are stored as Notes Documents in the database, containing a tilte, a type definition (Point of Interest or Accommodation) a description, longitude and latitude and a link to the specific url for the POI.

How it has been built:

A) The Bean:

To serve the data to leaflet, I use JSON as the data format of choice. The JSON data gets created by a request scope bean within the database. I don't use the built in rest services because I want to have full control of the JSON data that gets created. The bean exposes a method called getMarkerData() that will go into a view in the database, reads the entries and spits out JSON. To test the output, there's also an XAgent in the database (getMarkerData.xsp) that will return the marker data. Of course I have to bring the definitions into faces-config.xml.

<?xml version="1.0" encoding="UTF-8"?>
<managed-bean id="Markerdata">
<!--AUTOGEN-START-BUILDER: Automatically generated by IBM Domino Designer. Do not modify.-->
<!--AUTOGEN-END-BUILDER: End of automatically generated section-->

As I use the ExtLib, I also have to check it in the xsp.properties.The source code of the bean can be found in the Code/Java section using Domino Designer.

B) The UI:

The UI is rendered in the Xpage called "Map.xsp". It loads the leaflet.js library via...

<xp:headTag tagName="script">
            <xp:parameter name="type" value="text/javascript" />
            <xp:parameter name="src" value="leaflet.js" />

...to be loaded before Dojo kicks in and creates a mess. Thanks for that great tipp to Sven Hasselbach (see Resources [4]). The leaflet.js is stored as a file resource in the database.
Then, I also have to load the leaflet.css and my own client side javascript library to glue everything together:

<xp:styleSheet href="/leaflet.css"></xp:styleSheet>
<xp:script src="/leafletembedd.js" clientSide="true"></xp:script>

The rendering of the map is done using one DIV -Tag in the Xpage:

<div id="map" style="width: 99%; height: 600px"></div>

To talk to our Bean, I also injected a JSON-Rest-Service-Object:

<xe:jsonRpcService id="jsonRpcService1"
                    <xe:remoteMethod name="getMarkerData">
                            <xe:this.script><![CDATA[var liste = MarkerData.getMarkerData();
return liste;]]></xe:this.script>

This basically exposes the getMarkerData()-Method of the bean to client side javascript.

I want to show different markers for different types of POIs  on the map. If it's a real POI it should show a red marker, if it's a motel or other accommodation type, it will show a blue marker. To do that, I can define Icon classes for leaflet, and I do so in the leafletembed.js CSJS-Library.

blueIcon = L.icon({
iconUrl: 'marker-icon.png',
shadowUrl: 'marker-shadow.png',

iconSize:     [19, 48], // size of the icon
shadowSize:   [25, 32], // size of the shadow
iconAnchor:   [11, 47], // point of the icon which will correspond to marker's location
shadowAnchor: [4, 32],  // the same for the shadow
popupAnchor:  [-3, -76] // point from which the popup should open relative to the iconAnchor

redIcon = L.icon({
iconUrl: 'marker-icon-red.png',
shadowUrl: 'marker-shadow.png',

iconSize:     [19, 48], // size of the icon
shadowSize:   [25, 32], // size of the shadow
iconAnchor:   [11, 47], // point of the icon which will correspond to marker's location
shadowAnchor: [4, 32],  // the same for the shadow
popupAnchor:  [-3, -76] // point from which the popup should open relative to the iconAnchor

As you can see, the Icons are PNG files (see image resources in the sample database). If you have more than two, you would create a base class for the icons and extend from that to keep the code more sustainable of course.

The library has a function called initMap that will get called in the onClientLoad event of Maps.xsp. InitMap also defines the starting point for the map and the zoom level:

// start the map in Shelburne, Nova Scotia
map.setView(new L.LatLng(43.7612695, -65.3226),10);

Then, I grab our marker data from Domino using the function "askForPlots". In the function askForPlots, I call the JSON Rest Services using a callback:

// request the marker info
markerList = fetchMarkerData.getMarkerData();

and add the markers where I distinguish between the icon color, based of a value in the JSON data coming from the service. I also attach a pop up to each of the markers showing the title and the url in this sample.

typ = plotlist[i].Type;
(typ==("POI")) {
    console.log("--> POI !");
    plotmark = new L.Marker(plotll,{icon:redIcon});
} else {
    console.log("--> Acommodation !")
    plotmark = new L.Marker(plotll,{icon:blueIcon});
}                                }

C) Summary:

As always - here's my default disclaimer:

Yes, there are a ton of ways to do this more efficiently. My code may be bloated or inefficient for some of you out there. My goal is to get the idea across - go ahead and improve the sample and send it back to me at hvoigt AT sit.de, I'm happy to learn.

Now the real summary.

It took me three hours from scratch to get this sample up and running. I'm impressed by leaflet.js that IMHO is a great tool to work with as well as by the flexibility of the XPages runtime to really let you do new stuff in a fast and easy way. Everytime I am able to do something like this, I simply don't get, why IBM does not recognize this gem in its portfolio and instead let's us create crippled widgets for a crippled app platform like Connections.

This sample is a first start on how to work with maps but it can easily be extended on all ends. The backing bean gives you for example the opportunity to have only the design of the app in a publicly accessible database and grab the data from another secured database using sessionAsSigner functionality.
Leaflet offers a ton of features, APIs and Plugins to create interactive maps for various use cases. What I personally like is that it does not bring any other dependency to the table e.g. you don't have to fire up jQuery to make use of it. The CSJS Lib gives you some hints on how to attach to events on the map - with that, you can pass values to the service bean and get the marker data for the specific region in the map only. You can extend the marker icons and the content in the pop up and the look and feel by altering the CSS.... . So, lot's of potential.

That's it for today folks, have fun !

Resources and Links:

Heiko Voigt   |   4 May 2015 11:37:00   |    xpages  javascript  OpenStreetMap  Leaflet    |   Comments [2]

22 April 2015 Wednesday

The new me after Social Connections 8

Hi there,

first of all a big "Thank you !" to the team around Social Connections 8 last week in Boston. It was a great event, great talks and a great crowd in Boston ! We had a good audience for our speech about using IBM Connections as a social business middleware and I will always remember the lively discussions with Phil Riand at the party on thursday night.

As a speakers gift, we have been given caricatures of ourselves and I have to say I like mine, so meet the new me below:

Image:The new me after Social Connections 8
I haven't seen Patrick's yet - but it simply cant be that good looking, eh ?!

Thanks again to the team of Social Connections for a great conference !

Heiko Voigt   |   22 April 2015 15:30:46   |    Adobe  Connections  AEM  CQ5    |    [0]

Logo Social Connections

So folks,

after a very successful IBM ConnectED in Orlando in January, I'm happy to say that we will be presenting at Social Connections VIII in Boston in April. In conjunction with Harbour Light Ltd. we will be demonstrating our experience in using IBM Connections as a social business middleware. By that, we are talking about using REST APIs of Connections to create components in a Web CMS that are able to leverage IBM Connections functionality in a fully customizable UI without the pain of modifying the Connections UI itself.
"Hit it like you mean it !" became the refrain for us when it comes to the Connections REST APIs - we show you why and how we worked our way through the features and shortcomings of the API. In our presentation "Playing LEGO with IBM Connections" we also demonstrate the beautiful UI options that we came up with - and yes, we will show code as well !

Please check out the Agenda and our session here !

We are glad to be part of the group of presenters at Social Connections VIII which really features a great lineup this year ! See you all in Boston and stay tuned for more integration components withIBM Software and Adobe AEM !

Heiko Voigt   |   26 February 2015 12:49:46   |     |   Comments [0]


our friends over at Harbour Light have posted a new video on their integration product IMPRISIS CA that integrates IBM Connections and Adobe AEM.
It shows how to extend a customized social intranet based on Adobe AEM using social components from IBM Connections.


Heiko Voigt   |   7 January 2015 10:16:30   |    Adobe AEM  IBM Connections  IMPRISIS  Harbour Light    |   Comments [1]

23 December 2014 Tuesday

2014 - a year in transition

Image:2014 - a year in transition

So this year is almost done and it's the time to look back on what happened over the past months.
Businesswise, 2014 was a year in transition for me. With SIT in Germany, we started to become a reseller of integration products for Adobe AEM, sold our first IBM Connections Integration products and did our first projects in that space. It was quite challenging and a huge learning curve for us, but with social rendering we seem to have found a new niche to persue over the next couple of years.

In the Notes/Domino space of our customers, the move to XPages continued, both based on our portal solution SIT Portal DXP as well as with individual development projects. Meanwhile, we have a whole arsenal of tools to easily migrate existing applications, integrate search capabilities, "bean bags" for office and workflow integration, etc. We are heavily using Bootstrap to develop responsive solutions and extended the knowledge on all of the new tooling within the team as we also got cross-referenced technologies from Adobe AEM like Angular.js, OSGI Bundles and a lot more.

Personally, I have spent a lot of time in the project management arena, also transitioning from the groupware space to a new world for me: for one of our financial sector customers I was working as IT project manager in a host development project for the whole year working with teams that mainly use COBOL and Assembler as their tools of the trade. It was a good experience and I am glad to say that we finished a 1500 person days project within time and with 15% less budget than planned, so I'm pretty happy. The team was great and I was able to gain a lot of knowledge in a totally different segment of our industry.

My biggest venture this year though was the creation of Harbour Light Software Development Ltd. as our first toehold in north america. Building up a new team in a new country, setting up an organization that hopefully will be fully operational in 2015 was a big challenge with so many other things to do. But what a great experience ! I'm happy to take this venture further next year. With new products coming out (IMPRISIS DA is almost around the corner), we will hopefully be able to make a footprint in the americas as well.

Our transition from being a pure IBM partner to a more broader approach in technology as well as in partnering has payed off. We did not present at DNUG or in any other ICS Event this year altough Connect 2014 was a great event for us in building new relationships. We did present on some Adobe Events though, AEMHub in London and CONNECT Web Experience in Basel. Both events were very perfectly organized and well attended. Fun all the way.

We also stayed in touch with the IBM part of the house as part of the Design Advisory board for IBM Mail.Next or IBM Verse respectively. I am really looking forward to ConnectED 2015 to see more around Verse, although I'm a bit disappointed about the sessions announced so far. I can't see the increase of technical content so far - it's a smaller venue and less people will attend which doesn't have to be a bad thing, but I'm afraid that IBM looses traction even further in the ICS space where for all of my customers the cloud and bluemix are not of interest at all. IBM Verse is a heavily discussed topic but the long time to wait for the on-prem version is discouraging a lot of my customers. I hope that IBM will be able to climb out of the hole and not dig it any deeper than it already is.  
Btw - climbing out of the hole - I did well receive the signs that my favorite smartphone company BlackBerry is slowly slowly on the way out of the hole again. Personally, I love my Passport and Blend in particular and some old and some new customers are coming back and are listening to the strategy John Chen was able to build around BES12 and the new products. It's going to be a log haul - keep it up, BlackBerry !

Looking back into our own backyard, we had a very busy year indeed. We had more billable hours per person as ever before, more projects in parallel and more diverse customers than ever. We finished new versions of your core products, extended our reach with new technologies and built a new product line, all in one year. So it has been a really stressfull year for all of us and my team worked it's fingers to the bones, and it's about time for me to say a big "thank you" to my guys here at SIT GmbH for the tremendous support, the great work this year and the patience and trust in the management team in this transition phase. Keep up your passion and your customer-first attitude and we will see a great 2015 !

Finally, a big thank you goes to all of our customers, old and new for the trust and good partnership in various projects throughout the year. We are blessed with brilliant people at our customers so it was easy for us to deliver the results they expected from us. We are in a people's business and people make the difference on both ends of the project table. Thank you for the support and trust - we are looking forward to new challenges in 2015.

To all of you out there - merry Christmas, happy new year and a peaceful, happy and healthy 2015 !

Kind regards,

Heiko Voigt   |   23 December 2014 12:00:00   |    review  domino  xpages  adobe    |   Comments [0]


every couple of months, I see companies in the high tech industry (that are building hightech products themselves) struggle with work arounds for self signed SSL certificates that somehow "magically" made their way to productive systems. One special case in that row of stupidity are traveler servers. Even a moron of an admin can install and configure them, install a self signed ssl certificate and pull it out into the public. And then put the IT-Directors phone on it. And it works. Him (being the great IT Director) tells all his management colleagues that own 650,- $ Smartphones from Samsung or Apple by the dozens, how easy it is to hook up to traveler. And all of a sudden, the Poc Server of our moron admin becomes the production server that has to be available all the time.
Now, someone in the IT Department tells the admin to ask for wildcard ssl certificate that would cost the same as an upper class smartphone for a year - guess what happens: the IT-Director denies the money. Too expensive. Works fine now, eh ? Why bother ?
And of course the stupidity continues on like that - can't we send our email to our provider via SSL using a self signed certificate ? Yay, that works as well ! A great step forward for your mail safety. Until someone from outside the company starts sending mails about how to buy viagra and much nastier stuff via your providers email server in your name because your provider still trusts self signed certificates that pretend to be you. Outrageous !
Does our moron admin know about this ? Well, it depends. He starts to think that something is fishy here, when emails don't get delivered to external mail domains any more. Because your domain is skyrocketing the spam lists. Then, all of a sudden, you can't send any mails anymore, because your provider stops accepting your self certified ssl certifikate. And you IT director doesn't get his latest invitation to a golf tournament anymore. Oh boy, we are so f****d up !
Sounds familiar ? Well, we got called to three different companies who acted like this in this year alone. Guess who got fired for that chain of desasters ? The ISP that accepted the self signed certificates for mails in the first place because the customers asked them to, no begged them on their knees to not let the company die because of the high-priced SSL Certificate.

Repeat after me - you get what you pay for.


P.S.: One of these companies is now moving their mail to Gmail. Needless to say they are developing high tech products and send beta designs from their customers back and forth by email. They have signed NDA agreements for those design betas because their customers don't want third parties not to see them. But man, it's that cheap, how can you possibly go wrong ?! And we got rid of our moron admin as well, because our secretary can manage the email accounts now, how cool is that ?!
Heiko Voigt   |   1 August 2014 18:05:14   |    SSL  Domino  Traveler    |    [0]


While working on an Xpages Workflow Engine of one of our customers, I came across a requirement to do backend field validations in SSJS. As the field validation is done via the workflow engine, we were not able to use standard validators. The engine was able to do this already and would eventually spit out validation errors based using addFacesMessage() and a default Error Messages Control.

The fields to check for are defined in the workflow step definitions. In there, I added not only the field names to check but also to corresponding ids from the XPage controls to that definitions. Now, the workflow engine does the validation on fields and attributes and returns a list of ids that are invalid that are stored in a session scope variable for the sake of simplicity. We will be moving this to a bean sometime in the future. To highlight the fields now, I use an additional attribute in the xpages controls that I call "highlighted":

Image:SSJS Field Validation and highlighting of fields without standard validators

This computes a value of "1" if it's part of the invalid ids list and "0" if not. Like this:

try  {

var me:javax,faces.component.UIComponent = this;
var myID:String = me.getId();

var invalidFields:String = myBean.getInvalidFieldListAsString();
if(invalidFields) {

if(@Contains(invalidFields,myID) {
return "1";
} else {
return "0";
} else {
return "0";
} catch (e) {
return "0";

To actually highlight the fields, I dynamically change some CSS style values in the onLoad Event by selecting all the nodes with an attribute value of highlighted="1" using dojo.query() like this:

nodeList = dojo.query("[highlighted]");
nodeList.forEach(function(node) {
  try {
    var value = node.attributes["highlighted"].value
    if (value=="1") {
            dojo.setStyle(node, "background", "lightyellow");
            dojo.setStyle(node, "border", "2px solid red");
  } catch (error){

I then set background color and border color respectively. The cool thing about this is that I can also highlight a group of fields by putting them in a separate panel an adding the "highlighted" attribute there as well. I only need to hook up the field to validate with the id of a specific panel. the result looks like this:

Image:SSJS Field Validation and highlighting of fields without standard validators
Heiko Voigt   |   24 July 2014 16:23:26   |    XPages  SSJS    |   Comments [0]


just a quick tipp - I was looking for a solution on how to launch attachments in an XPINC application without downloading them first and eventually came up with a solution. My problem was, that I had multiple attachments in the documents I had to deal with. The attachments were Office documents, PDFs and even MP4 video files, so a wide range of formats.

The basic idea behind my solution is to use a notes:\\\ Link to open the corresponding Notes Document from my XPINC app and let LotusScript handle the process of launching the attachment. My only problem was how to let LotusScript know, which attachment I wanted to launch. One idea was to create temporary documents and to use the launch first attachment functionality, but I did not want to create and delete additional documents.

So, here's what I came up with in a nutshell: Environment variables. Still remember them ? Yeah, back in Notes 2 and 3 they were huge, but they are still around and guess what - even XPages can work with them. So, to handle my attachments, I created a repeat control for a table, that lists all the attachments in the Notes backend document as one table row. This look like this:

Image:Launch Attachments in XPINC app (Windows only !)

This is the SSJS to select all my attachments for the repeat control:

var alist = document1.getAttachmentList("Body");

if (alist.isEmpty()) {

     return null;

} else {

     var alisti = alist.iterator();

     var names = new java.util.Vector();

     while (alisti.hasNext()) {

             var content:String = alisti.next().getName().toString();



     return names;


The control renders a link for each attachment showing its name. The link contains an onClick-Event that takes care about creating the notes:/// link to the document itself and to set an environment variable with the name of the attachment to launch. I use the view.postscript construct to redirect to the notes document, this automagically opens in a new notes window.

Here's the code for that, "docs" is my variable from the repeat control that carries the name of the attachment, document1 is the document datasource:

var aname:String = docs.toString();

var replid = database.getReplicaID();

var baseurl:String = "

var url:String = baseurl+"?OpenDocument&AttachmentName="+docs.toString();



In Notes, I have used the ShellExecute command - I remebered the shellexec.lss of Julian Robicheaux, you can find it here: http://www.nsftools.com/tips/WinTips.htm

So, in the Notes Document, I used the QueryOpen Event to launch the attachment and stop the Notes Document from opening - et voilà !

Image:Launch Attachments in XPINC app (Windows only !)

Here's my code in the query open event:

Sub Queryopen(Source As Notesuidocument, Mode As Integer, Isnewdoc As Variant, Continue As Variant)

     On Error Goto fehler

     Dim doc As NotesDocument

     Dim obj As NotesEmbeddedObject

     Dim aname As String

     Dim AgentArgs List As String

     Dim db As NotesDatabase

     Dim s As New NotesSession

     Dim result As Long

     Dim rtitem As Variant

     Set db = s.CurrentDatabase

     Set doc = Source.Document

     aname = s.GetEnvironmentString("CurrentAttachment")

     'Msgbox "File: "+aname

     Set rtitem = doc.Getfirstitem("Body")

     If (rtitem.Type = RICHTEXT) Then

             Set obj= rtitem.GetEmbeddedObject(aname)

             aname = "c:\windows\temp\" & aname

             Call obj.Extractfile(aname)

             result = ShellExecute(0, "open", aname, "", "",1)        

     End If

     Goto raus


     Msgbox Error$+" at line: "+Cstr(Erl())

     Resume raus


     continue = False

End Sub

As always - there are tons of ways to do this better/easier/with less code - let me know. I have been looking around for some time now and this is the best I came up with so far.

Happy coding !

Heiko Voigt   |   3 March 2014 12:54:59   |    Notes  XPAGES  XPINC    |    [0]