dominoGuru.com

Latest Updates

Loading... Please Wait!

Products & Applications

Showtime
My Blackberry Enterprise Server Push Utility for the Lotus Notes Client, allows you to create Jobs for individual Channel, Message, and Browser Content Pushes, as well as allows you to delete Pushed Channel Icons from defined recipient devices.

Time Tracker
The idea is simple. At the start of your day - upon completion of your first task - create an entry highlighting what you did and whether you feel it was an efficient or inefficient use of your time. Based on several requests, you can also select the priority, apply categories, or even align your time against a project.

For Lotus Notes Client v8.0 and above, you can use the Time Tracker Widget to make this process even easier!

Zephyr
My Configuration-based Rich Text Mail Merge and Emailing Utility, Zephyr allows you to create rich, data-driven emails to support automated workflow - all via Microsoft Word Mail Merge-like architecture. Dear <firstname> allows you to personalize each email message not only to the individual recipient, but also to the individual application workflow event!

xCopy
xCopy is a simple configurable xCopy client for the Lotus Notes client. By creating and defining xCopy Profiles, you can batch process your file backup or remote upload jobs. With the addition of the xCopy sidebar widget, you can easily kick-off these jobs, and modify both the xCopy Profiles and xCopy itself.

Community & Resources

Lotus Technical Information & Education Community

The Lotus Technical Information & Education community is comprised of IBM, business partner, and customer subject matter experts who use product wikis, published articles, white papers, community blogs and the latest in social media to build and share high quality technical content.

OpenNTF.org - Open Source Community for Lotus Notes Domino

OpenNTF is devoted to enabling groups of individuals all over the world to collaborate on IBM Lotus Notes/Domino applications and release them as open source.

developerWorks Lotus : Wikis

Share your deployment experiences and best practices in our wikis and help IBM to create scenarios for successful deployments. Contribute to the community by collaborating on shared content and leverage the shared knowledge from that community.

Welcome to dominoGuru.com!

Focused on being the go-to resource for the IBM Lotus Notes Domino developer, dominoGuru.com delivers introductory-level best practices and advanced development deep dives for the IT professional, book and gadget reviews, and technical weblog, and more!

Quick Hack: Controlling the Render Form of a NotesDocument in the Lotus Notes Client

07/29/2009 12:03:36 PM by Chris Toohey

As I am ever discussing the need to separate the NotesDocument from Form Design Element binding - in other words, separating UI from the DataStore - I thought that I'd pass you a quick tip.

First, the scenario:

I have a Lotus Notes Client-based application that contains a simple document approval engine. Each approval document is a response NotesDocument to the parent NotesDocument which contains the overall status and miscellaneous document data. There is a business logic to which NotesDocument and Form Design Element is displayed based on who you are in the system or the current state of the NotesDocument.

For example, while the NotesView shows me the given document, I might be launching my individual review response NotesDocument, or a reader response NotesDocument, or the actual document.

Use Form Formula? Well, I do... but not how you might suspect. See, remember that I might need to launch the document or one of it's specific responses (my review NotesDocument).

Simply put, I need to be able to control what's opened regardless of how it's opened.

The tip:

document is not a UI component per se, but rather a "stub" Design Element that relies on the application logic to render a given NotesDocument via it's PostOpen event.

Example A Sub Postopen(Source As Notesuidocument)

  Dim s As New NotesSession
  Dim w As New NotesUIWorkspace
  Dim rcol As NotesDocumentCollection
  Dim rdoc As NotesDocument

  Set db = s.CurrentDatabase

  Set rdoc = Nothing
  Set rcol = source.Document.Responses
  If (rcol.Count > 0) Then
   Call rcol.FTSearch(|[reviewer] = "| & s.CommonUserName & |"|, 0)
   Set rdoc = rcol.GetFirstDocument
   Call w.EditDocument(True, rdoc)
  End If

 Call source.Close(True)

End Sub

Pretty basic right? Well, here's the trick that will allow you to open that - in the above case - review NotesDocument with any Form you wish.

Example: Sub Postopen(Source As Notesuidocument)

  Dim s As New NotesSession
  Dim w As New NotesUIWorkspace
  Dim rcol As NotesDocumentCollection
  Dim rdoc As NotesDocument

  Set db = s.CurrentDatabase

  Set rdoc = Nothing
  Set rcol = source.Document.Responses
  If (rcol.Count > 0) Then
   Call rcol.FTSearch(|[reviewer] = "| & s.CommonUserName & |"|, 0)
   Set rdoc = rcol.GetFirstDocument
   Call rdoc.replaceItemValue("form", "reader")
   Call w.EditDocument(True, rdoc)
  End If

 Call source.Close(True)

End Sub

Pretty simple right?

This allows me to open rdoc with the reader Form Design Element.

The only caveat to this approach would be if I needed to actually save content back to rdoc but wanted to ensure that the form NotesItem wasn't overwritten with my reader value.

... which is something I'll save for tomorrow's post.

When do you NOT help?

05/18/2009 12:47:26 PM by Chris Toohey

Maybe it should be a Yellow Hatter?I was contacted the other day by someone who came across my website -- specifically my Disabling $KeepPrivate documents! article -- who was looking for a method to add a Readers-type NotesItem to selected emails in his mail NotesDatabase. The issue that he was running into, he explained, was that his company prohibited personal Agents (and I suspect that each user only has Manager access to their mail NotesDatabase).

After explaining the potential issues with doing this - from the obvious "you could potentially lock yourself out" to the potential legal and corporate policy implications - I found out that he was concerned about his "nosey" boss reading his email.

Now, while I want this person to know that there are capabilities within the Lotus Notes client that will allow them to gain a richer experience and can improve the way that they perform their day-to-day functions, I don't want to condone such actions by me telling him how to do this.

And therein lies an issue: where do you draw the line?

I like to consider myself - at times - a Lotus White Hatter, but one person's White Hat can be another's Black Hatter. And in this particular case, I think the actions - at best - would be considered black hat, if not actionable!

So, Constant Reader, have you run into a similar situation?

Public Build: Event Calendar - Misc. Updates

02/25/2009 05:22:44 PM by Chris Toohey

Event Calendar It's been a while since I've updated the Event Calendar Public Build project... more due to me being extremely busy than not working on the build. Since my last video, I've put some considerable work into the application. It's still Notes Client-only at the moment... and for good reason: we're far from done! See, one of my goals with this particular project was to show you how to take a Notes-based application and ready it for the web... and I wanted to build a pretty feature-rich and configurable (which is key!) before I jump into the web-build of this particular project.

So what have I been doing?

Well, for starters I've added a facility that will allow you to assign Groups (from an Admin-defined list) as an additional level of categorization... and read-access restrictions - all configurable at the UI level to the Event Author via a Restrict to Group? flag.

Event Calendar Entry

You'll also notice the Reservations Embedded View - pretty self-explanatory there: user's will be able to click-and-subscribe to events!

I've also done some considerable work with the Preferences engine: specifically adding more keywords (which was simple enough, and a given really), and the Admin-defined Color-coding... with a twist. See, I'm allowing you to define the Color Profile Formula in a Formula field - using placeholders for the font and background colors - and I then apply the Runtime Formula (which is a Computed and evaluated version of the Admin-defined Formula).

Event Calendar Preferences

If that wasn't enough, I've also allowed you to define the default action of the New Event button via the Preferences document's Default Action. Selecting Event Form will wire the button to launch the simple single-entry Entry|entry Form Design Element, while selecting Event Wizard will wire the same button to instead envoke the New Events Wizard. This wizard, which is lifted from my Lotus Notes Client Wizard components example download, will allow the user to create multi-day event entries in the Event Calendar as well as drive the creation of the standard single-day event.

Event Calendar New Events Wizard

All of this resulting in a very simple, but very functional Lotus Notes Client application that can handle basic Event and Reservation management!

Event Calendar

The next step, prior to the web build, is the C&S (Calendaring and Scheduling) integration. The intended goal is simple: click on an event, and a new Meeting invitation is sent from a simple standard Mail Database Application, containing all of the Event information, and putting those individuals with reservations into the invite list - where we'll leverage the built-in C&S functionality in the standard Mail Application Template... which is something I certainly don't want to hack around in or attempt to re-write!

I'm on the fence as to whether to public this particular design release yet, which is admittedly incomplete. See, I don't want someone to take this application as a finished product and start using it... because the finished product will kick this one in the nards!

... but if I get enough "gimme-gimme-gimme!" feedback, I'll post what I have so far for download and dissection!

XPages, XHTML and Domino-generated Form supression

11/18/2008 10:36:45 AM by Chris Toohey

So maybe I'm just slow on the uptake, but I had no idea that you could use your own XHTML markup in an XPage through the Source Pane, and have that markup render along with your XPage!

XPage Source + XHTML markup

This was news to me, and opened up a whole new world of development with XPages as I now didn't have to rely on the XPage Design Pane in DDE to build some pretty amazing UIs for my Domino Web Applications. Using my preferred XHTML markup editor - TopStyle in this case - I can write my own UIs in markup and then quickly "port" them to XPages... where I can use the power of NotesDocuments and NotesViews to not only populate content but also generate markup when needed. But I'll get into more on that with an upcoming article I'm writing for developerWorks on XPages and Themes (and Mashups and Public Web Services...).

The real eye opener came when I found out that I could supress the Domino-generated <form> via a flag on the XPage. I'll say that again... I didn't have to hack my way around Domino "helping" me anymore by using the Navigator+Navigator Template or adding </form> to the top of my Form Design Element or any of the countless other hacks that we've all used over the years - I could tell Domino to just give me what I want and "roll my own" <form> elements to be rendered to the web browser client via a flag on the XPage!

There is a Properties entry point, but below is the direct Source Pane method for setting this option - in all of it's simple glory!

XPage Source - No [Domino-generated Form] means No!

You'll see more of this type of extended XPage stuff in the aforementioned article, which will be a "build diary" for an XPage-based Employee Tracking Mashup with OpenStreetMap.org and geoCoder.us. If you haven't heard me say this before, I'll say it now: XPages rock!

Now if I could only control the Content Type... that would solve all of my problems...

Using getElementsByClassName and CSS to create location-sensitive navigation

06/01/2006 10:09:53 AM by Chris Toohey

So with me currently looking for contracts, I've had the opportunity to work on some back-burner projects and exercises that I've been holding off on for the past several months. One of these projects was the re-development of my DHTML Menu Builder (a v2.0 if you will). One of the goals of this version is to greatly clean up the web-based user interface for the application and (quite frankly) make it look like more of an application than an exercise that happens to produce a usable DHTML menu.

So the latest web UI called for a tabbed interface for the application - allowing you navigate through a large form in a smaller container/footprint. While this was a simple task, I wanted to streamline the code to be as light and expandable as possible (as I'm certain that the UI of v2.0 will be ripped apart and used in other applications). So I started first by doing a little research.

Did you know that it's slower to change element styles via Javascript than it is to simply change/append a className? I didn't either! So, armed with this new information, I decided that I was going to do the following with my tabs: All tabs would have the className of "tab_inactive" except the default tab, which would have the className "tab_active". Onclick of the tab, I would simply cycle through all active tabs (in case there were multiple active tabs onload), and set their className to "tab_inactive". My onclick function would designate which tab was to be set as an active tab, so my function would then take this designation and set the element's className to "tab_active". Pretty simple stuff really, and pretty simple to accomplish once you think about it that way. So, I then added the javascript from Robert Nyman's Ultimate getElementsByClassName which would be used to cycle through the DOM document and grab elements that had the "tab_active" className, and with this created a very simple function (seen below):

function settab(atab) {
var myArray = getElementsByClassName(document, "li", "tab_active");
for ( var i=0, len=myArray.length; i<len; ++i ){
myArray[i].className = 'tab_inactive';
}
atab.className = 'tab_active';
}

And now, for my HTML markup. We will define the active and inactive tabs to start, as well as the to-be-active tab onclick in our settab() function:

<ul id="tabbednavigation">
<li class="tab_active" id="tab1" onclick="settab(document.getElementById('tab1'));">Tab 1</li>
<li class="tab_inactive" id="tab2" onclick="settab(document.getElementById('tab2'));">Tab 2</li>
<li class="tab_inactive" id="tab3" onclick="settab(document.getElementById('tab3'));">Tab 3</li>
<li class="tab_inactive" id="tab4" onclick="settab(document.getElementById('tab4'));">Tab 4</li>
</ul>

Alternately, if the current element is the to-be-active tab, you can simplify this function further by utilizing this. For example: <li class="tab_active" id="tab1" onclick="settab(this);">Tab 1</li>

And now, to make this work (visually now, as the elements should have their classes swapped as per the logic defined in the settab() function), we will define the element classes in CSS. We'll create two different visual states for the tab - active and inactive:

ul#tabbednavigation {
padding-bottom: 5px;
border-bottom: 1px solid #333;
margin: 10px 5px 10px 5px;
}

ul#tabbednavigation li.tab_active, ul#tabbednavigation li.tab_inactive {
list-style: none;
padding: 5px;
margin: 0px 2px 0px 2px;
display: inline;
border: 1px solid #333;
background-color: #f1f1f1;
border-bottom: none;
cursor: pointer;
}

ul#tabbednavigation li.tab_active {
border-bottom: 1px solid #fff;
background-color: #fff;
}

And wth all of this, you now have a fully functional location-sensitive tabbed navigation engine for your web-based UIs.

  • Tab 1
  • Tab 2
  • Tab 3
  • Tab 4