TexasSwede
texasswede@gmail.com
  • About this blog
  • My Website
  • My Resume
  • XML Export Tool
  • Photos

Category Archives: Notes/Domino

My Connect 2016 presentation & demo database

Posted on February 17, 2016 by Karl-Henry Martinsson Posted in Bootstrap, Community, Connect, HTML/CSS, IBM/Lotus, jQuery, Lotusscript, Notes/Domino, Web Development 6 Comments

Connect2016_DemoDesignAs 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!

 

IBM Connect 2016 coming up!

Posted on December 8, 2015 by Karl-Henry Martinsson Posted in Community, Connect, IBM/Lotus, Javascript, jQuery, Lotusphere, Notes/Domino, Web Development 1 Comment

Connect2015_People1In 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 fountain at WDW Dolphin

The fountain at WDW Dolphin

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.

HP_GringottsAfter 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.

ConnectSessionLetterFor 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, and not all of them are listed in the session tool on the conference site yet. I think this is a very interesting concept, and I believe it will be successful. I can see myself attending a number of shorter sessions like this to get a good overview of a particular subject, then go on and learn more later.

My session is called “Think outside the box” and I will show how you can connect to a Domino backend from a traditional web application and retrieve data in JSON format. This data can then be used to populate fields/values on a page or used in jQuery/Bootstrap plugin like calendars and data tables. This is a version of the presentation I did at MWLUG in Atlanta, but shorter and with some new content added.

I hope to see you at Connect 2016 in Orlando, perhaps even at my session. If you haven’t registered yet, it is time to do it now. Stay tuned for more posts here leading up to the conference.

Calling a Notes web agent from another server using JSONP

Posted on November 6, 2015 by Karl-Henry Martinsson Posted in Javascript, jQuery, Lotusscript, Notes/Domino, Programming, Web Development Leave a comment

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 String)
		'*** Store value in list
		me.p_json(itemname) = value
	End Sub
	
	%REM
		Function GetJSON
		Description: Return a JSON object as text
	%END REM
	Function GetJSON As String
		Dim json As String
		'*** Opening curly braces + CR
		json = "{" + Chr$(13)
		'*** Loop through all list elements and build JSON
		ForAll j In me.p_json
			json = json + |"| + ListTag(j) + |":| + j + "," + Chr$(13)
		End ForAll
		'*** Remove the comma after the last item
		json = Left$(json,Len(json)-2) + Chr$(13)
		'*** Add closing curly bracket and return JSON
		json = json + "}"
		GetJSON = json 
	End Function
	
	%REM
		Sub SendToBrowser
		Description: Print JSON to browser, with correct MIME type
	%END REM
	Public Sub SendToBrowser()
		'*** MIME Header to tell browser what kind of data we will return (JSON).
		'*** See http://www.ietf.org/rfc/rfc4627.txt
		Print "content-type: application/json"
		Print me.GetJSON
	End Sub
	
	%REM
		Sub SendJSONPToBrowser
		Description: Print JSON to browser, with correct MIME type
	%END REM
	Public Sub SendJSONPToBrowser(callbackFunction As String)
		'*** MIME Header to tell browser what kind of data we will return (Javascript).
		'*** See http://www.rfc-editor.org/rfc/rfc4329.txt
		Print "content-type: application/javascript"
		Print callbackFunction + "(" + me.GetJSON + ")"
	End Sub
	
End Class

 

My MWLUG presentation

Posted on August 20, 2015 by Karl-Henry Martinsson Posted in Bootstrap, HTML/CSS, IBM/Lotus, Javascript, jQuery, Lotusscript, MWLUG, Notes/Domino, Web Development Leave a comment

You can find my presentation from yesterday here.

I plan to publish the speaker notes soon, after I clean them up some.

Code – Read from and Write to Windows Registry in Lotusscript

Posted on June 23, 2015 by Karl-Henry Martinsson Posted in Lotusscript, Notes/Domino, Programming 3 Comments

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 KEY_ALL_ACCESS = &H3F
Const REG_OPTION_NON_VOLATILE = 0


Sub Initialize
	REG_NONE = 0
	REG_SZ  = 1
	REG_EXPAND_SZ = 2
	REG_BINARY = 3
	REG_DWORD = 4
	REG_DWORD_LITTLE_ENDIAN = 4
	REG_DWORD_BIG_ENDIAN = 5
	REG_LINK = 6
	REG_MULTI_SZ = 7
	REG_RESOURCE_LIST = 8
	REG_FULL_RESOURCE_DESCRIPTOR = 9
End Sub


Function SetValueEx(Byval lngHKey As Long, strValueName As String, lngType As Long, varValue As Variant) As Long
	Dim lngValue As Long
	Dim strValue As String
	
	Select Case lngType
	Case REG_SZ
		strValue = varValue & Chr(0)
		SetValueEx = RegSetValueExString(lngHKey, _
		strValueName, _
		0&, _
		lngType, _
		strValue, _
		Len(strValue))
	Case REG_DWORD
		lngValue = varValue
		SetValueEx = RegSetValueExLong(lngHKey, _
		strValueName, _
		0&, _
		lngType, _
		lngValue, _
		4)
	End Select
End Function


Sub RegistryCreateKey(dblHiveID As Double, strBaseKey As String, strKey As String, strData As String)
	Dim lngResult As Long
	Dim lngDisplay As Long
	Dim intReturn As Integer
	
	lngResult = 0
	lngDisplay = 0
	intReturn = RegCreateKeyEx(Byval dblHiveID, _
	Byval strBaseKey, _
	Byval 0&, _
	Byval "REG_SZ", _
	Byval 0&, _
	Byval KEY_ALL_ACCESS, _
	Byval 0&, _
	lngResult, _
	lngDisplay)
	intReturn = RegSetValueExString(Byval lngResult, _
	Byval strKey, _
	Byval 0&, _
	Byval 1&, _
	Byval strData, _
	Byval Len(strData))
End Sub 


Function RegistryGetValue(dblHiveID As Double, strKeyName As String, strValueName As String, _
strDefaultValue As Variant) As Variant
	Dim lngReturn As Long    ' result of the API functions
	Dim lngHKey As Long      ' handle of opened key
	Dim varValue As Variant  ' setting of queried value
	
	On Error Goto RegistryGetValueError
	lngReturn = RegOpenKeyEx(dblHiveID, strKeyName, 0, _
	KEY_ALL_ACCESS, lngHKey)
	lngReturn = RegistryQueryValueEx(lngHKey, strValueName, varValue)
	RegCloseKey (lngHKey)
	If (varValue = "") Then
		RegistryGetValue = strDefaultValue
	Else
		RegistryGetValue = varValue
	End If
	Exit Function
RegistryGetValueError:
	RegistryGetValue = strDefaultValue
End Function


Function RegistryQueryValueEx(Byval lngHKey As Long, Byval strValueName As String, _
varValue As Variant) As Long
	Dim lngDataPntr As Long
	Dim lngReturn As Long
	Dim lngType As Long
	Dim lngValue As Long
	Dim strValue As String
	
	On Error Goto RegistryQueryValueExError
    ' Determine the size and type of data to be read
	lngReturn = RegQueryValueExNULL(lngHKey, strValueName, 0&, _
	lngType, 0&, lngDataPntr)
	If (lngReturn <> ERROR_NONE) Then
		Error 5
	End If
	Select Case lngType
        ' For strings
		Case REG_SZ:
			strValue = String(lngDataPntr, 0)
			lngReturn = RegQueryValueExString(lngHKey, _
			strValueName, 0&, _
			lngType, strValue, lngDataPntr)
			If (lngReturn = ERROR_NONE) Then
				varValue = Trim(Left(strValue, lngDataPntr - 1))
			Else
				varValue = FullTrim("")		'returns empty
			End If
   	     ' For DWORDS
		Case REG_DWORD:
			lngReturn = RegQueryValueExLong(lngHKey, _
			strValueName, 0&, _
			lngType, lngValue, lngDataPntr)
			If (lngReturn = ERROR_NONE) Then
				varValue = lngValue
			End If
		Case Else
            ' all other data types not supported
			lngReturn = -1
	End Select
RegistryQueryValueExExit:
	RegistryQueryValueEx = lngReturn
	Exit Function
RegistryQueryValueExError:
	Resume RegistryQueryValueExExit
End Function

Coming Soon – Interesting Webinars

Posted on April 30, 2015 by Karl-Henry Martinsson Posted in Community, IBM/Lotus, Notes/Domino, Verse Leave a comment

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

One week to ConnectED 2015 in Orlando

Posted on January 19, 2015 by Karl-Henry Martinsson Posted in ConnectED, IBM/Lotus, Lotusphere, Notes/Domino, Personal, Verse Leave a comment

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!

File Upload in Classic Domino Web using jQuery and Bootstrap

Posted on January 8, 2015 by Karl-Henry Martinsson Posted in Bootstrap, IBM/Lotus, jQuery, Notes/Domino 6 Comments

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());
  });
  // Submit form to Domino server using specified form
  $.ajax({
    url: 'AgencySubmission?CreateDocument',
    type: 'POST',
    data: formData,
    async: false,
    cache: false,
    contentType: false,   // Important!
    processData: false,   // Important!
    success: function (returndata) {
      window.location = 'SubmissionThankYou.html';
    }
  });
  return false;
});

That’s it! It worked like a charm. And this is what the final result looks like:

FileUploadControl_Bootstrap

Of course, if you are able to use XPages, there are nice file upload controls there that you can use.

Happy 25th birthday, Lotus Notes!

Posted on November 27, 2014 by Karl-Henry Martinsson Posted in History, IBM/Lotus, Notes/Domino 1 Comment

image

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.

image

Happy birthday, Lotus Notes!

Free Code – Class to read URL name-value pairs

Posted on November 20, 2014 by Karl-Henry Martinsson Posted in ConnectED, Lotusscript, MWLUG, Notes/Domino, Web Development 4 Comments

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 this class in my demos. So see this as a preview.
If the session doesn’t get selected by IBM, I plan to record it and post it somewhere online later.

The premise of the session is that you have data in a Domino database, but for some reason you can’t use XPages. Your company may be on an older version of Notes/Domino with no plans/budget to upgrade, the web developer don’t know XPage and have no time to learn it, or the data will be retreived from some other Web based system, perhaps WordPress.

Update: The session was not accepted at ConnectED, but I will present it at WMLUG in Atlanta on August 19, 2015.

Stack Exchange

profile for Karl-Henry Martinsson on Stack Exchange, a network of free, community-driven Q&A sites

Recent Posts

  • Domino 14 is now available
  • Domino 14 Early Access Program
  • Announced: Engage 2024
  • Integrate Node-RED with Notes and Domino
  • Notes and Domino v12 is here!

Recent Comments

  • Theo Heselmans on Announced: Engage 2024
  • Lotus Script Multi-thread Message Box [SOLVED] – Wanted Solution on ProgressBar class for Lotusscript
  • Viet Nguyen on Keep up with COVID-19 though Domino!
  • Viet Nguyen on Keep up with COVID-19 though Domino!
  • Mark Sullivan on Looking for a HP calculator? Look no further!

My Pages

  • How to write better code in Notes

Archives

  • December 2023 (1)
  • October 2023 (2)
  • September 2023 (1)
  • June 2021 (1)
  • April 2021 (2)
  • March 2021 (1)
  • August 2020 (3)
  • July 2020 (2)
  • April 2020 (2)
  • March 2020 (1)
  • December 2019 (2)
  • September 2019 (1)
  • August 2019 (2)
  • July 2019 (2)
  • June 2019 (3)
  • April 2019 (2)
  • December 2018 (1)
  • November 2018 (1)
  • October 2018 (5)
  • August 2018 (2)
  • July 2018 (3)
  • June 2018 (2)
  • May 2018 (1)
  • April 2018 (2)
  • March 2018 (1)
  • February 2018 (2)
  • January 2018 (4)
  • December 2017 (3)
  • November 2017 (2)
  • October 2017 (2)
  • September 2017 (1)
  • August 2017 (2)
  • July 2017 (6)
  • May 2017 (4)
  • February 2017 (1)
  • January 2017 (2)
  • December 2016 (2)
  • October 2016 (3)
  • September 2016 (4)
  • August 2016 (1)
  • July 2016 (2)
  • June 2016 (2)
  • May 2016 (3)
  • April 2016 (1)
  • March 2016 (4)
  • February 2016 (2)
  • January 2016 (4)
  • December 2015 (3)
  • November 2015 (2)
  • October 2015 (1)
  • September 2015 (2)
  • August 2015 (1)
  • July 2015 (5)
  • June 2015 (2)
  • April 2015 (2)
  • March 2015 (3)
  • February 2015 (2)
  • January 2015 (10)
  • December 2014 (1)
  • November 2014 (3)
  • October 2014 (3)
  • September 2014 (13)
  • August 2014 (6)
  • July 2014 (5)
  • May 2014 (3)
  • March 2014 (2)
  • January 2014 (10)
  • December 2013 (5)
  • November 2013 (2)
  • October 2013 (5)
  • September 2013 (4)
  • August 2013 (7)
  • July 2013 (3)
  • June 2013 (1)
  • May 2013 (4)
  • April 2013 (7)
  • March 2013 (8)
  • February 2013 (9)
  • January 2013 (5)
  • December 2012 (7)
  • November 2012 (13)
  • October 2012 (10)
  • September 2012 (2)
  • August 2012 (1)
  • July 2012 (1)
  • June 2012 (3)
  • May 2012 (11)
  • April 2012 (3)
  • March 2012 (2)
  • February 2012 (5)
  • January 2012 (14)
  • December 2011 (4)
  • November 2011 (7)
  • October 2011 (8)
  • August 2011 (4)
  • July 2011 (1)
  • June 2011 (2)
  • May 2011 (4)
  • April 2011 (4)
  • March 2011 (7)
  • February 2011 (5)
  • January 2011 (17)
  • December 2010 (9)
  • November 2010 (21)
  • October 2010 (4)
  • September 2010 (2)
  • July 2010 (3)
  • June 2010 (2)
  • May 2010 (3)
  • April 2010 (8)
  • March 2010 (3)
  • January 2010 (5)
  • November 2009 (4)
  • October 2009 (7)
  • September 2009 (1)
  • August 2009 (7)
  • July 2009 (1)
  • June 2009 (4)
  • May 2009 (1)
  • April 2009 (1)
  • February 2009 (1)
  • January 2009 (3)
  • December 2008 (1)
  • November 2008 (1)
  • October 2008 (7)
  • September 2008 (7)
  • August 2008 (6)
  • July 2008 (5)
  • June 2008 (2)
  • May 2008 (5)
  • April 2008 (4)
  • March 2008 (11)
  • February 2008 (10)
  • January 2008 (8)

Categories

  • AppDev (10)
  • Blogging (11)
    • WordPress (5)
  • Design (5)
    • Graphics (1)
    • UI/UX (2)
  • Featured (5)
  • Financial (2)
  • Food (5)
    • Baking (3)
    • Cooking (3)
  • Generic (11)
  • History (5)
  • Hobbies (10)
    • LEGO (4)
    • Photography (4)
  • Humor (1)
  • IBM/Lotus (178)
    • #Domino2025 (14)
    • #DominoForever (8)
    • #IBMChampion (46)
    • Administration (7)
    • Cloud (7)
    • CollabSphere (9)
    • Community (49)
    • Connect (33)
    • ConnectED (12)
    • Connections (3)
    • HCL (15)
    • HCL Master (1)
    • IBM Think (1)
    • Lotusphere (46)
    • MWLUG (25)
    • Notes/Domino (99)
      • Domino 11 (7)
    • Sametime (8)
    • Verse (14)
    • Volt (3)
    • Watson (6)
  • Life (8)
  • Microsoft (7)
    • .NET (2)
    • C# (1)
    • Visual Studio (1)
  • Movies (3)
  • Old Blog Post (259)
  • Personal (23)
  • Programming (84)
    • App Modernization (11)
    • Formula (4)
    • Lotusscript (47)
    • NetSuite (4)
      • SuiteScript (3)
    • node.js (4)
    • XPages (4)
  • Reviews (9)
  • Sci-Fi (4)
  • Software (24)
    • Flight Simulator (2)
    • Games (4)
    • Open Source (2)
    • Utilities (6)
  • Technology (37)
    • Aviation (3)
    • Calculators (2)
    • Computers (6)
    • Gadgets (7)
    • Mobile Phones (7)
    • Science (3)
    • Tablets (2)
  • Travel (7)
    • Europe (1)
    • Texas (2)
    • United States (1)
  • Uncategorized (16)
  • Web Development (50)
    • Frameworks (23)
      • Bootstrap (14)
    • HTML/CSS (12)
    • Javascript (32)
      • jQuery (23)
  • Prev
  • 1
  • …
  • 4
  • 5
  • 6
  • 7
  • 8
  • …
  • 10
  • Next

Administration

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org

Tracking

Creeper
MediaCreeper
  • Family Pictures
© TexasSwede 2008-2014