IBM Connect 2017 – I will be speaking in San Francisco

I will be speaking at IBM Connect in San Francisco now in February. Rob Novak has resurrected "The Great Code Giveaway" and asked me to present it together with him. Who would turn down that opportunity? So some time between February 21 and 23 you can see Rob and me on stage at Moscone West. The exact time and location has not been announced yet. I hope to see you in San Francisco and that you will find our presentation and code useful!

1 Comment

New life for “old” technology

A few weeks ago I visited the town of Antigua in Guatemala for 5 days. My wife used to live in Guatemala, working for a non-profit organization back in the late 1990's, and she wanted to show me how beautiful the country is. Of course my wife was absolutely right. The town was colorful and relaxing, people were very nice and the food was delicious. When I in the past heard "Guatemala" I thought of rain forests and hot and humid conditions. But in Antigua the temperature was perfect, about 70° F (21° C) during the day and 55° F (13° C) at night. We slept with open windows every night, with a view of one of the nearby volcanoes. No need for air conditioning, we could just enjoy the clean fresh air. But what is really amazing is how resourceful people in Guatemala are. They reuse things in a very clever way, with the most striking being the "chicken bus", the local transportation system between cities. When American school buses get old they are sold at auctions for a couple of thousand dollars. Many of them are purchased by Guatemalans who drive them down through Mexico to Guatemala. There they are fitted with upgraded powerful diesel engines (often the same ones used to power semi-trucks), repainted and outfitted with additional lights (sometimes neon lights), roof racks for cargo and plenty of chrome. Often they get a new hood from a semi-truck as well. The US truck manufacturer International used to have a truck manufacturing plant in Guatemala, but it was closed down some years ago. This left the country with an abundance of very competent mechanics, especially diesel engine mechanics. They are now passing their knowledge on to the next generation. On an interesting note, IC Bus, one of the major manufacturer of the yellow American school buses, is a division within International and the school buses share much of the design with the International trucks. And this is what the end result looks like:   https://youtu.be/TuLDmSo24NY So what does this have to do with IBM Notes and Domino, you may ask? Well, the same way as you can take a boring and generic workhorse like a yellow school bus and give it a second life by converting it into a colorful and useful source of transportation, you can modernize and update your old and perhaps a bit dated Notes application to something new exciting and attractive that your users would like to use. Take your Notes application from this: To this modern web application: Just like the mechanics in Guatemala replaces the old worn-out engine with a new powerful truck engine, your Domino data engine can be replaced with a new engine, for example from LDC Via, if you want to get away from Domino as a server platform. But Domino is a very competent and powerful NoSQL database/server and will work well for most users. So like old worn out yellow school buses, your Notes applications can be given a…

2 Comments

IBM Notes, Domino and the future

As some may already know I was recently laid off after 14 years as a Notes and Domino developer at my workplace. I suspected for a while that some staff reduction would be coming soon, but I was a bit surprised that I was included since I am the only Notes developer in the company. I had for a while considered to do consulting and freelance development. My wife as well as several friends have been encouraging me for years. So this was just the push I needed. I am starting my own company, Demand Better Solutions, where I will focus on Notes and Domino Development, application modernization and migration as well as building brand new web applications and websites. I realize that me being laid off is just a business decision. It is not personal. Several of the business critical applications at my former employer are developed using IBM Notes, but the executives have for years been talking about moving away from the platform. Of course they don't realize the huge amount of work needed to do this, but never the less this was/is their ultimate goal. The reason is that they feel (based on what they hear from other executives) that Notes is old technology. The fact that IBM has been slow in modernizing the interface, and that many of the templates still look like back in 1999 when version 5.0 was released does not help this perception. Last fall all our email at my old job was moved to Outlook, and ever since I have heard users complaining about missing Notes and certain functionality they were used to. A lot of integration between Notes applications and Notes mail were also lost, and I had to re-create it in different ways. You often hear stories about people complaining about the Notes client, but most of our users wanted nothing but to get it back... My old employer also uses Visual FoxPro, a product where the last version was released in 2004. It has officially been discontinued by Microsoft, but we use it for several important applications. So I don't think that even a product being discontinued is driving a huge number of migrations. It is the perception of how modern the product is that matters. And that perception is almost 100% the way the product looks. To a user the interface is the product. Create a modern looking application and nobody will question (or care) what tool was used to build it. The last 3-4 years I have been learning new web technologies, like jQuery, Bootstrap, Ajax, JSON. I have been able to use much of that at work, as well as in several side projects. I also started learning C# and .net. After the layoff I sat down and started looking at (among others) php and mySQL as well as researched frameworks like AngularJS. As a developer I have to keep up with new technologies, or I will be left behind. But it is hard when you work full-time, have side work and then have…

2 Comments

IBM extending support of Notes & Domino

IBM today announced that support for IBM Notes and Domino 9.0.1 have been extended until September 30, 2021, five years from now. Like many others I would have liked to see IBM use the wording "at least until 2021", but I am sure IBM's lawyers have something to do with this. It is important to notice that this is not an end-of-life announcement, At the same time IBM also announced that they now will start shipping new features for the products in the Notes and Domino product line without changing the version number like before. In the past only bug fixes were shipped between version in so called "fix packs". Any new features had to wait until a new version was released. But recently some new features have been added as well, causing some confusion. In the future IBM will shift to more frequent updates , using the name Feature Packs. Many cloud offerings don't even do version numbers anymore (what version of Gmail are you using?), and Microsoft is doing the same thing with Windows 10, pushing out new features within the same version number. Also today IBM announced Fix Pack 7 (FP7), probably the last fix pack version before the name change to Feature Pack. It can be download as of today. You can read more about what is new here. In an upcoming feature release IBM is expected to update the JVM to Java 8, as well as add new functions needed for Verse on-promises which is planned for release at the end of the year.    

0 Comments

My MWLUG presentation

I have been very busy ever since the MWLUG conference in Austin, but now you can finally view my presentation and download the sample code. Enjoy!   I will post the code for my Phonegap Demo next week. Reminder: you need to sign the database (or at least all the agents) with an ID who has the rights to run agents, or the Ajax calls will not return anything. If you are interested in having your Notes applications modernized and moved to the web, feel free to contact me at karl-henry@demandbettersolutions.com.

0 Comments

Updated MailNotification class – Now with HTML email support and web links

I have updated my MailNotification class with some additional functionality I needed at work. Since our mail system now is Outlook/Exchange, and therefore the Notes doc links don't work anymore, I am in the process of converting all my email notifications into HTML email. The doc links are now made into HTML links, pointing to a notes:// or http:// address. I simply added a new class, HTMLmail. It is based on the old NotesMail class, but I override a few functions that are different. This makes it very easy to update the emails I am generating in my Lotusscript agents, in most cases I only have to replace NotesMail with HTMLmail in the declaration and instantiation: Dim maildoc As HTMLMail Set maildoc = New HTMLMail() When I had doc links in the email I also had to modify the code where I generate it. The method takes three arguments: the NotesDocument to link to, the Alt/Title attribute for the link (to be displayed when hovering over the link) and the text of the link: Call maildoc.AppendDocLink(doc,"Click to open",doc.ClaimNumber(0)) In order to generate the links I created a Link class, where you can set what protocol you want to use ("notes" or "http") you want the link to use, you can change the port from the default of 80, and you can even force the link to point to a different server. I use this class in the AppendDocLink method in the HTMLmail class. Here is a short code sample, it is just a function to create a mail notification for an insurance claim. The claim document is passed to the function and a mail is sent to the adjuster and his/her manager. Sub SendNotification(doc as NotesDocument) '*** Create a new object and set the sender, recipients and subject Set maildoc = New HTMLMail() maildoc.Principal = |"System Notification" <noreply@example.com>| Call maildoc.AddMailTo(doc.GetItemvalue("Adjuster")(0)) Call maildoc.AddMailCC(GetManagerName(doc.GetItemValue("Adjuster")(0))) maildoc.Subject = "30 DAY ALERT - " & doc.GetItemValue("ClaimNumber")(0) '*** Build body content, including a link to the document Call maildoc.AppendText("Claim number ") Call maildoc.AppendDocLink(doc,"Click to open",doc.GetItemValue("ClaimNumber")(0)) Call maildoc.AppendText(" was received on ") Call maildoc.AppendText(Format$(doc.GetItemValue("Received_Date")(0),"mm/dd/yyyy") & ". ") Call maildoc.AppendText("This claim has been opened for 30 days. ") Call maildoc.AppendText("Please confirm all appropriate actions has been performed.") Call maildoc.AddNewLine(2) '*** Add no-reply notification to the end and send the email maildoc.NoReply = True Call maildoc.Send() '*** Flag the NotesDocument as processed and save it to avoid duplicate notifications doc.Warning30daySent = "Yes" Call doc.Save(True,True) End Sub That's pretty much it.  Enjoy the code, and as usual I do not guarantee anything. Use on your own risk, as always. If you like this code and use it, let me know. Option Public Option Declare Class NotesMail Public maildoc As NotesDocument Public body As NotesRichTextItem Private p_subject As String Private p_sendto List As String Private p_copyto List As String Private p_blindcopyto List As String Private p_principal As String Public NoReply As Boolean Public mailbox As NotesDatabase Public Sub New() Dim session As New NotesSession Dim mailservername As String ' We must use mail.box on current server. mailservername…

2 Comments

Review – Ytria consoleEZ

Recently I wrote about the great customer service I received from Ytria, and that made me realize that I haven't been writing about one of their newer tools yet. The tool is consoleEZ, and it has actually been out for over a year. A new version was recently released. As the name indicates, it is a Domino server console on steroids. You can load a number of consoles into one window, have them neatly tiled and get a great overview of what's happening on your servers. Just like all other Ytria tools it runs in it's own process, which means that it does not lock up your Notes, Administrator or Designer client. This is of course very convenient. Each console window has a field where console commands can be entered. A nice feature here is auto-complete/type-ahead. You also have a drop-down button that will give you any previous commands you sent to any console, it does not have to be the one you are working on. And the commands are saved, as opposed in Domino Administrator where you lose your command history when you close the client. You can also launch a task viewer, where you can see what tasks are running on a specific server. It updates every 3 seconds, so you can stay updated for example on views being updated, somethings I sometimes need. I would highly recommend consoleEZ for any Domino administrator, as well as for the more advanced developer who need to see what's happening on the servers. Contact Ytria for a current price quote in you region.  

3 Comments

Some upcoming conferences

IBM Connect is not the only conference that you should attend if you are interested in the IBM collaboration/social platforms, there are many other spread out over different continents, and many of them are even free. You just pay your travel and hotel. Next one up is Engage (formerly BLUG) arranged by Theo Heselmans and his team. This year it takes place in Eindhove, the Netherlands on March 23-24. There are less than 20 seats left for this free event with world class speakers, many of them are IBM Champions. Inhi Cho Suh, the new GM of IBM Collaboration Solutions, will be speaking at the Opening General Session together with Suzanne Livingston, Christ Crummey and Sarah Gibbons, all from IBM. There are five tracks with sessions, and if you look at the agenda I am sure you will find plenty to choose from. Theo always put on a great conference, I really wish I was able to attend! Update: there will be 43 IBM Champions attending, 33 of which will be presenting! On April 11-13 you have EntwicklerCamp in Gelsenkirchen, Germany. This conference, which has been taking place for many years and I have heard much good about, is arranged by Rudy Knegt and the cost is €1499 for the three day conference. If you look at the agenda, you will see that there are sessions not only in German but also in English. Many of the sessions are presented by IBM Champions. ICON US (formerly IamLUG) did not take place last year, but in 2016 Chris Miller and his team is back with a two day vertual conference. It takes place May 9-10 and you can register here. Seats (even if they are virtual) are limited. Social Connections 10 is taking place in Toronto, Canada this year, June 6-7. Keynote speakers are Luis Suarez and Alan Lepofsky. As the name indicates, this conference focuses on IBM Connections. Early bird registration ends on April 1, and the cost is CA$229.00 while the regular price is $CA269.00. Then there is MWLUG, this year taking place in Austin on August 17-19. Richard Moy and his team did a great job in Atlanta in 2015, and I am looking forward to this years conference. This is an "almost free"  conference, the fee is $75 but don't be fooled to think it is a cheap conference. Don't miss out on some excellent content! So go to some user conferences, be social and learn amazing new things!    

2 Comments

My Connect 2016 presentation & demo database

As I promised, I would post my IBM Connect 2016 presentation on my blog. Presentation (PDF): {link}  Demo database (ZIP): {link} You can also find the presentation on SlideShare.net. To the right you see the database design, you want to look in the Agent section for the agents and in the Pages section for the HTML pages. Note: You need to sign the database with an ID that have the proper rights. Otherwise the code will not work. Enjoy!  

6 Comments

IBM Connect 2016 coming up!

In the end of January it is once again time to head to Orlando for the yearly conference that for many years was known as Lotusphere. For the last few years it have been renamed IBM Connect (as well as ConnectED in 2014), and last year most people (including me) thought that 2015 was the end of this conference. But perhaps due to the popularity of the 2015 edition, IBM decided to have the conference again this year, but in a new location as the contract with Swan and Dolphin (where the conference had been held since the first one in 1993) had expired. The new venue is Hilton Orlando. It is closer to the airport and there are also more restaurants around than at Swan and Dolphin. It is close to SeaWorld as well as to the Universal Studios theme parks. Personally I am excited about the new venue. "Swolphin" (as Swan and Dolphin often was referred to) started to get old and worn down, despite a refresh of the rooms back in 2003-2005 some time. Yes, after this many years (18 in a row for me) Swolphin started feeling like a home away from home. You know where everything is, you know the staff and the shortcuts between hotels and sections within the hotel. So a new location makes Connect 2016 more exciting, it will feel like a new conference but hopefully with many of my old friends attending. I have already found several interesting sessions using the session tool. Philippe Riand and Jesse Gallagher will for example talk about the Darwino application development platform, which allows you to integrate your Domino applications with IBM Bluemix an IBM Connections. Another must-attend session is called IBM Domino App.Net and talks about how to utilize Bluemix to build XPages applications in the cloud. In addition we of course have all the sessions we have come to know and love: UserBlast with Mat Newman, Admin Tips Power Hour presented by Chris Miller, Spark Ideas, and of course the Opening General Session (OGS) with a secret guest speaker as the tradition requires. After the fiasco last year with the Tuesday evening special event the organizers went back to holding the event in one of the local theme parks. For the second time it will be held in the Wizarding World of Harry Potter - Hogsmead, which is part of Universal's Islands of Adventure. Last time I had a blast, so much that last year I took a couple of vacation days to visit Hogsmead again as well as the then newly opened Diagon Alley extension over in the Universal Studios park next-door. You need a park-to-park admission pass to visit both parks, but that allows you to take the Hogwarts Express between the two parks. For me personally Connect 2016 is a milestone. It will be my 20th Lotusphere/Connect and for the first time I will present a session! This is not a full one hour session, but a new format called Lightning Talk. Those are shorter 20 minute sessions,…

1 Comment

Calling a Notes web agent from another server using JSONP

In my MWLUG presentation (as well as in a couple of entries on this blog) I talk about how you can access Domino data from a regular webpage using jQuery and a Lotusscript agent returning data as JSON. The issue with this solution is that the web page must be on the same web application path as the Domino agent. You can't do what's known as cross-domain Ajax. For example if the Domino server is domino.texasswede.com but you have the webpage hosted at www.texasswede.com, it will not work. The security in Javascript does not allow calls across servers like that. There is however an easy solution, and it is called JSONP. What you do is to return not JSON but a call-back function with the JSON data as the argument. So instead of returning this: { "firstName":"Karl-Henry", "lastname":"Martinsson","email":"texasswede@gmail.com" } you would have the Lotuscript agent return this: personCallBack({ "firstName":"Karl-Henry", "lastname":"Martinsson","email":"texasswede@gmail.com" }) Let's assume we call the agent GetPersonData.jsonp.  On the calling side (in the jQuery code) you would then use this code: $.ajax({ url : "http://domino.texasswede.com/database.nsf/GetPersonData.jsonp?OpenAgent", dataType:"jsonp" }); Finally you write the Javascript call-back function that will accept the data: function personCallBack(data) { $("#firstName").html(data["firstName"]);     $("#lastName").html(data["lastName"]);     $("#emailAddress").html(data["email"]); } You can of course make this as advanced as you like but this is the basics. I have updated the JSON class I use for stuff like this to include a method to return JSONP. The new function is called SendJSONPToBrowser() and takes a string with the name of the call-back function as argument, for example like this: Call json.SendJSONPToBrowser("personCallBack") Below is the updated class (if you downloaded my sample database from MWLUG you have the older version of it). Enjoy!   %REM Library Class.JSON by Karl-Henry Martinsson Created Oct 9, 2014 - Initial version Updated Nov 6, 2015 - Added JSONP support Description: Class to generate simple JSON from values %END REM Option Public Option Declare Class JSONdata Private p_json List As String Public Sub New() '*** Set default value(s) me.p_json("ajaxstatus") = "" End Sub %REM Property Set success Description: Set success to true or false %END REM Public Property Set success As Boolean If me.success Then Call me.SetValue("ajaxstatus","success") Else Call me.SetValue("ajaxstatus","error") End If End Property %REM Property Get success Description: Not really used... %END REM Public Property Get success As Boolean If me.p_json("ajaxstatus") = |"success"| Then me.success = True Else me.success = False End If End Property %REM Sub SetMsg Description: Set msg item %END REM Public Sub SetMsg(message As String) Call me.SetValue("msg",message) End Sub Public Sub SetErrorMsg(message As String) Call me.SetValue("errormsg",message) me.success = False End Sub Public Sub SetValue(itemname As String, value As String) Dim tmp As String Dim delimiter As String '*** Check for quote (double and single) and fix value if needed tmp = Replace(value,Chr$(13),"<br>") tmp = FullTrim(Replace(tmp,Chr$(10),"")) If InStr(tmp,|"|)>0 Then If InStr(tmp,|'|)>0 Then tmp = Replace(tmp,|"|,|"|) delimiter = |"| Else delimiter = |'| End If Else delimiter = |"| End If '*** Store value with delimiter in list me.p_json(itemname) = delimiter & tmp & delimiter End Sub Public Sub SetData(itemname As String, value As…

0 Comments

Code – Read from and Write to Windows Registry in Lotusscript

A question was posted in the IBM DeveloperWorks forum for Notes/Domino 8 about the possibility to detect from within Notes if a computer is equipped with a touch screen. The answer was that you have to check if a specific DLL is installed, which is done though the registry. The original posted then asked how to do that in Lotusscript, so I deceded to simply post some code I am using. I did not write this code, and I don't know who originally did. I think I may have taken some VB code and simply adapted it for Lotusscript. I plan to rewrite this a s a class when I have some time. In the mean time, here is the code.   Option Public Option Declare Dim REG_NONE As Long Dim REG_SZ As Long Dim REG_EXPAND_SZ As Long Dim REG_BINARY As Long Dim REG_DWORD As Long Dim REG_DWORD_LITTLE_ENDIAN As Long Dim REG_DWORD_BIG_ENDIAN As Long Dim REG_LINK As Long Dim REG_MULTI_SZ As Long Dim REG_RESOURCE_LIST As Long Dim REG_FULL_RESOURCE_DESCRIPTOR As Long Declare Function RegCloseKey Lib "advapi32.dll" (Byval hKey As Long) As Long Declare Function RegCreateKeyEx Lib "advapi32.dll" Alias "RegCreateKeyExA" (Byval hKey As Long, _ Byval lpSubKey As String, Byval Reserved As Long, Byval lpClass As String, _ Byval dwOptions As Long, Byval samDesired As Long, Byval lpSecurityAttributes As Long, _ phkResult As Long, lpdwDisposition As Long) As Long Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (Byval hKey As Long, _ Byval lpSubKey As String, Byval ulOptions As Long, Byval samDesired As Long, _ phkResult As Long) As Long Declare Function RegSetValueExString Lib "advapi32.dll" Alias "RegSetValueExA" (Byval hKey As Long, _ Byval lpValueName As String, Byval Reserved As Long, Byval dwType As Long, Byval lpValue As String, _ Byval cbData As Long) As Long Declare Function RegSetValueExLong Lib "advapi32.dll" Alias "RegSetValueExA" (Byval hKey As Long, _ Byval lpValueName As String, Byval Reserved As Long, Byval dwType As Long, lpValue As Long, _ Byval cbData As Long) As Long Declare Function RegQueryValueExString Lib "advapi32.dll" Alias "RegQueryValueExA" _ (Byval hKey As Long, Byval lpValueName As String, Byval lpReserved As Long, lpType As Long, _ Byval lpData As String, lpcbData As Long) As Long Declare Function RegQueryValueExLong Lib "advapi32.dll" Alias "RegQueryValueExA" _ (Byval hKey As Long, Byval lpValueName As String, Byval lpReserved As Long, lpType As Long, _ lpData As Long, lpcbData As Long) As Long Declare Function RegQueryValueExNULL Lib "advapi32.dll" Alias "RegQueryValueExA" _ (Byval hKey As Long, Byval lpValueName As String, Byval lpReserved As Long, lpType As Long, _ Byval lpData As Long, lpcbData As Long) As Long ' --- Registry key values Const HKEY_CLASSES_ROOT = &H80000000 Const HKEY_CURRENT_USER = &H80000001 Const HKEY_LOCAL_MACHINE = &H80000002 Const HKEY_USERS = &H80000003 Const HKEY_CURRENT_CONFIG = &H80000005 ' --- Registry return values Const ERROR_NONE = 0 Const ERROR_BADDB = 1 Const ERROR_BADKEY = 2 Const ERROR_CANTOPEN = 3 Const ERROR_CANTREAD = 4 Const ERROR_CANTWRITE = 5 Const ERROR_OUTOFMEMORY = 6 Const ERROR_INVALID_PARAMETER = 7 Const ERROR_ACCESS_DENIED = 8 Const ERROR_INVALID_PARAMETERS = 87 Const ERROR_NO_MORE_ITEMS = 259 ' --- Registry access key Const…

3 Comments

Coming Soon – Interesting Webinars

The Notes training company TLCC has two very interesting webinars coming up, especially for anyone that were not able to attende ConnectED in January. On May 14 the IBM development team will talk about the Domino development landscape, including new features for Domino on-premises as well as for the cloud through IBM Bluemix. IBM:ers Pete Janzen, Martin Donnelly and Brian Gleeson will be featured. Then on June 16 the IBM product team will be featured. Scott Vrusho and Scott Souder is going to talk about where Notes, Domino and Verse are heading, while Dave Kern and Kevin Lynch will talk about recent security related changes to the Domino server. You can find out more at http://www.tlcc.com/admin/tlccsite.nsf/pages/xpages-webinar

0 Comments

One week to ConnectED 2015 in Orlando

Today it is one week until IBM ConnectED, the conference formerly known as Lotusphere (and briefly also as IBM Connect) opens the doors in Orlando. This might be the last year the Lotus faithfuls gather at Walt Disney Swan to drink from the firehose of knowledge, as Lotusphere used to be described. Back in 2006 (if my memory is correct), IBM announced during the conference that the company had renewed the contract with Dolphin & Swan until 2015, a year that then was far in the future. Now we are there, and I an convinced that IBM will merge Lotusphere/Connect/ConnectED with one of their other big conferences. This year we will see many changes. Some are already known, other we will probably see when or after we arrive. Some of the known ones: The conference will be smaller, the number of attendees have been limited to around 1500. The number of IBM:ers have also been reduced to a few hundred. The conference will take place (almost) in it's entirety at the Swan conference center. A few sessions have been listed on the official site as taking place at Dolphin, like BP101: @IF("Its Really Good";"It MUST Be Notes";"Must Be Something Else") 25 Notes on 25 Years of Notes! with Carl Tyler, Mat Newman and Alan Lepofsky. ConnectED is more technical than the last few years, with less sessions dedicated to case studies and panels, and more focus on the technical aspects of the products. The conference is one day shorter, ending Wednesday instead of Thursday. There will be no theme park visit/party, instead there will be a poolsite party Tuesday. The Sunday night welcome reception will take place on the Swan Lake Terrace, as well as in the new TechnOasis area, which replaces the solutions showcase and social café from the past. On a more personal front, some of my long-time friends in the Lotus/IBM/ICS community will not be attending this year, for a number of different reasons. They will all be missed. But many will still be there, and there are even several attending only the social events and not the actual conference. That is a sign of how strong the community is. I hope this will continue at whatever conference Lotusphere get assimilated into. The social part is the best part of the community. Like Volker Weber said a few years ago: Let me tell you something: life is about people, not about technology. Your friends will be your friends. And you will see them again. And again, and again. Technology changes, friendship lasts. In change, there lies opportunity. I am looking forward to the people of ConnectED 2015. And the technology. I am for example interested to learn more about the roadmap for IBM Verse as well as Notes/Domino on premises and in the cloud. I also hope to learn more about IBM BlueMix. See you in Orlando!

0 Comments

File Upload in Classic Domino Web using jQuery and Bootstrap

This week I was asked to create a simple web form where customers could fill out a few fields, attach two files and submit it for review. The document with the information and attachments are saved into a Domino database, so it can be processed thought the Notes client by the internal staff. These days I mainly use Bootstrap (and jQuery) to design the webpages, since Bootstrap makes it very quick and easy to get a nice clean look of the page. Using jQuery allows me to do some nice manipulations of the DOM, hiding and showing sections as needed for example, or disable the submit button until all required fields have been filled out. It has been a long time since I worked with the file upload control in Domino, and it was as ugly as I remembered it. But I knew I had seen some nice jQuery/Bootstrap file upload controls, so I located one that I liked in the Jasny plugin library. If you haven't already, take a look at those components! So how do I tie this control to the Domino file upload control? As so many times before, Jake Howlett and his excellent site CodeStore comes to the rescue. He wrote an article back in 2005 about how to fake a file upload control, and that code can be used as-is, and combined with the Jasny plugin. Here is what my code looks like after doing that: <div class="col-md-6"> <label>Producer Agreement</label> <!-- File Upload --> <div class="fileinput fileinput-new input-group" data-provides="fileinput" title="Attach file here"> <div class="form-control" data-trigger="fileinput"> <i class="glyphicon glyphicon-file fileinput-exists"></i>&nbsp; <span class="fileinput-filename"></span> </div> <span class="input-group-addon btn btn-default btn-file"> <span class="fileinput-new">Select file</span> <span class="fileinput-exists">Change</span> <input type="file" name="%%File.1" class="required"> </span> <a href="#" class="input-group-addon btn btn-default fileinput-exists" data-dismiss="fileinput">Remove</a> </div> </div> On the second file upload control I just change the name to "%%File.2". The form tag must have the encoding set to multipart/form-data, so this is what it looks like for me: <form name="SubmissionForm" id="SubmissionForm" action="AgencySubmission?CreateDocument" method="post" enctype="multipart/form-data"> It all worked perfectly. I was able to attach the files and submit the form, and the files showed up in the Notes client. What I did not like was the dreaded "Form processed" message. I tried a few different things, using the $$Return field, etc. But nothing worked. To make a long story short(er), and without diving too deep into details, I had the form setup to render as HTML, not as a Notes form, thus using ?ReadForm to display it. But when I changed it to Notes on the form properties, the Domino server added it's own Javascript code to submit the form (in addition to extra HTML). I found out a way to trick Domino to "hide" that Javascript code, so only my jQuery/Javascript code was sent to the browser. Then I wrote my own code to do a HTTP POST submission of the form as multipart/form-data: $('form#SubmissionForm').submit(function(event){ // Disable the default form submission event.preventDefault(); // Gat all form data var formData = new FormData($(this)[0]); $('input').each( function() { formData.append($(this).attr('id'),$(this).val()); });…

6 Comments

Happy 25th birthday, Lotus Notes!

Today is the 25th birthday of Lotus Notes. It is the program responsible for me moving to the US, as well as being my career for the last close to 18 years. So, as you can see in the picture above, I am toasting this amazing software in IBM blue colors, courtesy of Curaçao Blue. Happy birthday, Lotus Notes!

1 Comment

Free Code – Class to read URL name-value pairs

Here is another little code snippet I want to share. I use it all the time in my Lotusscript-based Domino web agents, and I figured that other could benefit from it as well. It is just an easy way to check for and read the name-value pairs (arguments) passed from the browser to the web server by HTTP GET or POST calls. Put the code below in a script library, I call it Class.URL: %REM Library Class.URL Created Oct 9, 2014 by Karl-Henry Martinsson Description: Lotusscript class to handle incoming URL (GET/POST). %END REM Option Public Option Declare %REM Class URLData Description: Class to handle URL data passed to web agent %END REM Class URLData p_urldata List As String %REM Sub New() Description: Create new instance of URL object from NotesDocument %END REM Public Sub New() Dim session As New NotesSession Dim webform As NotesDocument Dim tmp As String Dim tmparr As Variant Dim tmparg As Variant Dim i As Integer '*** Get document context (in-memory NotesDocument) Set webform = session.DocumentContext '*** Get HTTP GET argument(s) after ?OpenAgent tmp = FullTrim(StrRight(webform.GetItemValue("Query_String")(0),"&")) If tmp = "" Then '*** Get HTTP POST argument(s) after ?OpenAgent tmp = FullTrim(StrRight(webform.GetItemValue("Request_Content")(0),"&")) End If '*** Separate name-value pairs from each other into array tmparr = Split(tmp,"&") '*** Loop through array, split each name-value/argument For i = LBound(tmparr) To UBound(tmparr) tmparg = Split(tmparr(i),"=") p_urldata(LCase(tmparg(0))) = Decode(tmparg(1)) Next End Sub %REM Function GetValue Description: Get value for specified argument. Returns a string containing the value. %END REM Public Function GetValue(argname As String) As String If IsElement(p_urldata(LCase(argname))) Then GetValue = p_urldata(LCase(argname)) Else GetValue = "" End If End Function %REM Function IsValue Description: Check if specified argument was passed in URL or not. Returns boolean value (True or False). %END REM Public Function IsValue(argname As String) As Boolean If IsElement(p_urldata(LCase(argname))) Then IsValue = True Else IsValue = False End If End Function '*** Private function for this class '*** There is no good/complete URL decode function in Lotusscript Private Function Decode(txt As String) As String Dim tmp As Variant Dim tmptxt As String tmptxt = Replace(txt,"+"," ") tmp = Evaluate(|@URLDecode("Domino";"| & tmptxt & |")|) Decode = tmp(0) End Function End Class It is now very easy to use the class to check what values are passed to the agent. Below is a sample agent: Option Public Option Declare Use "Class.URL" Sub Initialize Dim url As URLData '*** Create new URLData object Set url = New URLData() '*** MIME Header to tell browser what kind of data we will return Print "content-type: text/html" '*** Check reqired values for this agent If url.IsValue("name")=False Then Print "Missing argument 'name'." Exit Sub End If '*** Process name argument If url.GetValue("name")="" Then Print "'Name' is empty." Else Print "Hello, " + url.GetValue("name") + "!" End If End Sub It is that easy. If my proposal for a session at ConnectED is accepted, you will about how to use jQuery and Bootstrap to retrieve data in .NSF databases through Lotusscript agents, and I will be using…

4 Comments

October Community Webcast – Wednesday October 15

This Wednesday it is again time for the monthly ICS community webcast. This month's guest speaker will be Luis Guirigay, IBM SME for Social, Mobile and Cloud. Below is the description of the webcast agenda. Never before has there been more opportunity for IBM Notes Domino Enterprises! Join Luis Guirigay to learn about the latest tools that will help your company get the most of the Domino platform and increase your ROI. Step through all of the latest user experience options in IBM Notes, Domino, and iNotes, and Traveler that will take your company to the next level of social email. Step through the benefits and options to access mail and apps in the cloud and get the lowdown on the IBM Connections Cloud (formerly IBM SmartCloud) offering. Get the latest information on IBM Mail Next and how the Design Advisory Program is going. Read more here and register here.

0 Comments

Free Software – Password Reset for Notes/Domino

Earlier this year I was asked to research some alternatives for a web-based password reset function at my work. One of the larger support burdens are users who forget the passwords, especially in the first few days after changing it. We have a 90 day password lifespan, then a new password need to be picked. Some users wait until the last minute, which usually is Friday afternoon right before they go home, making it very likely that they will forget the new password over the weekend. Another big group is auditors, who may come in every 6 months or so, and by then their passwords have of course already expired. I first looked at some COTS solutions from HADSL (FirM) and BCC (AdminSuite). They were both very competent, and in addition have several other functions that I really would like to have in my environment (like synchronization between Domino Directory and Active Directory). However, as my company is in a cost saving phase, I was asked if I could build something myself, so I played around a little, and came up with a small and simple application. The application contains two web pages. The first page (Setup) is where the user will setup the security questions used for password recovery as well as entering an external email address that they have access to even if locked out from the Domino account at work. This page is protected by regular Notes security, so the users need to set this up before they lose access to their account. The second page (Request)is where the user can request the password to be reset. After entering their Notes name, the user is presented with one of the security questions. If the question as answered correctly, the user can now enter a new password. If the question is wrong, another of the questions is presented to the user. I am also using regexp to make sure that the password match the requirement our organisation have for password strength. Both pages are built using Bootstrap (v3.2.0),  jQuery (v1.11.0), and for the icons I use Font Awesome (v4.2.0), all loaded from BootstrapCDN. I also use a few local CSS and Javascript files to handle older versions of Internet Explorer. The process steps were created using code by jamro and you can find the code here. By the way, Bootsnipp is a great resource to avoid having to invent the wheel again. There are hundreds of free snippets of code there to build neat Bootstrap functionality. When the user fill out and submit the setup page, a document is created in a Notes database. When the user need to reset the password, the security questions and answers are retrieved from that document. To prevent unauthorised access to the Notes documents, they use Readers fields to prevent them from being visible to anyone but the signer of the agents running on the server. This application can of course be updated with more functionality. Instead of allowing the user to pick a password, one could be generated by the server and sent through email to the address entered during setup. There…

7 Comments

End of content

No more pages to load