Thursday, May 29, 2008

SnTT: Lotus Notes and Web UI Examples

Patrick asked for some Notes UI examples, so I thought that I'd post a couple of mine in the interest of additional food for thought - and also to let Chris and that other chap (the one with the funny colored hair!) that their mission was maybe a little effective.

I'll explain how I ended up with each UI. First of all I'm not a graphic designer and would never claim to be one. I'm pretty familiar with Photoshop and Gimp and if I'm given a starting point then I can come up with a few similar concepts.

The inspiration for my latest UIs are from the web 2.0 styles and web 2.0 applications. I love the simplicity of the interfaces like basecamp, ideaJam, Remember the milk and linkedin. These application have the less-is-more approach to making the interfaces simple. This is what I was striving for. A simple interface that is closer to what you see on the web than the traditional notes applications.

I've still retained the traditional frames approach, but removing the borders made the first page more web like. The horizontal outline in black, for the primary navigation is something that you might see on a website. 


On the form the removal of the traditional border around the action bar is removed and shaded so that the action button feels more like it is part of the page. (I think that I picked up that tip from someone else, although I can't remember who)

The downside of the tabbed approach is that printing format isn't that great, but the client rarely prints so its not much of an issue.

Finally a web example, this is a Lotus Domino web application. The process that this manages is a 6 step process with sub task for each one. 

I started by drawing a low fidelity prototype which laid out what I wanted to convey and where to put it. For example, the status of the top level steps and status bar for the sub steps.  I then engaged a local graphic designer to come up with the images, colors and general look and feel.



With these examples I think that I got a closer to what I was striving for and embraced some of the things that Chris and Nathan endorse. Starting with a blank piece of paper and working out what am I'm trying to tell the user was a good technique for me to detach from the technology and focus on the interface without considering how to implement it. For web applications this works well. For Notes applications, there's no harm in starting with the vision and then re-factoring the paper interface by accepting compromises as you work out the detail.

Finally try de-cluttering the interface. You might have elements of your design that have been inherited from application to application and just accepted as required.
I've seen heaps of LN applications that have the old classic 5 entry audit history tagged at the bottom of every form. Do forms with pick list values for dblookups really require an audit history ? If not then get rid of them as they are not only cluttering the interface but you are also storing and managing irrelevant information.

There you go Patrick, a few additional Lotus Notes and Domino UI examples.



Monday, May 19, 2008

SnTT : Dojo. It's not just eye candy

If you thought that Dojo was all about fancy widgets and eye candy for you web apps, then you might have missed another advantage of using Dojo. In fact, it's not just Dojo. Most of the popular toolkits provide the features to make OO in JavaScript easier. I'm using Dojo, so my third post on Dojo is all about how I used OO in Dojo.

The challenge.

Let me explain the challenge. I needed to build  a few HTML forms (without resorting to the whole lotus workplace forms solution). The forms, while fairly short (the longest being 30 multiple choice questions), were complicated by the fact that a large majority needed to include the 'Other - please specify' additional to the simple radio and checkbox fields. In addition the users could also choose different paths through questions. As a user answers the questions the subsequent questions that they need to answer change.

I wanted to have the simplest user experience possible and in my opinion that means, if you can't fill in a field then it should be hidden away. In short, I wanted the field that captures the 'other' detail to be hidden until the 'other' choice is selected. Likewise, fields that are not available based on previously selected choices are also hidden. 

To make it even simpler for the user I wanted to maintain the hidden fields choices. If the user changed their mind a few times, they would not need to repeat answering questions. I would also need to remove all the hidden values before the form was submitted so that the data sent to the server represented exactly what was on screen.

It sounds like a lot of work, for something so simple as filling in a few multiple choice fields - but I don't think of it has extra programming. Think of it as an investment in reducing the number of support calls.

So why Dojo ?

Sure, you could do all of this in plain old JS. Functions for this and functions for that, but wouldn't it be nice to be able to just write some simple JavaScript. Something like...

if(fielda.mandatorySelected()==false) {
// then record or show errors
}

or 

fielda.visible(true);
fieldb.visible(false);

and maybe...

fielda.display();
fieldb.display();


Dojo.Declare.

Dojo gives you a great framework for OO using Dojo.declare for building JS classes. Its simple to implement, simple to reuse and easy to read. If you are reusing it then you're writing less lines of code. Which means less that the browser needs to download which in turn makes the pages load faster. 

How did I use Dojo Declare ?

In the Notes form, the HTML looks like the screen shot below. A div for the radio or checkbox field with a unique id 'q8' and a div for the other field with a unique id of 'q8-other'.  All pretty standard stuff.



I started by calling my class scius.AuditField. I won't reproduce all the functions as I've attached the JS file here.

dojo.declare("scius.AuditField", null, 
{ ... } );

then I added in some member variables and the constructor. The constructor allows me to initially specify the visibility, and if this field has the 'other' field.

_id:null,
_other:"other",
_hasOther : null,
_isVisible : null,
_otherIdSuffix : "-other",
_otherFieldSuffix  : "other",
constructor : function(id, isvisible, hasOther) {
this._id = id;
this._hasOther = hasOther;
this._isVisible = isvisible;
},

some setters and getters (or properties), which I can use to determine the visibility or set the visibility.

visible : function(isVisible) {
this._isVisible = isVisible;
},
isVisible : function() {
return this._isVisible;
},

The hiding and showing using CSS classes through hide() and show() which is called by the display() function. The display function also checks to see if it needs to display the 'other' field (see the source code attached).

hide : function(fieldid) {
dojo.removeClass(fieldid,'form-fields');
dojo.addClass(fieldid,'form-fields-hidden');
},
show : function(fieldid) {
dojo.removeClass(fieldid,'form-fields-hidden');
dojo.addClass(fieldid,'form-fields');
},


Next is the checking of mandatory fields function. Note I reused an existing function to determine the actual value of the radio button via the 'isRadioChecked(rbo)' line. I guess it should really be part of the class or a utility class of its own.....maybe one day it will !

mandatorySelected : function() {
var rbo= document.forms[0][this._id];
if(isRadioChecked(rbo)) {
if (this._hasOther && this.hasValue("other")) {
var oth = document.forms[0][this._id+this._otherFieldSuffix];
if (oth.value=="") {
return false;
} else {
return true;
}
} else {
return true;
}
} else {
return false;
}
},

So how did I use this class in the Form ?

As I had around 30 questions, I decided to store the questions in an array and initialize them in the Notes forms JSHeader object. Creation is fairly simple. 

The format is scius.AuditField(domid, visible, hasOther).

var qlist = new Array();
...
qlist[8] = new scius.AuditField("q8",false, false);
qlist[9] = new scius.AuditField("q9",false, true);
....

I have a checkConditionalQuestion() function that gets called from the onClick() of each field, which checks the visibility of dependent fields.


function checkConditionalQuestion(cond_question) {
...
} else if (cond_question=="7") {
if (qlist[7].hasValue("yes")) {
qlist[8].visible(true);
qlist[9].visible(false);
}else if (qlist[7].hasValue("no")) {
qlist[9].visible(true);
qlist[8].visible(false);
}
qlist[7].display();
qlist[8].display();
qlist[9].display();
} else if (cond_question=="9") {
qlist[9].display();
}

...
}

You've already seen the checking of mandatory field values and of course there is the emptying of the invisible fields. Called after validation and before the submit.

function emptyInvisible() {
for (var i = 1; i <= 30; i++) {
if (qlist[i].isVisible()==false) {
qlist[i].empty();
}
}
}

Summary.

Using the Dojo.declare to create classes is more readable than the JS prototype way. The format is closer to the way you would create Object in LotusScript and Java and so is familiar and easier to read. I only scratched the surface of what's possible and I can see areas for improvement. If you are interested, here it is in action.  

Next.

I think that a database containing the three articles as a download would be a useful starting place if you need to implement similar forms. I've already started pulling out the various components into a standalone application and I'd like to tidy up a few areas before releasing it. As soon as its ready I'll post it.  I can't say when - it all depends on the workload over the next few months. 

Wednesday, May 07, 2008

YSlow - in moderation.

An interesting post popped up on my Ajaxian feed, which linked to a post in developerworks. The post is about using Yahoos YSlow tool. YSlow analyzes a website and gives you a performance score complete with suggestions.

The posts are worth a read if you are interested in how to make your websites and web applications quicker. 

I decided to run YSlow against a web application that is in the final testing phase - just out of curiosity. I'd already checked the performance with firebug and was pretty happy with the speed, especially seeing as it used a few of the dojo libraries and was much faster that the clients website. 

I was disappointed when YSlow reported a middle of the range score. 

I then ran YSlow against a number of popular websites and web applications, all of which fared similar to mine. Finally, I decided to run YSlow against the local Yahoo website au.yahoo.com.

Guess what....



Yahoo gets an F. 

I felt much better after that.

After a bit of research, it seems as though you shouldn't take the score card too literally. There are plenty of popular websites out there that don't score highly according to YSlow.