You’ve Got Mail (And an Image) !!

March 30, 2007 at 3:25 pm (Embedded Image, Lotus Notes, PassThru HTML)

My clients threw an unusual request at me; somebody higher up in the hierarchy wanted a way to track the number of people who were even opening a particular newsletter email.

Ok, well, simple – could easily do with plain ole’ read receipts, or so I thought. Apparently, not – the whole thing had to be done in a way completely transparent to the user-base. So read-receipts were definitely out (especially since disabling read-receipts is not exactly rocket-science!). My next suggestion was to have some code in the mail’s PostOpen on QueryClose event, to increment the count in another database. But it turned out that the client had something much more tricky in mind. He wanted to insert an image-reference URL inside the email, which would automatically be loaded up from the source (much like an image inside a website is loaded). The number of ‘hits’ to the image could then be computed.

Hmm… tricky. First, I thought of inserting an image resource into the email, and then use the owner database of the image resource to compute the number of hits. This seemed feasible especially since you can now insert image-resources from other databases too. Unfortunately, the image seems to be embedded into the email, and is not treated as a reference to the database. I sent out an email with such an image inside to multiple people, who did open their emails but were not recorded by the database. So that came to nought.

My next thought was to use passthru-HTML to notate an image reference using an <img> tag. I opened up my Memo form in designer, did the Store-Form-in-Doc and Render-passthru-HTML checks. Then I proceeded to create a new Memo, inserted an <img> reference, turned on passthru for the tag and then sent it out. However, that didn’t work either; though a form with a passthru <img> tag on it works fine.

After a lot of digging, I found out that mere passthru HTML on a memo probably wouldn’t cut it – because, Lotus Notes’ native data format is something called Composite Data (CD). Thus passthru-HTML doesn’t ultimately behave like ‘real’ HTML, instead it gets converted to this CD format. And because its in the CD format, the HTML doesn’t get rendered. So what would be a good way to force a mail to render HTML on its pages? MIME, of course. I mean, emails that come into a LN mailbox from internet-addresses like gmail and yahoo render images correctly, so MIME has to work.

With that idea in mind, I played around with the Notes MIME classes, and finally got it to work. The script I used (rather frayed around the edges, needs more fine-tuning) was this:

‘———- Creating a MIME Email —————-
Dim session As New NotesSession
Dim ws As New NotesUIWorkspace
Dim db As NotesDatabase
Dim maildoc As NotesDocument
Dim mime As NotesMimeEntity
Dim mimeHeader As NotesMimeHeader
Dim mimeChild As NotesMimeEntity
Dim stream As NotesStream
Dim recipients As Variant

recipients = ws.PickListStrings(PICKLIST_NAMES, True)
If Isempty(recipients) Then
Msgbox “Cannot proceed without specifying who this mail has to be sent to”
Exit Sub
End If

Set db = session.CurrentDatabase
Set maildoc = New NotesDocument(db)
maildoc.Form = “Memo”
maildoc.Subject = “Checking out image references”
maildoc.SendTo = recipients

Set stream = session.CreateStream
session.ConvertMime = False
Set mime = maildoc.CreateMimeEntity
Set mimeHeader = mime.CreateHeader(“Content-Type”)
Call mimeHeader.SetHeaderVal(“multipart/mixed”)

‘—Create Message Text ———–
Set mimeChild = mime.CreateChildEntity
Call stream.WriteText(“The purpose of this email is to test whether image references work corectly” & Chr$(10) & Chr$(10))
Call stream.WriteText(“<img src=’http://riscapp03.metlife.com/auddbs/starsforum.nsf/Help.jpeg’ alt=’Publications DB’>”)
Call mimeChild.SetContentFromText(stream,”text/html”,ENC_NONE)
Call stream.Close

Call maildoc.Send(False)

With a bit of fine-tuning (probably to accept the URL of the image as well), the script would be ready for delivering to the client. Gotta admit, this support for MIME is cool. Have never played around with it much, so it opens up some interesting possibilities.

Permalink Leave a Comment

Tabbed Navigation

March 26, 2007 at 8:37 pm (Lotus Notes, UI)

And no, I am not talking about tabbed tables here. If you already knew that you could have horizontal outlines giving you a tabbed-navigation style instead of the routine, boring left-hand navigation that most LN templates offer, then read no further. For the others:

A bit of history first: outlines were introduced in R5. When I used them for the first time, there was a lot of skepticism from my colleagues (a dinosaur even complained that he couldn’t ‘edit’ them, like he could with plain, ole’ navigators :) ). But hey, outlines can be used for a whole lot of things, than the conventional templates tell us. Some of the most inventive usages I’ve seen are from Chris at his Interface Matters blog – including a fabulous drag’n'drop feature, and some nifty menus.

Now, let’s take a look at what I was trying to do. At our company, everybody uses the same, old template-style interface, and I have been raring to break the mould. One of those attempts resulted in this:

Horizontal Outline

This is surprisingly easy to do, using a horizontal outline. Just create an outline, and play around with the spacing, its that easy! This is what I used:

Horizontal Outline Horizontal Outline - Spacing

Permalink Leave a Comment

Implementing a Domino-Suggest

August 4, 2006 at 9:51 am (Ajax, Domino, HTML, JavaScript)

This is a continuation of the series on implementing an interface similar to Google-Suggest on our typical Domino search pages (The first part in the series dealt with Ajax views).

The basic idea behind Google-Suggest is pretty ingenious; as the user types into the textbox, Google would perform a lookup into its index of search-terms and suggest results. The first suggestion would be automatically populated into the textbox, while the rest of the suggestions appear automatically as a SELECT element under the textbox.

I have borrowed the implemntation of the auto-suggest feature from this awesome article, which explains the underlying concepts better than I ever could. The basic premise behind the implementation is to have two classes: an autosuggest textbox class to handle all user-interaction, and a suggestion-provider class to provide the autosuggest textbox with suggestions.

The autosuggest textbox class would take control over the textbox where the user would type in the search-string. It would impose custom handlers over events such as keyup, keydown, keypress etc. Typically, these custom handlers would track the search-string entered (so far), and pass it onto a requestSuggestions() member-method of the suggestion-provider class. In our case, the suggestion-provider class would basically be the wrapper class around the NotesView class that we discussed earlier.

The auto-suggest dropdown is nothing but an absolutely positioned DIV that is created and populated ‘dynamically’. Part 2 of the article explains this concept as well. With all these concepts in tow, implementing a nifty auto-suggest feature in a Domino database should be a cinch.

Permalink Leave a Comment

Ajax Views

August 2, 2006 at 9:46 am (Ajax, Domino)

For the uninitiated: Ajax stands for Asynchronous JavaScript and XML. This is the technology that is providing Web applications with rich, desktop-like features; just take a look at Google Suggest and Google Maps, for instance. An Ajax application does away with the standard start-stop-start HTTP mechanism hitherto used, and makes user interaction appear asynchronous. To read more about Ajax, this is a great introductory article.

Now, the conventional mechanism to display a view in Domino is to use the $$ViewTemplate form. Of late, the embedded view has found favor amongst many developers as well. A third way is to build an Ajax view using a JavaScript class (yeah, JavaScript does ‘support’ OOP). This method basically consists of using the ReadViewEntries url-command to build the view.

function NotesView(url)
{
 this.xmlDoc = new ActiveXObject(“Microsoft.XMLDOM”);
 this.xmlDoc.async = false;

 this.xmlDoc.load(viewURL + “?ReadViewEntries&count=-1″);
 xx = this.xmlDoc.getElementsByTagName(“viewentries”);
 c = xx.item(0);
 d = c.getAttribute(“toplevelentries”);
 this.docCount = d;
 this.dbColumn = dbColumn;
}

The usage of the this keyword above indicates that docCount and dbColumn are respectively a member-variable and member-method of the NotesView class, and not mere variables. A simple version of the dbColumn function could look like this:

function dbColumn(colNo)
{
 var colEntry = new Array(0);
 viewEntries = this.xmlDoc.getElementsByTagName(“viewentry”);
 var curCol = 0;
 
 for (i=0;i<viewEntries.length;i++)
 {
  entryData = viewEntries[i].getElementsByTagName(“entrydata”);
  
  for (k=0;k<entryData.length;k++)
  {
   curCol = parseInt(entryData[k].getAttribute(“columnnumber”));
  
   if (curCol == colNo)
   {
    entryText = entryData[k].getElementsByTagName(“text”);
    for (j=0;j<entryText.length;j++)
     colEntry.push(entryText[j].firstChild.nodeValue);
   }
  }
 }

 return colEntry;
}

In this simple version of a dbColumn function, we merely iterate through all the columns until the column# that was passed as a parameter is encountered. Then, all the values in that column are oushed into an array which would form the return value of the function.

With this NotesView class, building a ‘dynamic’ view is no big deal; it is just a matter of collecting all (or just the necessary) columns of the view and displaying it in a well-styled table. I personally use it for categorized views – displaying the categories on the left and the category details using the NotesView class (of course, then the url used by the class would contain a RestrictToCategory parameter as well).

Permalink 12 Comments

Using nifty ‘Google Suggest’-style search-pages

August 2, 2006 at 3:13 am (Ajax, Domino, Lotus Notes)

The new Google Suggest site rocks, I have always thought. Hence while implementing one of those boring search-pages all over again, I thought – why not come up with a stylish auto-suggest interface? The next three articles will be a primer on how to implement this.

Permalink 3 Comments

Follow

Get every new post delivered to your Inbox.