Latest Updates

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!

NotesDocument READ and UPDATE with AJAX calls to Domino Agents (or Simple Inline View Editing over the web) - Build, Demo, and Download

09/22/2009 10:30:03 AM by Chris Toohey

Building off of my example from yesterday, I thought that I would show you how we can quickly and easily create READ and UPDATE functions for NotesDocuments via calls to our (modified) HTTP Request Consumer Domino Agents. And, to spice things up, I thought I'd do it all via AJAX.

Build Synopsis

HTTP AJAX NotesDocument Mods Example NotesDatabase

That's the end-goal - a simple NotesData table that will allow us to change the Status of a given NotesDocument.

To get to that goal, I'll take the Agent Design Elements from yesterday - creating one for the READ and another for the UPDATE function. But first I need to ready the Page Design Element that acts as the Default Launch Object for the NotesDatabase, which will act as the display for our NotesData table.

Phase One: index.html Page Design Element

The index.html Page Design Element - just like with yesterday's example - is extremely simple by design: I want to focus your attention to the functional capabilities of having your Web Applications (Domino or non-Domino technologies-based) interacting with the HTTP Request Consumer Agents.

We'll focus on the HTML Form Element and the JavaScript functions, as the rest of the HTML markup is either descriptive/introduction or my Paypal Donation stuff.

The HTML Form Element contains the following markup:

<form action="#" name="moddocs" id="moddocs" method="GET">

<div id="viewbody"> </div>
<script>getdocs(document.getElementById("viewbody"));</script>

</form>

The JavaScript functions - there are two - are:

var http = false;

if(navigator.appName == "Microsoft Internet Explorer") {
http = new ActiveXObject("Microsoft.XMLHTTP");
} else {
http = new XMLHttpRequest();
}

function getdocs(target) {
http.open("GET", "getdocs.agent?open", true);
http.onreadystatechange=function() {
if(http.readyState == 4) {
target.innerHTML = http.responseText;
}
}
http.send(null);
}
function moddoc(val, UNID) {
http.open("GET", "status.agent?open&status=" + val + "&UNID=" + UNID, true);
http.onreadystatechange=function() {
if(http.readyState == 4) {
getdocs(document.getElementById("viewbody"));
}
}
http.send(null);
}

getdocs() simply grabs getdocs.agent Agent Design Element-generated markup and sets the innerHTML of the passed-thru HTML Object (via an AJAX call). moddoc() passes two values to the status.agent Agent Design Element: the new value of the status NotesItem and the target NotesDocument UNID (again, via AJAX). When it's complete, it runs another AJAX call to getdocs() to refresh the NotesData table.

All I need to do from here is make sure that my NotesData table has the markup it needs that wires into the moddoc(). Pretty simple, as via the getdocs() function I have absolute control over what's returned to the Web Browser Client.

Phase Two: HTTP Request Consumer Agents

The getdocs() and moddoc() simply require a modification to their respective Initialize subroutines to both deliver and update our NotesDocuments.

getdocs.agent Agent Design Element - Initialize

status.agent Agent Design Element - Initialize

... and that's it. The getdocs.agent Agent Design Element generates the markup that we need: the onchange event of each SELECT HTML Element passes the newly-selected value and the target NotesDocument Unique ID to the moddoc() JavaScript function, which calls our status.agent Agent Design Element. This processes the request - using the submitted UNID and status parameter values to find the target NotesDocument and update said NotesDocument status NotesItem respectively.

After that, we simply "refresh" the UI via another AJAX call... and we're done.

Online Demo, Example Download, and Closing Remarks

Again, for those of you who prefer an online demo complete with downloadable example, I've got you covered.

The code written in this series is - how should I put this - not ideal. In a "best practices" scenario here, you'd want to return something like JSON, and parse that JSON return locally. This code is about as simplified and straight forward as it gets - I didn't do anything that would subtract from the goal of this article: getting you to understand just what you can do with an HTTP Request Consumer Agent Design Element.

Hopefully, this is a simple enough showcase that you'll start delving into this practice yourself - regardless of your comfort level with LotusScript, JavaScript, HTML Method calls, and AJAX. It's really powerful stuff here, and your web applications will definitely benefit from the overall approach.

Notice I said web applications - which is the second time in this article that I haven't prefixed Domino as normal. I use this approach with Flash-based Banner Ads, simple HTML Forms hosted on IIS and Apache, and countless other scenarios. It's ultimately no different than using Google Web Services or any other SaaS or Cloud service. I take that back actually - using this approach, you can quickly and near-immediately bring Lotus Notes Client-only applications onto the Web and Mobile Browser Clients: simply point the target NotesDatabase to a different NotesDatabase, Domino Server, etc. and you have yourself a very powerful NotesData proxy on your hands...

Breaking News: IBM developerWorks Lotus - New Wiki Home Page!

08/05/2009 10:20:02 AM by Chris Toohey

IBM Lotus Wikis Complete with customer and contributor testimonials and showcased Top Contributor and New Contributor profiles, the new developerWorks Lotus Wiki Home Page acts as a gateway into all of the IBM Lotus and IBM Websphere product family Wikis.

They even put a quote from some hack who thinks himself a guru of sorts:

"With technology, printed materials become dated before they're sent to the editor; improvement of application and technique change almost hourly. Content creation and community interaction--via mediums such as Product Wikis--are invaluable to establishing 'living documentation' which can evolve in tandem with its community."

The product wikis are an amazing resource to both customers, business partners, and even to IBMers who can quickly access best practices tutorials as well as a deep well of feature functionality for each Lotus and Websphere product.

This is why I cannot stress the importance of cross-posting article content: establishing the product wikis as an authoritative master resource for customers - be they product customers, the aforementioned business partners, or even the aforementioned IBMer - will do nothing but strengthen the product, empower the customer to extend their usage of the given product, allow the genius-level contributors to this Lotus Online Community to further establish themselves as subject matter experts, and ultimately benefit everyone involved.

Not contributing to the wikis today? You can use your IBM Sign-in and contribute something - there's a lot of room out there for contributions.

And if you're a blogger who is interested in cross-posting content - or anyone who has an idea for an article-length contribution - let me know and we'll chat - there's a Recognition Program eager to give you credit for your contributions!

Domino URL Schemas for Domino CRUD API READ States

06/04/2009 12:59:41 PM by Chris Toohey

I posted a question yesterday across the various social networks (Facebook, MySpace, Twitter, LinkedIn, BrightKite, etc.) asking the following:

Do you prefer db/view/doc or db/doc?open&UNID=X architecture for the front-end of the Domino CRUD API & web development?


... and I got some amazing feedback. Before I go into the feedback on the idea - which I'll admit 140 characters didn't quite do justice - I'll elaborate.

The Thinker Every Domino Web Application Developer has used the db/view/notesdocument URL Schema for accessing a NotesDocument in a Domino-based NotesDatabase. That's the standard usage scenario. It's what we have all been taught. It's how Domino RAD drives us to develop.

But I'm curious... is there a better way? Specifically, does the db/Page_or_Form?open&UNID=X URL Schema, when combined with @URLQueryString and @GetDocField, lend to a better NotesDocument and NotesData access scenario?

No, I haven't done benchmark testing yet on this, but avoiding a View Design Element that does nothing at times but add bloat to a NotesDatabase - to me - is just one of the many potential benefits to this approach.

Now, a few things that people brought up and that I think definitely should be mentioned:

  1. This can impact/break URL Walking
    Simply put, you can't delete the NotesDocument and expect to see the View.

  2. Most Domino Web Application Usage Experiences warrant Views
    ... so why not just use the View.

  3. This can impact URL Permalinking
    Basing the URL up a NotesDocument UNID is easy, but it breaks any permalinking functionality, which can cause problems for bookmarking content or Search Engine Optimization.

Now, I have an address for each of these items:

  1. This really depends on the expected usage experience. Do I want to return - potentially - a listing of all content if I navigate away from a specific content entry (NotesDocument)? Depending on the application, I might not want to. As for this "breaking", you can handle a missing UNID and where to redirect in that event in the design architecture.

  2. Again, depends on what you need the application to do. For an application like Email, this meta-viewing of entries makes sense. For an application like a requisition, helpdesk, or jobs database, I don't think you'd want to return the customer back to a listing of all entries.

    As far as rendering a NotesDocumentCollection in the UI, some could argue that unless there is a continuous update on View Entry contents, using a View can be unnecessary overhead. For example, if I were to render an entire "View Index" into a single NotesDocument as JSON and return those contents, I'm getting the exact functionality I would require without that overhead... but I'm getting ahead of myself here.

  3. This... this I'm working on.

For that last one, consider a technique that I've mentioned in the past (Nathan T. Freeman's Andrew's Allusion (or Creating Primary Keys in NSFs)), where with db/Page_or_Form?open&UNID=X, X is something like index.html. The content - when created - is assigned a plain-text UNID by the customer (ie., index.html). Post submission, the NotesDocument UNID is set to @ReplaceSubString(@Password(UNID); "(":")":":";""). This hash - for those curious - would result in a completely valid UNID (3A8A735F029991B9844D181AE297DDDE).

But I'm again getting ahead of myself.

Back to the original question: which method works best? I personally think that - once you have a handle on the UNID, @GetDocUNID would return a NotesDocument much faster than lookup via NotesView. Why? Well, consider this:

When you access a NotesDocument by it's UNID from the Web Browser Client via the db/view/UNID URL schema, the view simply becomes a placeholder, and is quite frankly ignored. Next time you see a Domino Web Application that uses this UNID URL schema, replace the view with either a 0 (zero) or thisviewdoesnotexist. Both will result in the NotesDocument being rendered. The View however is considered for things like Form Formula etc., as long as you don't use a zero or a non-existing element name.

I dunno, that sounds more dangerous to me than breaking the URL Walking and could potentially be another feather in the cap for the db/Page_or_Form?open&UNID=X URL Schema.

But like I said, I've yet to do any real benchmarking on this to see which is indeed faster or weigh the true benefits of one approach over another. For that, I'll open up the comments. Weigh in and let us know what you're thinking. If we get enough interest, I'll update the Understanding the Domino CRUD API Example Database to use both techniques.

Understanding the Domino CRUD API: $$Return and Smart Landing Pages

04/16/2009 02:00:58 AM by Chris Toohey

In the last video, I showed how you can use the $$Return in combination with some basic markup to create a simple Create and Update submission confirmation message or redirect to a URL.

In this video, I talk about creating a context-sensitive Smart Landing Page that uses a combination of Page Design Element, URL QueryString Parameter, XHTML, and some JavaScript to create a user experience that we're used to in Web Browser Applications.

Consider this my entry for Show-and-Tell-Thursday. ;-)

Questions, comments, and suggestions welcomed and appreciated!