Wednesday, December 20, 2006

Quick Tip: Colored "OS Style" Field Borders

A colleague of mine recently asked me if it was possible to create fields that are OS style in the Notes client, but change the border of the fields to some color other than black. I always work under the assumption that there is some kind of trick, hack or workaround I can come up with when designing with Notes, so I played around with some ideas until I figured it out.

First, let's look at the OS style field option and what we get with it. When designing a field, you can choose to make it look more "Windows-like" (or "Mac-like" or whatever the flavor of your operating system) by selecting the "Native OS style" option. When you do this, you can control the formatting of the field slightly by manipulating the border style and setting the background color. However, Notes does not give you an option to manipulate the size of the border or its color.

Here's the trick for designing the border however you'd like. Instead of using the border style properties of the field, enclose the field within a table cell and set the border style of the field to 'None'. The border for the table then effectively becomes the field's border. Since it is just a standard Notes table, you can style it up however you'd like, changing the border weight, color, etc. Here's a few examples:

The design of the first one is borrowed from Trans-Siberian Orchestra's fan club sign up page. I changed the fields to be light colored orange with a dark orange border (by the way...here's another great use for layers...putting fields on top of a background).



The second example is from an actual document library database, which shows a more subtle use of this effect. The borders of the field are light grey instead of black, which makes them blend better with the overall color scheme of the page.



The final example is pretty out there, but it shows what you can do if you experiment a bit. In this case, I gave the tables that enclose the fields a border style of "Image", selected an image from the database and increased the thickness to seven pixels. Quite an interesting effect.



Keep in mind that all of these screenshots are from the Notes client. Don't believe me? :-) Here's a shot in design mode (showing all of the relevant settings of course).



A couple of other things to keep in mind:

-If you want to control the width of the field, use the OS style and set it to a fixed width. Make sure to turn off the "Allow multiple lines" display option on the second tab. This will prevent the user from using a carriage return in the field.

-If you want your field to be able to grow as the user types in text, use the standard Notes style field and then uncheck the option to "Show field delimiters". If you choose to use this type of fluid design construct, make sure it will not mess up the formatting of your form as the table grows.

Overall, this is an elegant and easy to implement solution. Just how I like it.

Happy Holidays everyone!

Monday, December 18, 2006

Quick Tip Update: Images In Views

Well, I had a couple of questions on how I made that view in my last post. Here it is again, just so we're all talking about the same thing:



It's not such a trick to get this working...more just playing around until you get it looking like you want it. In this case, the view design has four columns. The first is the categorized column which shows the Artist and CD Title. In this case, I'm using it as a "header" of sorts. The second column contains the CD cover image (which is the image resource referenced in the "txt_Image" field on the document) as discussed in the previous post. The third column, which I guess is what people are asking about, is just set with a multi-value separator of "New Line". In order to center the text, I just concatenated the various fields together, with some null values in front. Here's what it looks like in Designer:



There's one more column in this view and this is kind of a trick. Perhaps there is a better way to do this. If so, please let me know. In the design, the number of rows is set to 9. However, the size of the row is determined by the column with the largest text size. In this example, my icons were too big and were being cut off since the rows weren't tall enough. To correct this, I inserted a column at the far end which has a null value. The text properties for this column are important, though, since they control the height. I left the font as "Default Sans Serif" and changed the size to 130. Upon doing this, voilĂ ...the perfect spacing I wanted.

The track listing is provided via an embedded editor. The form that is being used has all of the fields hidden when embedded except for the rich text field that holds the track info. Here is the form in design mode showing the embedded editor and embedded view:



In order to associate the embedded view with the embedded editor, just set the embedded view's Target properties to the same name as the name of the embedded editor. When you do this, clicking on the entry in the view will show the corresponding document in the embedded editor, which in this case displays the track listings. Tre cool! :-)

Friday, December 15, 2006

Quick Tip: Images In Views

File this one under "stuff I thought everyone knew, but turns out some people missed it". With all the talk about the new view icons over on Mary Beth Raven's blog (and subsequent spillover to Nathan's), it reminded me that I wanted to do a short post about using your own custom icons in a Notes view. I often make my own view icons so that the context more closely represents what my application is all about. At the Lotus Developer2006 conference in Vienna, I showed a demo database that happened to make use of this idea. I didn't address the technique, nor did I mention anything about the view icons, but I was actually asked on three separate occasions during the conference how I "got those icons in the view". Thus, today's Quick Tip is how to do just that. Luckily, it couldn't be easier, which makes for a nice Friday post! :-)

To use your own custom view icons, you need to drop the icons you want to use into the database's Image Resource section. Once your icons are there, create your view column and set the property to "Display values as icons", Now here's the trick...instead of referencing a number (which allows you to use the built-in Notes icons), simply enter the name of an icon in your Image Resource section (e.g. "newdoc.gif"). Of course, usually you'll want to use a formula to calculate this. Perhaps you have different status icons that represent the state of a document. Just setup the column as you always do and reference the image names rather than the numbers and you're good to go. Another nice thing about using this technique is that the name that you give the image resource will be shown to the user when they mouse over the icon. Thus, you could write some nice descriptive text such as "This document is ready for review".

Creating your own icons is cool, since there are some neat things you can do. Here's an example of an embedded view that has CD images. It's in a form with an embedded editor, so that when the user selects the document, they also see the track listing without actually having to open the document.




If you get creative, you can really extend these ideas to make some powerful apps. For example, you could allow the user to attach a file that would be used as the view icon for a document and then you could have code to extract the attachment and automatically make it an image resource so it could be shown in the view (several folks have done this with DXL...a quick search should turn some up).

Well...I hope you all have a great weekend. Cheers!

Thursday, December 14, 2006

Lotusphere BOF: Designers Unite!

Hi Folks. Along with the session that Nathan and I will be doing at Lotusphere 2007 (BP101 - Designing the User Experience: Why Your Interface Matters), we're also proud to be your hosts for one of the Birds of a Feather sessions.

There are a lot of Notes developers out there that have been putting nice UI designs together and even more that are interested in the topic. So please come join us for BOF202 - Designers Unite: Developing Innovative Interfaces In IBM Lotus Notes and share your thoughts, experiences and expertise. We're scheduled at 7AM on Tuesday the 23rd in Y&B GH Salon VI.

Birds of a Feather sessions are designed to allow like-minded individuals to come together and trade ideas, ask questions, etc. Interface/user experience design is an especially great topic for a BOF, since this is such a fast moving and dynamic field. If anything, the whole "Web 2.0" craze has ignited a lot of innovation in the UI design arena, and provides us with a lot of material to discuss.

I've included the BOF description below. If you think this kind of thing is up your alley, then we hope to see you there!

User Interfaces…they’re not just about pretty pictures and matching colors. This Birds of a Feather session is intended to draw together IBM Lotus Notes developers that are passionate about usability and user interface design. Learn from others how interface design can be integrated into your development methodology, and get real world insight on how to build more exciting and dynamic interfaces that can make users more productive. Take the opportunity to share ideas and best practices about a topic that is becoming more important on a daily basis as users become more savvy, sophisticated and demanding.

Tuesday, December 12, 2006

To The Person That Found My New Blackberry...

...and returned it: THANK YOU, THANK YOU, THANK YOU! You've reaffirmed my faith in humanity (at least for this week) :-)

Although they will most likely never see this, I have to thank the person(s) that returned my Blackberry. On Sunday, the family and I trekked out to our favorite Christmas tree farm about an hour and a half from our house. We've been going there for many years...great place. You take a horse-drawn wagon ride out to the fields, look for the perfect tree, chop it down and bring it home. This year the pickings were pretty slim, so we walked way to the back of the farm. Out of the blue, I feel the telltale burst of a snowball against my back. Soon, I am being assaulted on all sides by my kids and it's on...a massive snowball battle thus begins. We go at it hard core for about 10 minutes before everybody tires themselves out, then it's on to continue our search for the perfect tree. Eventually we give up and decide to head back to the barn for a picnic lunch by the fire. As we start to pack up, I look down as I put on my jacket and notice my phone holster on my belt...minus the phone!

Well...stupid me, I forgot to remove my 4 day old(!) Blackberry 8703e from my belt before getting out of the car. In the ensuing chaos of the snowball battle royal, it must have slipped out of the holster and ended up in the snow. Upon realizing this, my son and I run out to the fields and begin to retrace our steps, but to no avail...the phone is lost. Dejected, I give my name and number to the owner of the farm and ask them to call if by any chance someone finds it.

After getting home, I notice a message on the answering machine. It's completely garbled, but we can make out a few words. It sounds like a couple of little kids and a dad and I swear we hear "blackberry" and "does it work?". So, it appears someone may have found it and hit my home speed dial by accident. I continue calling the phone, but there is no answer, so I give up for the night. Well...imagine my surprise when I get a call from the owner of the place later that evening. Someone did indeed find it and they turned it in when they got back to the barn. How cool is that!!! I got it back yesterday and amazingly, not only does it work, but it doesn't have a scratch on it!

Anyway, this story obviously has no bearing on Notes at all, but I thought I'd share since, even though we sometimes lose sight of it when we listen to the never ending bad news from the media, there are still a lot of good people out there who try and do the right thing. Here's to them...Cheers!

Monday, November 27, 2006

Off To Vienna...

I'm on my way out the door to head for Vienna today. I'm repeating my Vegas sessions at the Lotus Developer2006 Europe conference. I hope I'll get a chance to see some of the sights...I know it's a beautiful city, but there's always lots of work to be done. In any event, if you are attending, please stop by and say hello. Cheers!

Monday, November 20, 2006

Comments Issue

I was converted to the beta version of Blogger about a week ago. So far, not too many issues, but as of the last few hours, it seems that comments are not being posted. Well, actually, they seem to be, as I am getting e-mail notification of them, but they are not posting to the blog pages. Please bear with me as I figure this out...Thanks!

Sunday, November 19, 2006

Book Review: Lotus Notes Developer's Toolbox

Well, I'm certainly no Tom Duff, but I thought I'd share my thoughts on a new Notes development book that the fine folks at Pearson Education sent me a couple of weeks ago. The book in question, Lotus Notes Developer's Toolbox: Tips for Rapid and Successful Deployment by Mark Elliot, would do well to find a place on the shelf of every new and intermediate Notes developer. According to the back jacket, Mark has been employed by IBM since the early 90s and has implemented commercial applications for many large clients. He uses this background to craft a very solid technical book that covers a lot of ground.

While there is probably nothing new here for the truly advanced Notes crowd, I would recommend this book highly for those developers that have been working with the technology for a few years and want to fill in a lot of the gaps. Even better, this book should be required reading for someone new to Lotus Notes. Thinking back to my introductory days of Notes development, owning this book would have been a blessing. Mark does a fantastic job of starting at the beginning, introducing the reader to the concept of Notes. He explores often overlooked pieces, such as the various clients, installing Notes, an in-depth tour of the Designer client, etc. As Chapter 4 kicks off, we get into the actual architectural details of Notes before he launches into discussions of the Formula Language (Chapter 5), LotusScript (Chapter 6) and the fundamentals of a Notes application (Chapter 7).

The next several chapters are quite nice, as they focus on real-world applications. Each chapter introduces a new project (workflow app, calendar database, etc.), walking the user through all of the bits and pieces to get it going. There's even a section of the book that delves into web apps via Domino.

The remainder of the book builds upon information introduced before, focusing on specific techniques in LotusScript, Formula Language, building views, writing agents, etc. Mark rounds out the book by addressing data management, security, troubleshooting and application deployment and maintenance. Two appendices provide information about the related online materials and a discussion of Notes' future state. Of course ( and yes...I'm a bit biased), I'd have liked to see more emphasis on the importance of designing an attractive and usable interface in Notes, but I guess we'll need to wait for the sequel. ;-)

All in all, this is probably the most solid Notes development book that I've ever read. I especially liked all the "Note" sections that are interspersed among the text. These might be one of the most valuable parts of the book, since they point out little tips, tricks and pitfalls that many of us learned the hard way. For all of the beginning and intermediate Notes developers on your holiday shopping list, I'd be happy to recommend finding a place for Lotus Notes Developer's Toolbox on it.

Saturday, November 18, 2006

Fun With The DOM...Playing With The Action Bar

I promised some more technical articles awhile back and haven't delivered on that promise yet, so...here you go. I'm going to stray from my Notes client focus this time to talk about web development. In this post, I'm going to spend a little time dissecting the Domino-generated action bar as it is represented in the Document Object Model (DOM). While many blog authors have focused on ways to modify the look and feel of the action bar, if you utilize the power of the DOM, you can do much more. Like what, you may ask? How about:

Generating a right-click menu...



...or generating a dynamic drop-down menu...



...or whatever you can think up. Basically, if you know how to utilize the DOM to get a reference to the action bar object, you are limited only by your imagination. I'm sure smarter people than I can come up with even better techniques. But, since this is my blog, I'll give it the old college try and explain things as best I can.

My idea when putting this technique together was to allow the Domino developer coming from a Notes client background to write action buttons as they always do...no need to write special code for the web. Of course, it's my opinion that you should learn as much as you can about web techniques. When you do, you'll find yourself relying less and less on Domino-generated code. However, there's something quite satisfying about whipping out a line or two of formula language and having the code execute in the browser. If you think so too, read on.

When Domino generates the action bar (on a form, view, page, whatever), the underlying HTML that is created is a table. Each action button that exists on the design element is housed in its own table cell. To see this in action, just view the source (in your browser) of any page that has an action bar. Let's take an example view with three action buttons: "Expand", "Collapse" and "Create New Document". For now, the code behind these buttons is unimportant. What we care about is the HTML output. In this example, it would look something like this:


<table border="1" cellspacing="2" cellpadding="2">
<tr valign="middle">
<td><a onclick="showHide('descRow', 1) return false;" href="">Expand</a></td>
<td><a onclick="showHide('descRow', 0) return false;" href="">Collapse</a></td>
<td><a href="/DHTML2006.nsf/New?OpenForm" target="_self">Create New Document</a></td>
</tr>
</table>


As you can see, Domino creates a table with a single row and then generates three <td>s...one for each action. So far, so good.


Representations in the DOM

One thing that I've found when working with other Domino developers is although they have probably used techniques that manipulate the DOM in their applications, many don't really know about the DOM or understand what its about. Here's my (probably oversimplified) version: The Document Object Model describes an HTML document in a tree form. It basically allows you to use an object-oriented methodology to parse HTML and to operate on the contents of that HTML. When a page loads in your browser, the browser creates a hierarchical representation of all of the HTML elements. This hierarchical representation is often called the Document Tree. The document tree consists of "nodes", which are basically objects that have properties and methods. There are several types of nodes in the DOM, but usually we work with either element nodes or text nodes. An element node is a node on the Document Tree that was created by an individual HTML tag. For example, a <div> element in your code will create an element node branch of the tree. A text node is a node that is created by some general content...usually text. It's interesting to note that nodes can have many relationships since the DOM is hierarchical in nature. An element node can have child nodes, for example, or siblings, a parent, etc.

Let's take a look at a simple example that might explain this a bit better.

Assume we have a standard unordered list describing what happens at a typical rock concert from the perspective of the roadies.


  • Sound Check
  • Main Event
  • Break Down


In HTML, this is written as

<ul>
<li>Sound Check
<li>Main Event
<li>Break Down
</ul>


Represented as a document tree, it would look something like this:



The opening <ul> tag creates a new branch in the document tree...a new element node. This element node has three children, the <li> elements. These in turn have child elements as well...the text nodes that represent the content within the <li> tags ("Sound Check", "Main Event" and "Breakdown"). Pretty cool, yes?

Finding objects within the document tree is a matter of traversing the various nodes, using the relationship between elements. For example, if I have an object representing the first <li> element (let's say it has an ID of "node0"), then if I want to retrieve its parent, I would write node0.parentNode, which would give me an object representing the <ul> tag. If I wanted to get the text inside the middle <li> tag in our concert example, I could traverse the tree like so:


//Line 1 (assuming in our example that we want the first <ul> on the page)

var theList = document.getElementsByTagName('ul')[0];

//Line 2 (this would result in an alert box with the text "Main Event")

alert(theList.childNodes[1].firstChild.nodeValue);





Let's break this down:

Line 1 uses getElementsByTagName to return an array of objects representing all the <ul> tags on the page. We want the first <ul>, so we use subscript 0 to get the first object in the array.

Line 2 uses some of the node relationships to get what we want. childNodes returns an array of all the children of a given element node, while firstChild returns just that...the first child node. Thus, we are getting the second child of theList (the second <li> tag) and then the first child of that element (the text node that holds the content we want). Finally, nodeValue returns the actual text inside the node (i.e. "Main Event").

I don't want to go too deep here, so suffice it to say that there are many of these node relationships available (firstChild, lastChild, nextSibling, etc.) and it is quite worthwhile to learn them.

You can see from this fairly simple example that the document tree can get complex very quickly. A far easier way to traverse the tree is to use an element's ID attribute. You've probably done this before. The JavaScript to get a particular object is simply document.getElementById('idvalue'), where 'idvalue' is the ID attribute of the object in question. It is highly recommended that you give your elements ID attributes...it will make your life much easier. Going back to the simple example, let's put some IDs in and re-write the code.


<ul ID="concertList">
<li ID="firstPhase">Sound Check
<li ID="secondPhase">Main Event
<li ID="thirdPhase">Break Down
</ul>


Now to get the text in the middle <li>, we could simplify our code to:


alert(document.getElementById('secondPhase').firstChild.nodeValue);


Ah...much cleaner!

In addition to element nodes and text nodes, there is a special kind of node known as an attribute node. An attribute node is not really a part of the document tree, but it does provide a handy way of getting at attributes for a given element node. If you wanted to change the 'href' attribute for a link on a page from www.google.com to www.yahoo.com, you could do this by manipulating the attribute node of the <a> object. Assume the link had an ID of "thelink". The JavaScript to do this would then be: document.getElementById('thelink').setAttribute('href', 'http://www.yahoo.com'). You can manipulate attributes using:

setAttribute()
createAttribute()
getAttribute()
removeAttribute()
etc.

Again, I'd recommend looking into these functions in more detail...


Aside: To learn more about the DOM, check out the following great book:

Stuart Landridge, DHTML Utopia: Modern Web Design Using JavaScript & DOM (SitePoint, 2005).


OK...at this point you're thinking..."Great...thanks for all the boring DOM mumbo jumbo...on with the good stuff, geek boy!" I promise that this is important, though, since it will make manipulating the action bar seem really easy. So let's get to it, shall we?

As I mentioned at the top of the post, the Domino translation engine outputs the action bar as a table and it is always the first table on the page. So the first thing we want to do when manipulating the action bar is to get this object.


var actionBarTable = document.getElementsByTagName('Table')[0];


Next, we want to get all the <a> elements, since these hold the actual code to execute and the labels for the action buttons. Again, we'll use getElementsByTagName to return an array of all the <a> elements that are within the table.


var actionAnchors = actionBarTable.getElementsByTagName('a');


Now the fun begins...and this is where your imagination can come up with some great uses for the objects we have in the actionAnchors array. Usually, you'll iterate through the objects in this array to pull out the onClick events or href attributes and also grab the labels. So...how could you get information from the first action button?

To get the label, you would traverse the DOM:


actionAnchors[0].firstChild.nodeValue //remember...the <a> tag creates an element node and it has a child node which is the label text


To determine what the action actually does, you can check if it has an onClick event (if you coded your action button with JavaScript, then this will be true). If it doesn't, then it will have an href attribute (usually used to trigger an @Formula).


if (actionAnchors[0].onClick) {
do something with the onClick attribute;
}
else {
do something with actionAnchors[0].href;
}



Now, it's time to put these ideas together into a concrete example. Here's a sample database you can use if you want to follow along.

We are going to use the action bar generated by Domino to create a simple CSS drop-down menu. There are many freely available menus out on the internet and I encourage you to use the great work others have done. Don't reinvent the wheel...just use Domino to leverage it's power. CSS Menus are generally regarded as the most flexible and "safe" kind of dynamic menus since they rely on standard HTML tags which allow the menu to degrade gracefully in the event there is a problem with the CSS or the browser does not support a feature that is used. There are many excellent CSS menus available on the internet and a quick search on your favorite search engine will turn these up. For purposes of this demo, I'm using CSS Express Menus from projectseven.com.

To get started, there are a couple of downloads to grab from the projectseven website (these are already in the example database). You'll find the CSS (which is quite simple and elegant) in the page titled 'p7exp.css'. There is also a small snippet of javascript that is used to address some shortcomings in IE (p7exp.js). The structure of the dynamic menu is simply built with an unordered list. You can see a hardcoded example of this structure by examining the "StaticCSSMenu" form in this database. Here's the basic idea:


<div id="menuwrapper">
<ul id="p7menubar">
<li><a href="#">Home</a></li>
<li><a class="trigger" href="#">Trigger One</a>
<ul>
<li><a href="#">Sub 1.1</a></li>
<li><a href="#">Sub 1.2</a></li>
<li><a href="#">Sub 1.3</a></li>
<li><a href="#">Sub 1.4</a></li>
</ul>
more code here...
</li></ul>
<br class="clearit">
</div>


Note that the menu is a single, nested unordered list. Each link that acts as a trigger to show a sub-menu is assigned a class="trigger". The trigger class sets a downward-pointing arrow as a background image, indicating that a sub-menu is available. The code looks like this:


<li><a class="trigger" href="#">Trigger One</a>


Viewed without CSS, this code gives you the following:



It's fairly easy to style this unordered list, then, to provide the functionality we're looking for. So, the plain unordered list magically becomes:



Hopefully, at this point you are thinking you are thinking to yourself, "Self...with Notes, I can do all sorts of cool list processing and text manipulation. I bet I could dynamically create the unordered list and have a customized, on-the-fly CSS menu." Well, you are one smart cookie, since that is exactly what we are going to do...using the action bar as our source.

Let's review the first step in the process. This part is generic to any solution you would use to manipulate the action bar. The action bar in design mode for our example looks like this:



1. Iterate through the <a> tags in the Action Bar and create three arrays; one to hold the a flag that tells us what the action is (an href or onClick), one to hold the actual code and one to hold the label.


var whatAction = new Array();
var contextAction = new Array();
var labelAction = new Array();

var actionBarTable = document.getElementsByTagName("Table")[0];
var actionAnchors = actionBarTable.getElementsByTagName("a");
for (i=0; i < actionAnchors.length; i++) {
if(actionAnchors[i].onclick) {
contextAction[i] = actionAnchors[i].getAttribute("onclick").toString
().replace(/^function anonymous\(\)\n{\n/,"").replace(/\n}$/,"");
contextAction[i] = contextAction[i].replace(/return false/, "");
whatAction[i] = "click";
}
else {
contextAction[i] = actionAnchors[i].href;
whatAction[i] = "href";
}
labelAction[i] = actionAnchors[i].firstChild.nodeValue
}


As you can see, this code loops through the actionAnchors object, which is an array of all the <a> elements in the action bar table. In this loop, we check if the <a> element that is being processed has an onclick event. If it does, we use the DOM to get the onclick attribute and place it into the contextAction array. I'm doing some string manipulation at the same time in order to remove the function definition that the browser automatically sets up for the onClick event (see aside for more detail). If the action doesnt have an OnClick event, then it is using an href, so we place this code into the contextAction array. At the same time we add stuff to the contextAction array we also add the text of the action to the labelAction array and we set the flag in the whatAction array to let us know if the action was an onClick or href. Note that I could have used a multidimensional array to store all of these things, but I find it easier to work with multiple single dimension arrays.

Using the example in the database, here's what the arrays would look like if we visualized them as a graphic:



Aside: Different browsers use different function names for the functions that represents certain events. Here's a simple example you can try in your database to see what I mean:

Create a new action button and add the following JavaScript to it:


alert("Here is some simple code");
alert(this.onclick);


When you click this action button on the web, the second dialog box that appears will show you how the browser represents that onClick event. IE and some other browsers use the function name "anonymous", a function that does not define any arguments. Firefox and other browsers use the event name as the name of the function and they use an argument called "event" (which is the Event object that gets passed to an event handler).




Now that you have all of this information within your three arrays, the logic from here on out is dependent on what you want to do. In our case, we want to generate an unordered list. Notice the labels I used for the action buttons include text values separated by an "*". I did this in order to define both the drop-down text and the label for the action within that drop-down menu. Thus, we'll have three drop-down menus in our example, "Demo", "View Actions" and "Create". Making use of this, we're going to iterate through the arrays and throw the menu name into a variable. As we walk the array, if we find that the current label has the same menu name, it will be part of the same <ul>. If it's not the same, we've encountered a new menu and we have to close the existing <ul> and start another one. In either case, we also construct the <li> tag and include the code for it, either using the href value or the onClick event. Please note that in this example, you'll need to keep actions that should be in the same menu grouped together. We could account for items in the same menu being located in different spots on the action bar, but that would make the scripting much more difficult.

Here's the code:


//Generate our unordered lists for use in the CSS Menu

var currentMenu;
var menuButtonText;
var currentMenuLabel;
var menuOutput = '';

//This function is a helper to construct the <li> elements
function makeLink (linkType, linkCode, linkLabel) {
if (linkType == "href") {
menuOutput += "<li><a href=\"" + linkCode + "\">" + linkLabel
+ "</a></li>";
}
else {
menuOutput += "<li><a href=\"#\" onClick=\"" + linkCode + "\">" +
linkLabel + "</a></li>";
}
}

//Iterate through the arrays now
for (i=0; i < contextAction.length; i++) {
menuButtonText = labelAction[i].split('*');
if (menuButtonText[0] == currentMenuLabel) {
//if the menu names are the same, just add an new <li> to the existing <ul>
makeLink(whatAction[i], contextAction[i], menuButtonText[1]);
}
else { //otherwise, create a new menu
currentMenuLabel = menuButtonText[0];
menuOutput += "</ul><li><a class=\"trigger\" href=\"#\">" +
currentMenuLabel + "</a><ul>" //adds the new menu drop down
makeLink(whatAction[i], contextAction[i], menuButtonText[1]);
}
}

//Hides the Domino generated action bar and HR
var actionBarTable = document.getElementsByTagName("Table")[0];
var actionBarHR = document.getElementsByTagName("HR")[0];
actionBarTable.style.display='none';
actionBarHR.style.display='none';

//Write the menu code out to the document
document.write('<div id=\"menuwrapper\"><ul id=\"p7menubar\"><ul>'+ menuOutput +
'<br class=\"clearit\"></ul></li></ul></div>');

//Call P7_ExpMenu() for IE compatibility
P7_ExpMenu();


If you take some time to deconstruct this, you'll find it's not very hard at all. The most difficult part was coming up with the concept.


All of this code lives on a single subform called "CSSMenu" within the example database. If you want to use this in an existing database without knowing anything about how it all works, all you need to do is copy the following design elements into your application:

CSSMenu (subform)
p7exp.css (page)
p7exp.js (page)
p7PM_dark_south.gif (image)

Wherever you position the subform on your main form is where the menu bar will appear. You can leave it at the top of the page, place it within a positioned element, within a table, etc. You'll also need to modify the labels of your action buttons (and maybe their positions) so that they reflect the name of the menu they should go under and the text that should have within that menu (e.g. Rock*Roll). The only other design change is to reference the p7exp CSS file and javascript file in the HTML head of your page.

(The sample database uses the following code in the HTML Head Content, since it uses a conditional comment for making a slight change in the CSS for IE.)


DBPath := @WebDbName;

"<link rel=\"stylesheet\" href=\"p7exp.css\" type=\"text/css\">" + @NewLine +
"<script src=\"p7exp.js\"></SCRIPT>" + @NewLine +
"<!--[if lte IE 7]>" + @NewLine +
"<style>" + @NewLine +
"#menuwrapper, #p7menubar ul a {height: 1%;}" + @NewLine +
"a:active {width: auto;}" + @NewLine +
"</style>" + @NewLine +
"<![endif]-->" + @NewLine +
"<style>body {margin:0; padding:0;font:11pt/1.5 sans-serif;}</style>"


I just tried this. It literally took me 7 minutes to plop the elements into a completely non-web enabled database and have a beautiful looking and nicely functional drop down menu generated from the action bar. Pretty sweet I think!

If you made it this far, then I hope you see the power in using techniques like this to manipulate the DOM. The specifics of this article aren't nearly as important as the underlying idea. Once you know how to access objects via the DOM, the world of dynamic web applications will completely open up to you. I hope that the content here made some sense to you, but if you have any questions, please leave a comment and I'll answer it here.

----

Update: Even before I posted this, I wondered how easy it would be to grab a vertical CSS menuing system from the internet and modify it for use here. Well, it took less than 10 minutes. Since most CSS menus use an unordered list, the only code I had to change was the line that actually writes the menu out to the browser. I also downloaded the CSS and JS files from JavaScript Kit and plopped them in the database. I created a new subform ("VerticalCSSMenu") and just changed the last line. I also made a slight modification to the css to use colors for the menu and hover rather than graphics. So...as you can see, this idea is very easy to extend/change, etc. to meet any needs you might have.



As always, I hope you find this useful. If you come up with other good ideas, please feel free to share. Cheers!

Caption Table Update!

One of the cool things about having a blog is that you can get your thoughts out there and then people smarter than you can comment on them to help you improve! :-D Thus, I tip my hat to Nathan, who posted that "Minimum height on rows is your friend with caption tables." Indeed, I had to slap myself upside the head when I read that. Seems so obvious now! ;-)

To be honest, the one thing I didn't like on my form was the resizing of the caption table as you switch from one row to another. Normally, I'm pretty good with form layout, so it was frustrating. I guess I didn't think about it long enough. But I'll say this now...Minimum height IS your friend. As soon as I saw Nathan's comment, I went back to the form and made some quick updates. The new and improved version is below. Much nicer!



I've actually got some tables setup within the caption table itself to allow for coloring the caption headings and aligning things correctly, so it was a little tricky at first. Just remember to set the minimum height on the actual content part of your table and you should be good to go.



Have a great weekend everyone!

Thursday, November 16, 2006

Quick Tip: Caption Tables

Caption tables were introduced in Notes 6 as another type of table format. Basically, a caption table creates expandable/collapsible rows. The expand/collapse functionality is activated by clicking on the header for each row. Caption tables are analogous to accordion tables on the web. When they were first made available, I didn't do much with caption tables...I just didn't love them as a UI element. However, not long ago, I was presented with a design situation for which caption tables are ideally suited.

In this example, I had several "control" fields on a form. These fields serve as indicators for the workflow process. I was working with limited screen real estate and wanted a way to make the workflow controls very evident and allow the user to rapidly navigate through them. It was at this point that I struck on the idea of creating a fixed width caption table that could hold these fields. I liked this concept very much, since it provides a separate "container" for each of the controls. By offsetting the fields from one another, the user is free to focus on one element at a time, which was important in this application because we wanted them to think about the choices they were making for each workflow option. The end result was a nice UI element that proved to be very usable...a win-win combo.

Here's what it looks like in action:




If you've not used a caption table before, it's quite easy. When you create a new table, specify the number of rows and columns and then choose the "Caption Table" option. The number of rows corresponds to the number of accordion sections that you will have, with each section containing the specified number of columns.



Most of the standard formatting properties for tables still apply with a caption table. To add the caption labels, use the "Special Row Options" tab of the table properties dialog. This process is very similar to setting up the labels for a tabbed table.





That's about all there is to it. For far more inspiring design uses of this UI feature, a quick search on Google will probably turn up some nice examples. If you want to do the same thing on the web, look no further than Rico, which provides a very nice and easy to use accordion effect (I use Rico as an example in one of my Lotus Developer2006 sessions).

For some additional caption table goodness, check out the following posts from Ben and William.

Ben Langhinrichs - SNTT: Accordion style views in Lotus Notes client
William Beh - Lotus Notes Categorized View using Rico Accordion

More Layer Goodies...

...but not from me this time. I'm working on a new article (promise!), but it's turning out to be a long one. I'll post it soon.

Anyway, check out Playing With Layers on Jane Griscti's Notes on Lotus Notes blog. She continues where I left off, building a cool layer effect to display document history and comments. There's some nice code there for showing/hiding the layers and she provides some great tips about positioning them (which can drive you crazy until you figure it out).

Take some time to dig through the rest of Jane's blog too...definitely some good stuff there. Ah...so many excellent blogs, so little time.

Sunday, November 12, 2006

Sorry 'bout the RSS updates...

If you got a bunch of old posts in your RSS reader from my blog, I apologize for that. I moved to the new Blogger beta today and I guess it made some underlying changes to past postings. Things should be back on track from now on. Sorry for the interruption...

Interface Matters At The 'Sphere

Nathan Freeman and I have been talking about interface and UI design a lot lately. In fact, my passion in this area is what led me to start this blog in the first place. I'm very happy to report that we're now taking the show on the road...We'll be presenting "Designing the User Experience: Why Your Interface Matters" as part of the Best Practices track at Lotusphere 2007!

We're really excited about this opportunity and we'll strive to make it a worthy session among all the other great ones you'll have to choose from. Of course, this is the one all the cool kids will be at!!! ;-)

Here's the session description for those that are interested:

BP101: Designing the User Experience: Why Your Interface Matters

Think all IBM Lotus Notes applications need to look and function the same? Think again! To most users, the interface IS the application. In this session, you'll find compelling reasons for why designing the user experience should be a big part of your job as a Lotus Notes developer. Learn about the importance of “interface first” design, incorporating the ideas of usability and aesthetics into your application plans at the very start of a project. Discover methods for reworking existing designs to provide the best user experience possible. Dive into concepts such as user profiles, low-fidelity prototyping and usability testing and see before and after examples that demonstrate why interface matters.


Hope to see you there!

"Taking Notes" With Mike Rhodin

Earlier today...in between all the chores :-)... I took some time to listen to the latest "Taking Notes" podcast. As usual, Julian and Bruce did a great job. This episode had a very nice interview with Mike Rhodin, Lotus General Manager. I was specifically pleased with how he talked about Notes 8 and its "outside in" focus on the UI. This is one of the core points of the "Interface First" design methodology that I use in all of my projects, and it is great to hear (from yet another source), that IBM is making such an effort on this front.

For Notes Developers, it's going to be important to take advantage of the new tools and templates that will be made available to us. I think it will be crucial for our community to place a renewed effort on UI design. As Julian mentioned, it will be pretty bad from a user standpoint to have this beautiful and slick new UI, only to pollute it with ugly apps or apps that have not focused on usability. This is exciting to me, since I think it will make the stuff that Nathan and I have been talking about lately even more relevant.

Besides all of the recent press from the IBM folks, I take it as a positive sign that Notes developers are actually reading this blog and others like it. It's also heartening to know that the interest is enough to warrant sessions at popular dev conferences. Yep...I think UI design in Notes is finally getting its due...and that is a very good thing!

Friday, November 03, 2006

Quick Thoughts On Lotus Developer2006...

Well...Lotus Developer2006 in Vegas has come and gone and even though it was quite a whirlwind, I had an awesome time. It was truly a pleasure getting to present my sessions to such a great group of people! I ended up doing a total of six sessions, since my presentation on Interface First design was repeated. When I wasn't speaking, I had to opportunity to pop in on some of the other sessions. Bill Buchan did a super job with his revamped Object-Oriented Programming for LotusScript topic. I attended some mobile sessions from Bill and Rob Wunderlich and also got to see Rob Novak's Ajax presentation (all great as well).

The highlights of the conference for me were meeting new friends and the many nice comments I received from attendees. Since this was my first time doing these sessions for a professional conference, I hope I did an OK job. I was really surprised at the turnout for the DHTML session, which ended up being the last 90 minutes of the conference. It was certainly a "drinking from the firehose" kind of session, but at least we finished up on time! :-)

Special thanks go out to the WIS staff. The whole team kept everything moving so smoothly and it made my job really easy. They should definitely be congratulated for putting on such a great show. I was really honored to be a part of it. I'm looking forward to doing it again in a few weeks!

Due to overwhelming demand, I'll be working over the coming weeks on trying to make more of the databases that I used in my "Rethinking Your Interface" session available for you to download and play around with. Some of them, such as the embedded editor/embedded view combo and horizontal drop down menus (as well as other goodies) are already available if you look through the archives here. As I mentioned to conference attendees, I'll be glad to answer any questions you have on any of my material, so feel free to drop me a line via chris@interfacematters.com.

I've got a lot of ideas for future articles, so I hope to be back to those soon...it's just finding the time to write them that's hard! :-)

Monday, October 23, 2006

The Music Of FZ Lives On!

When I started this site, I promised myself I wouldn't waste the reader's valuable time talking about my dog, what I ate for lunch, my thoughts on {insert current controversial social subject here}, etc. (If you want me to talk about that stuff, PLEASE, let me know...it's a lot easier than coming up with good technical ideas! ;-) However, please indulge me for a minute and let me break my promise to say a few words about an experience that I had last night that utterly blew my mind.

Most of my friends, family and co-workers know I am a HUGE music fan. Among all else, it's really my one true passion. I could easily spend every penny I earn buying music and attending concerts. I tend to gravitate to music that can challenge me intellectually, hence my leaning toward progressive metal, all forms of jazz, etc. And, sometimes, eclipsing everything else, the music of Mr. Frank Zappa.

Now many people only know of Frank from the smattering of hits he had...mostly his funny songs. He did have an awesome sense of humor and was a compelling satirist, but for me, it's his complex works that define him as a musician. Frank was a composer in the true sense of the word, and developed some mind boggling works. He was known for working with some of the best musicians in the world and was a taskmaster when it came to them performing his music flawlessly.

Anyway...last night I finally got to see Zappa's work played live. Sadly, not by Frank himself, as he died of prostate cancer in 1993, but by his incredibly talented son, Dweezil. The tour, dubbed 'Zappa Plays Zappa' features a band of young, but unbelievable musicians, along with special guests Steve Vai, Napoleon Murphy Brock and Terry Bozzio (all of whom played with Frank at various points in his career).

(I've probably lost many of you already...thanks for listening. If you're a FZ fan, then please continue reading...)

I have attended many, many shows in the past and none of them come close to the level of energy that I experienced coming from the stage. I got chills from the way Dweezil seemed to effortless channel his dad's playing and it was quite an experience to hear Vai and Bozzio recapture past Zappa magic. Napolean Murphy Brock was the perfect frontman and sang with such a passion that it truly affected everyone in the venue. Occasionally I glanced around, looking at other members of the audience and the expressions of sheer joy on all the faces was something really special. I lost track of the number of standing ovations the band received...let's just say it was "a lot".

Highlights for me were:

"Call Any Vegetable"
"St. Alphonso's Pancake Breakfast" (for the insane xylophone parts)
"The Black Page"
"The Torture Never Stops" (extended groove made it that much better)
Dweezil soloing
Terry soloing
Steve soloing

The band played for 3 hours straight and never missed a beat. Dweezil had a bunch of new hand signals and watching him conduct the band was out of this world. I have never experienced a band as tight as they were. Obviously, Dweezil has taken this endeavor seriously and aspires to do it as Frank did. It would have been very easy to "sell out" and make this a show of mostly funny songs that might appeal to more people who have heard those on the radio, but I think the appeal of this show was that it highlighted Frank's musical genius.

In order to get the best possible tickets, I participated in the online auction, which included the chance to get in to the venue early and watch the band soundcheck. Yep...it was pricy, but so very worth it. This was just the extra icing on top. Plus the chance to hear some of the setlist songs twice in one night...awesome! :-) Dweezil did mention during the show that he hopes to make this an annual event. I'm crossing my fingers for that.

In any event, it's past midnight now, and it's been a long day and I've probably bored everyone to tears. If, however, you are a fan of Frank's music, I hope I've inspired you to try and get to one of these shows. Musically, it was the best night of my life and a memory I hope never to forget!

Want to know more about Frank...then go here!

One Week 'Till Lotus Developer2006!

Well...in a week's time some of us will be holed up at the Rio Hotel for three days of heads down technical goodness. That's right...it's finally time for Lotus Developer2006, brought to you by the fine folks at The VIEW. It looks like there will be some great sessions to attend. The hard part will be choosing which ones to miss.

I'm honored to be the small fry among the heavyweight speakers of Lotus-themed events. Look at that list of presenters: Bob Balaban, Rocky Oliver, Rob Novak, Bill Buchan, et. al. These are the guys I've been seeing at conferences forever! It's humbling to be listed on the same page as them all.

If you're attending and you see me at the conference, please stop by and say hello. At a minimum, you can lie to me and tell me you're a frequent reader so I don't feel like I'm out here talking to myself. You get bonus points if you gush about how this blog fills the empty void you've had in your life for so long. ;-)

If you are coming to the show and feel like giving the new guy a chance, here's a list of my sessions. This is going to be fun!

Leveraging Interface First Design for Top-Notch UIs
Overcome the difficulties of balancing the requirements for functionality, usability, and look and feel with one solution – the interface first design technique. Start the design process with a user-centered focus and get great tips for building applications from the ‘inside out’. Discover the simplicity and high value of low-fidelity prototyping, find out how to incorporate user profiling into your design, and see how to leverage usability testing to identify design problems early on. Plus, bring theory to reality by viewing software products and Web sites that demonstrate this powerful design technique.

Rethinking Your Interface
This case-study based session explores various ways in which you can design innovative user interfaces in the Lotus Notes client. Unearth inventive workarounds for the problems inherent in the current state of Notes UI design. Learn how to apply industry usability and UI design best practices to your applications. Examine UI construction to guarantee faster database response times and learn to utilize UI tools, such as the color palette selector, that are built specifically for designers. Finally, witness firsthand the effects of various UI design techniques as you review real-world applications both before and after a user interface redesign.

Energizing Your UI With DHTML
This session supplies you with all the tools and techniques you need to design fast, eye-catching, and easy-to-use Domino UIs. Learn to utilize DHTML to enhance your views, forms, and other design elements. Leave prepared to create dynamic menus, provide in-view editing, launch view actions via right-click menus, and more. Tap into dynamic content generation concepts to breath new life into your Web UIs, and get great tips for enhancing essential elements such as positioning, layout, printing, and more. And, take home a Notes database containing a toolkit of DHTML elements that you can easily drop into any application.

JavaScript Best Practices
In this session you take your JavaScript skills to the next level by learning to create richly interactive applications, leveraging Domino’s strengths in the process. Discover new ways to tackle common problems, such as forms validation, using Prototype.js, the Yahoo! UI Library, and other cutting-edge JavaScript framework implementations. Pick up best practices for avoiding common user errors with variable scoping, object attachments, and more. Achieve highly extensible code using the Evaluate statement to make dynamic variables. You walk away with a reusable Notes database containing lots of examples that you can use to polish your own applications.

Creating Dynamic Domino Applications with Advanced CSS
Capitalize on Cascading Style Sheets (CSS) to control the style and layout of multiple Web pages all at once and present a professional, uniform look and feel throughout your Domino applications. Begin by gaining an understanding of the best methods to design, manage, and fine-tune visually appealing User Interfaces. Get expert recommendations for where to place CSS in Domino design elements based on different types of applications. Then find out how to use CSS to create a frame-like look and feel to Domino pages, as well as a cross-platform drop-down navigation system. Discover the advantages of building CSS style sheets as document objects, and pick up tips to develop dynamically sized Web pages without the use of tables. In addition, take home a fully functional database packed with reusable CSS solutions.

Hope to see you there!

Friday, October 20, 2006

Quick Tip: Simulating A "Frozen" Column

Disclaimer: This posting might be more academic in nature than anything else, since it might not be a very practical solution. However, depending on your needs, this might be a neat little hack you can implement in your own application.


I was asked by a user if I could basically "freeze" a column, similar to the function available in Excel. If you do this in Excel, you can scroll horizontally while your frozen columns stay fixed in place. This is a great feature when you have information in many columns, but want to keep the key value in view as you scroll. Unfortunately, Notes does not offer this option in views. I thought it might be possible to simulate this using column hide-when properties. What I came up with was good enough to satisfy the users, so I thought I'd share with the rest of the class. Here's the low down:

I created a couple of action buttons that control the "scrolling". The actions are used to set an environment variable to either "True" or "False" and this environment variable is checked in the hide-when formula for the columns I want to hide. In the case of my application, I basically wanted the four columns to the right of my first column to disappear if the user "scrolled" right. I would reverse the procedure to allow them to "scroll" the other direction. Since hide-when formulas for a view are evaluated only when the view is initially rendered in the Notes client, you have to either close and reopen the view or rebuild it. Just because I hate trying to close and open elements within frames, I chose to rebuild the view. The code for the action button then is very simply:


Dim workspace As New NotesUIWorkspace
Dim session As New NotesSession

Call session.SetEnvironmentVar("ItemMasterScrollLeft", "True") 'set to false to reverse
Call workspace.ViewRebuild


This LotusScript was converted to HTML using the ls2html routine,
provided by Julian Robichaux at nsftools.com.


And for each column that should be hidden when scrolled, the hide-when formula becomes:

@Environment("ItemMasterScrollLeft") = "True"



Simple as pie! :-)

The pic below shows the feature in action. The hide-when feature of columns can be pretty useful, so don't forget it when designing your UIs.



Have a great weekend everyone!

Monday, October 02, 2006

New Project At OpenNTF

Last night, I deployed a new project over at OpenNTF. I've wanted to contribute to the site for a long time, but never seemed to find the time or the right application. I finally decided to clean up an app I put together a couple of years ago, one that is pretty simple in its design but provides some neat functionality. The name of the project is Application Activity Tracking (for want of a more exciting name) and is basically a lightweight per-document tracking mechanism. If you add the design elements to an existing database, you can begin tracking the usage of each document within your application. Here's a brief description of the project:

The Application Activity Tracking functionality was designed to be a modular means to add a document-specific tracking mechanism to your application. By using this system, you can track how many times users have read, edited, created or deleted a particular document. This functionality is useful for those applications in which a business need exists to either audit the activity that takes place or for a database owner to see how particular documents are being utilized. Detail can be viewed for a single document or the powerful dashboard feature can be used to get detailed information on items such as the Top 10 users, Top 10 documents and other metrics of interest.

So if you want to know how many times a particular document has been accessed, you can do that easily. If you want to view which documents John Smith has been looking at, it's a piece of cake. A lot of information can be obtained from the application dashboard, which is very simple and easy to use. Here are some screenshots that show off the functionality better than I can explain it.

1. DASHBOARD WITH SUMMARY OF ALL DATABASE ACTIVITY - Totals are summarized here. More detail can be obtained by clicking the links on the left. This will open the 'Views' section (found at the bottom of the screen) automatically and navigate the user to the applicable view.



2. DASHBOARD WITH FILTERING - Totals can be displayed for a single user, server or month and year. In this example, I can see that I read 51 documents. The view at the bottom shows me which documents I read and when I accessed them. Unlike log reporting, these will be true indicators if a person physically opened or edited a doc.



3. DASHBOARD SHOWING TOP 10 USERS - It may be interesting to know who the most prolific users of a database are. Clicking on the 'Top 10 Users' tab presents this information. For the purposes of this first version, I just captured their name, but we could include the related numbers as well.



4. DASHBOARD SHOWING TOP 10 DOCUMENTS - Another interesting statistic is which documents in the application are the most frequently accessed. The 'Top 10 Documents' tab neatly summarizes this data.



5. USER ACTIVITY DIALOG FROM A DOCUMENT - All code for doing the user tracking is self-contained within a single subform. This subform includes an action button titled 'Activity Log'. Clicking this action button brings up the following dialog box. The user can view activity for this particular document by user, server or date. Some additional summary information is included at the bottom.



6. DOCUMENT TRACKING OPTIONS - For each document that is being tracked, it is possible to define how the title is captured by the database. For example, the owner can enter a specific title. This might be different than anything actually contained on the doc that the users interact with. Another option is using the field defined on the configuration form. The application owner can use this to define a certain field that will be grabbed from the document for the title. The final option is to allow the author to choose a specific field from the underlying document. This whole section is still under development, but gives you an idea of some options we have.



Without going into a lot of detail, this works simply by creating a small document in the backend whenever a user does a read, edit, delete, etc. The code really is quite simple and I'm sure there is room for improvement. I've already got one request to add an option to make the collection data anonymous, which is great for countries like Germany (where many of my colleagues sit).

If you have the need for simple and unobtrusive document tracking, then please head over to OpenNTF and download the Application Activity Tracking tool. I hope you find it useful. Please feel free to leave me any feedback right on the project page.

Cheers!

On Being A "Real Programmer"

Funny story...

I used to work for a large Fortune 500 company that had Notes throughout the enterprise. Everyone (for the most part), had a mail client and there were thousands of applications deployed. I was part of the IT group that worked at corporate headquarters and was the senior architect on the team. You'd think with all of the really cool applications that we had deployed that we would have some measure of respect. If you thought that, you'd be wrong. To the rest of the IT world, our little Notes team was the red-headed stepchild. Never mind that we deployed more applications that solved business problems than the other teams. Never mind that our embracing of the RAD methodology let us build business solutions cheaper and faster than everyone else. No...in IT, if you were involved in Lotus Notes, you were not a "real programmer".

While it would have been easy to, we never really took offense to this. We were getting a lot of great stuff done and our customers were really happy. In fact, we were constantly rated highly by our end users, not only for our solutions, but because they thought we were so easy to work with. Not being "real programmers" was a good thing in their eyes...unlike a lot of IT folks, we had real people skills! Over time, we came to embrace our position within IT and even came up with a tongue-in-cheek banner and slogan that we used among our group. Here it is...maybe you could identify and use it within your organization as well! And since they are out there listening, I have to say "Hi" to Sally, Joanne and Ashwin...my old "real people" colleagues. :-)



This story came back to me today as I was writing what I thought was some pretty cool code via Formula language. In one of the sessions I am doing for the upcoming Lotus Developer2006 conference, I am including a toolkit of DHTML items and one such component allows you to create a tabbed table in a document with a single button click. Of course, this is a DHTML tabbed table (from the friendly folks at WebFX) and not the poor web implementation we get with the standard Notes stuff. All of the complexity of the WebFX code is hidden and you don't need to know anything about the API. When you click the action button, you are prompted for the number of tabs and the code is immediately pasted into your field. Because it's so well suited for dealing with text, I implemented this in Formula language and had it whipped out in a matter of minutes. Using @For looping is just so simple and cool! However, I find that there are still people within the Notes community that look down on the Formula language, thinking that it's just a toy and not "real programming". I certainly don't profess to be a great programmer, but what's important in my business is the end result. If my customers are happy and the application works, I don't care if it's written in Sanskrit. Anyway, I guess there's no real point to this story. Just remember that even if your IT colleagues don't give you a lot of respect since you work with Lotus products, if you are building Notes apps that add value to your organization, then you most certainly are a real programmer.

Tuesday, September 26, 2006

Ozzie Watch 2006

So...according to Silicon.com, Ray Ozzie, as chief software architect for Microsoft, is number one in the Top 50 Agenda Setters in 2006. Hmmm...the question is, should we care anymore? Sure he is the father of Notes, but now that he's at Microsoft, he's kind of like Darth Vader...a traitor embracing the dark side! :-)

I jest, of course. I think Ray's tenure at Microsoft is very much worth watching. Not necessarily because I think we need to be scared of more competition for Notes. That in itself will be healthy. Rather, Ray seems to possess an uncanny knack for figuring out the direction technology is headed before it actually starts moving that way. His influence is already being felt. Some of the collaborative features I have seen in OneNote 2007 are simply phenomenal and I think we'll see the pace of these features in Microsoft products quicken as Ray moves the company in new directions. As long as these challenges to our domain spur the Lotus community to innovate and expand our offerings, Ray's work will be a very good thing.

Monday, September 25, 2006

This Week At LotusUserGroup.org...Usability and User Interface Design

Hey all! I'm honored to be the moderator for this week's topic forum at LotusUserGroup.org, "Usability and User Interface Design in Notes Applications". You have to be registered, but it's free and there is a lot of great content on the site.

Come on by and ask questions or share your skills on UI topics with other Notes developers. Hope to see you there!

Thursday, September 14, 2006

Sometimes, It's About The Small Things...

When designing a good user interface, there's really no getting around the fact that you need to obsess over all the little details. Sometimes it is the small things that make or break a design and sometimes it's the slight tweak that makes a great design that much better. In some cases, your users may not even notice the small things and that is a great feat...it means you've done your job of getting the interface out of the way! When this happens, your users can really kick ass.

So when is it the right time to focus on the details? Whether or not you follow an interface first way of thinking when you work on your applications, you shouldn't be obsessing about the little things until the end of your project. Whether that text box is 2 pixels too far to the left is irrelevant until you've got everything working. This doesn't mean you shouldn't be thinking about how you can improve your interface while you're constructing your app...just don't let it slow down your development effort. When you think the functionality is ready...that's the time you can really start making your incremental interface improvements.

One great example of an improvement that is oftentimes almost imperceptible is reducing the number of clicks a user has to make in order to carry out a function. The less a user has to click their mouse button, the more productive they will be. With all we have to think about when developing an application, you might argue that worrying about the number of clicks is pretty trivial, but to users it can be very important. As an example of this, I can think back to a recent event in which one of our companies was converted from Outlook to Notes. Believe it or not, there was quite an outcry from many of the users over the fact that replying to a message in the standard Notes mail template required TWO clicks...first to click the 'Reply' action button and then a second to select the desired action ('Reply', 'Reply with History', 'Reply without Attachment(s)', etc.). Yes...this really steamed some people up. In fact, I'm sure this was the reason that the OpenNTF mail template designers added a single click 'Reply' button. (They even added an option to set the default behavior when using this button, which was a nice touch. Users can setup their desired behavior one time and then forget about it.)

One of the "small things" I'm in the process of adding to an existing "dashboard" application is the ability for users to access the four most frequently used options in one of the linked databases directly from the main page of the dashboard. These were determined through feature requests and some user testing and appear to make a big difference in the end user experience. Rather than opening the dashboard, clicking on the database link and then navigating to the place in the database they want to access, users take advantage of the equivalent function directly from a "drop-down" (implemented with layers!) that appears when clicking on a special icon. In most cases, it reduces the number of clicks by at least one. Even when it doesn't, the really cool thing is that the PERCEIVED amount of work is less, even when it's not. This idea of perceived usability is a big deal and one I'll look at in a future post. Below is a screenshot that shows the prototype dashboard feature in action. While not earth-shattering by any means, it's one more small step towards better usability with a minimal development effort and in that way, everybody wins.

Need A Top-Flight Admin?

Hi all! If anyone is looking for an outstanding, senior-level Notes admin with many years of in-house and consulting experience, please drop me a line. A friend is currently on the lookout for a new gig and I told him I'd pass on the word. He's located in between Cleveland and Akron, but geography may not be an issue. Cheers and thanks in advance!

Wednesday, September 06, 2006

Welcome BOC Employees!

If there are any BOC employees out there reading this, welcome to The Linde Group!!! Today, we become the world's number one industrial gas company and as a result, I think there will be exciting things to come. I look forward to working with our many new colleagues around the world.

...And hopefully, we'll keep Notes as our enterprise e-mail platform! :-)

Cheers!

Tuesday, September 05, 2006

Lotus Notes...It Can Do That Too (and look ugly while doing it)

Well...Julian has some great thoughts on internal promotion of Lotus Notes within an organization. His tag line "Lotus Notes...Yeah, It Can Do That Too" probably rings true with many of us. Notes is such an incredibly versatile piece of software that it can really do many more things than it is known for. Rather than offer up any additional thoughts on what Julian so elegantly states, I thought I'd look at another facet of this idea.

Yes...Notes can do that too. However, there's still one major downfall for many Notes applications...Frankly speaking, too many look like crap. I'll be bold here and state an opinion that I think holds up after years of working with this product. I think the bad rap that Notes gets as an application platform is due almost solely to the poor user interface of its applications. With this in mind, I'd add an addendum to Julian's tag line..."...And It Looks Ugly Too" :-) True, UI is my area of interest, and there's certainly some bias there, but in assignment after assignment, when questioned about why users didn't like a certain Notes application, it came down to the interface. Often it's a case of usability, where the UI model just doesn't support what the users need to do. Other times, it's just the sheer ugliness of the application. Apps don't need to be a work of art or have wizbang graphics, but they do need to be attractive and easy to use. Unfortunately, far too few developers have had the time or training to focus on this area.

The good news, I think, is that this is changing. Design, as a general topic area, is really gaining more and more appreciation by developers (most often web developers...but this starts to trickle down to other dev types as well). Competition also leads to a greater focus on interface design. Case in point: the recent discussion in the Notes blogsphere about Sharepoint and creating a new "Nifty Fifty" set of apps. More than one comment came up about the interface and the nice, polished look of the Sharepoint templates vs. the Notes templates. From my experience, the polished apps will win the approval of the masses as long as they actually work. A Notes app may be better suited for the job, but if it doesn't look good, it may be discounted as amateur or at least not suitable for the enterprise.

I'm optimistic about the future with Hannover on the horizon and the great effort that the usability team, lead by Mary Beth Raven, is putting into the client. Hopefully, our community of developers can work together to leverage these new design ideas to beautify our own applications.

But what can you do now to build a better interface? Start looking at design as an integral part of your development process. Engage your end users and get their opinions on your design by using low-fidelity prototypes. Ask them to point out websites and applications that they like. Don't be afraid to borrow from good designs that you see. If we can start making Notes look as pretty as the competing products out there, they'll be no stopping us. We'll proudly state

"Lotus Notes...Yeah, It Can Do That Too...
and Look Darn Good While Doing It" :-)



P.S. I'll be presenting a couple of different sessions on usability and interface design at the upcoming Lotus Developer2006 and Lotus Developer2006Europe conferences. Come by and say hello!

Tuesday, August 22, 2006

The New Plazes Is Really Cool

I'm in Sweden this week on business, so I took the opportunity to re-sign up with Plazes. The new version (still beta :-) is pretty sweet. A very nice clean, UI that is extremely easy to use and that doesn't rely on obscure knowledge in order to allow the user to kick butt. This is a highlight of a good interface. Some of the key points:

-Plain, conversational English. This adds the fun factor and makes it seem like the website is an old friend. This is important for building passionate users. You may not think this could work in your stuffy business environment, but you'd be pleasantly surprised with the reaction from your users when you start to move away from business and techno speech.

-Good use of white space. Notice that the page is not crammed full of graphics, gadgets or gizmos. This allows the user to focus on the task at hand. Their locus of attention is pretty much guaranteed not to stray.

-Functionality is easy to understand. This may seem obvious, but how many sites do you know that miss this point? On Plazes, the major functions are always a click away. I especially like the contextually aware links that are displayed. Basically, the Plazes site determines what you are doing and presents some links that are related to this.

-Functionality is limited. This is a good thing! The Plazes team has picked one thing to focus on and they really do it up. Rather than overburden the user with options and features that probably won't be used, they have a limited number of functions that work exceedingly well.

The new flash "badge" that Ed talked about awhile back is slick as well. I finally got around to doing some updates on my blog design and you can see my badge on the side.

Anyway...even if you don't use Plazes, it's worth looking at to get an idea of a nice web UI. If you want to create a Plazes account, drop me a line or leave a comment and I'll send you an invite (to build up those karma points! :-D

Cheers!

Monday, August 07, 2006

It's Got Layers...Cascading Menus In The Notes Client

So the audience has spoken (all three of you :-) and the consensus was that I should talk a bit about how I made cascading menus with layers in the Notes client. It's an interesting exercise and one which might be useful, depending on your circumstances. First, I'll explain what I did to get this working and then discuss some of the limitations and drawbacks. So let's get on with it, shall we?

As a quick refresher, most of you probably know about layers and their availability in the Notes client. In practice, I don't know many developers that use them, but they can be extremely valuable in designing your user interface when you are concerned with pixel perfect layout and organization. The really cool thing about layers is that they allow you to place overlapping box elements anywhere on your Notes form or page. What rocks even more is that any elements that you can put on a form or a page can be placed into a layer. Thus, if you need your input field to be exactly 45px down and 210 px over from the edge of the screen, you can do that with a layer.

Before we get too deep, there are a few things you need to keep in mind about layers. First, a layer is positioned relative to its containing block. In the case of one layer within another, for example, the position of the internal layer will be measured from the top and left edges of the parent layer. This is very similar to relative positioning on the web. Second, layers have a z-index property (also analogous to the web). This property controls how overlapping layers interact. A child with a z-index of 10 will appear above it's parent with a z-index of 0. The higher the z-index, the "closer" that layer is to the user. Finally, I want to review the somewhat tricky way to implement hide-when formulas with layers. In order to hide a layer, you must put your hide-when formula on the paragraph that contains the layer anchor, not the layer itself. Whenever you create a layer, a layer anchor is generated as well (at the position your cursor is at the time you create it). Although you can move the layer anywhere you want, the layer anchor stays in place, unless you choose to move it by cutting and pasting it somewhere else. When you first start using layers this is a little weird, but you get used to it pretty quickly.

When I blogged awhile back about creating a cascading menu in Notes using Action buttons, I got a good response from people. I like the simplicity of the technique and have used it in some of my databases at work. However, several people asked me how to control the formatting of the menu. Unfortunately, Notes provides no interface to do this, so you are stuck with the menu rendering based on your operating system properties. This made me start exploring other avenues for implementing the same kind of functionality and in the end I found that layers can give you a pretty slick presentation.

The first step is to determine what kind of menu you want to create, a horizontal cascade or vertical cascade. As you are designing your UI, this will probably be pretty apparent based on other choices you have made. If you can't decide, just start with one. As you'll see, the technique is the same for either and changing from one to another is very simple. For our example, let's create a horizontal cascade. That is, our menu items will cascade out from the right as the user expands them.

In the screen shot below, I've created a fictional menu that might be something like you would see on a company intranet. To keep it simple, we just have three menu choices, "Personal", "Human Resources" and "Finance". The idea is that when you click on one of these options, the menu will expand and you will see additional choices under that category. In this example, we'll only expand the menu two levels deep, but you could extend this technique to more if you need it. (I'd caution against going any more that three levels deep...that gets tedious for the user).



If you look at this form in design mode (in the sample database), you'll see that I used a table to separate the top level elements. This is not really necessary, but it makes it easy to align all of the labels. Once the top level elements are created, it's time to start adding the layers. Click anywhere on your form and choose 'Create - Layer'. This will generate an transparent layer that is one third the width and height of your screen (or containing element). Notice the little icon layer icon in the top left corner of the new layer. This is the layer anchor. If you grab on one of the sides of the layer, you will see that you can drag it anywhere on the page. As you do, the layer anchor stays in place. To format the layer, select it and then pull up the layer properties dialog. You can modify the height, width, position, color, etc.



To create the menus in this example, I visually manipulated the size of the layer until it fit what I was looking for. Since we can place any kind of element inside a layer, I opted to construct the menu options with a table, again purely for formatting purposes. Each row of the table was designed to hold one menu item. I then formatted the table with borders, colors, etc., getting the exact layout I wanted.



Once you create the layers, you need to position them on the form as you want them to appear. This part can get tedious, because you just have to use trial and error to see if everything lines up as you like. The thing I really like about this, though, is that you have complete control over the final product, which is something you can't always say about Notes.

Aside: When you are working with layers, you can hide them to get them out of the way when you don't need them. This is really useful when you have a lot of overlapping layers crowding the screen. To do this, select the layer you want to hide and choose 'Layer - Hide Layer". Keep in mind that this only hides the layer in design mode...not when it's actually being used in the client.


Once your layers are arranged in the order that will simulate your cascade, it's time to work on hiding them until they are needed. To do this, remember that the hide-when must be placed on each individual layer anchor. Notice in this sample database that I arranged them all on different lines. This is necessary because each layer will have its own hide-when formula. The approach that I decided on to control the visibility was to create two hidden fields on the form, one entitled "MenuLevel1" and one named "MenuLevel2". The initial value of these fields is blank, but when a hotspot on the menu is clicked, it will set the value of the appropriate field. It will be one of these field values that the hide-when formulas compare themselves against.



"MenuLevel1" controls the first level cascade layers, whereas "MenuLevel2" corresponds to the second level of the cascade. If you want to extend this further, just add the necessary number of fields. The hide-when formulas on the layer anchors themselves are very simple. They just check if the applicable hidden field has a value equal to the value I (arbitrarily) picked and if not, they are hidden. For example, the hide-when formula on the first-level layer for HR reads "MenuLevel1 != "HR". So far, so good.

After the hide-when formulas are defined, the next step is to create the links that do all the work. In my first example, all of the menu labels are just text, so I created an action hotspot on each. In general, clicking on a link should reveal the next level of the cascade corresponding to that link. If a completely different menu is selected, the previous entry needs to be hidden and the new one displayed. Here's a sample from the hotspot on the 'Personal' link:


@If(MenuLevel1 != "Personal";
@SetField("MenuLevel1"; "Personal");
@SetField("MenuLevel1"; ""));

@SetField("MenuLevel2"; "");
@Command([RefreshHideFormulas])


In this formula the first couple lines determine if the level 1 cascade corresponding to the link should be shown or hidden. If it's not already visible (field != "Personal") then we turn it on, otherwise we turn it off. In order to avoid the situation where the user is in a second level cascaded menu for another link before clicking this one, the "MenuLevel2" field gets cleared (hiding the second level cascade). Finally, the hide-when formulas are triggered by the last line.

When a user executes an action on the menu, we want the menu to "de-cascade" (I'm making up words now folks). In addition to the code that runs whatever the action is supposed to do, we just need to make sure that "MenuLevel1" and "MenuLevel2" get set to blank so that the menus all disappear.

This is the essence of this technique. It takes a little patience to get things lined up the way you like, but the basic concept is quite easy. Of course, why stop there? There are a lot of improvements that could be had.

Getting Jiggy With It


First off all, what if the user opens a menu and then decides not to choose an action? On the web or in other software, the user can just click onto a blank area of the screen (or at least an area outside the menu) and it will disappear. I couldn't think offhand how to accomplish this within Notes, so I added a small icon in the bottom of each menu that will effectively close it by setting the "MenuLevel1" and/or "MenuLevel2" fields to blank. If you are in second-level cascade, clicking this icon will close just that menu, leaving its parent open. If you click it in a first-level menu, all will close.

After I tested the rough framework of the cascading menu concept, I decided to try different formatting options. One thing I tried was to create the links as graphic image wells so that you could have a rollover effect. This entails breaking out your favorite image editing software and creating the link to the appropriate size, with both the normal and hover state, as seen in the example below. All of these images should be placed in the Image Resource section of your application and then you can add these resources to your menu tables. When viewed in the Notes client, you get a nice rollover on the menus.



After playing with the images, I thought of an even easier way to get a nice rollover effect. Since you can put any element in a layer, you should be able to use an embedded outline right? Turns out, you can! I created the outlines to represent each menu, then created an embedded outline within each layer and played with the formatting until it matched what I wanted. Then a quick preview in Notes and...perfect!



The beauty of this technique is that the menus can be placed anywhere in your application where it makes sense. In fact, it just look a couple of minutes to reconfigure my initial cascading menu to turn it into a vertical one. You could have menus popping up from the bottom, the right size, wherever!



So...What's The Catch?


Surprisingly, there aren't many drawbacks to this technique. One thing to be aware of is that the layers cannot cascade across frames, so using your typical frameset with a navigation panel on the left is out. If you are rethinking your design though, you might not need frames. In the example, I created another frame to serve as the container for an embedded view. Using layers, you could easily create your entire UI in a single page.

One thing I found the hard way is that trying to contain the layers within tables is not an easy task. At first, I thought that this would make the design easier to manage, but I kept getting results like the screenshot below.



It turns out that the layer would not display correctly unless the table cell was as high as the height of the layer. This got unruly and difficult to work with very quickly. Hmmm...functionality buggy with tables? Never! ;-) In the end, I think positioning the menus by hand is a more elegant solution anyway.

After penning this post, I figured I shouldn't show you all this stuff without leaving you with something to take home. So...you can download a sample database, which is exactly what I took these screenshots from. Please note that this isn't anything polished, just my playground for the day. As always, if you have any questions, please feel free to contact me...chris@interfacematters.com.

I imagine many more variations on this theme and I will be exploring more ideas for this in the future. I also look forward to hearing from others on how they implemented functionality with layers in their applications. Until next time..."This is Walter Cronkite. Good night..."

Technorati tags: , ,