IBM®
Skip to main content
    Country/region select      Terms of use
 
 
   
     Home      Products      Services & solutions      Support & downloads      My account     

developerWorks  >  Lotus  >  Forums & community  >  Best Practice Makes Perfect

Best Practice Makes Perfect

A collaboration with Domino developers about how to do it and how to get it right in Domino

Cruel ValidationPerhaps my readers can help me understand this. Is it some misguided impulse to control the user, that makes people design forms that validate a field the moment you leave it, and force you to fill in fields in a particular order? Do some developers think end-users like to be herded along like sheep? Or do they do it accidentally?

Especially pernicious is the "automatically refresh fields" form option, in combination with validation formulas that don't distinguish between refresh and save. You click a field midway down the form, the form refreshes to that point. So the validations for fields above that fire, and any required field you left blank insists that you fill in a value now. You can't get to the field you clicked on until you supply valid values for all the fields above it.

The problem is, people have a limited number of things they can keep in mind at a time. They clicked on that field for a reason. They have some information -- in their own short-term memory, or on the clipboard -- that they wanted to insert at that point. When a person's immediate goal is frustrated, they feel -- well -- frustrated. Having to satisfy the insistent earlier fields that will not let you get by without filling in a value, is a distraction from their goal. Choosing the right value can take time and take attention away from what the user sees as their task. There are three risks you run by this:

  • The user will choose a value carelessly so that they can get to the field they wanted, and forget to fix it later.
  • The user will take time to fill in the fields correctly, and forget the perfect turn of phrase that they were wanting to type into the Body field, that they had wanted to do first thing.
  • The user will become irritated with the developer and will decline to contribute to the pool to buy you a birthday present.
There's seldom a good reason anymore to use the "Automatically refresh fields" option, since we now have options on keyword fields to do a refresh -- or run more targeted code -- when the field is changed or exited. And if you do end up refreshing the form during editing -- because you have a subordinate keyword field and you have to refresh its choices, for instance -- it makes sense to write validation formulas that wait to complain until the user tries to save the document. For instance:

@If(@IsDocBeingRecalculated; @Success; @ThisValue = ""; "Please, sir or madam, fill in a value for the Reason field."; @Success)

Actually, even this is less than ideal. The user is only told about one problem at a time, so if there are multiple fields that fail validation, they're repeatedly trying to save and having to answer a complaint. Once again, they're trying to do something -- save the document, be done with it -- and they are stymied multiple times. The popular web paradigm is to do a single pass on the document and flag all the fields that are incorrect, so that the user can address them all before they try to save again, in the order that suits them. This is a smoother and more easy-going UI, and if you can afford to take the time to design your form this way, you will be lowering the general stress level of your users, and significantly improve your chances of getting a nice birthday present (make sure your name appears on the form).

Implementing this is a little involved; do any of my readers know of a good description of how to do this for the Notes client, step by step? So that I don't have to write it myself? Thanks.

Andre Guirard | 20 February 2008 09:34:00 AM ET | Home, Plymouth, MN, USA | Comments (20)


 Comments

1) The crack that whip validation paradigm
Karsten Lehmann | 2/20/2008 10:25:40 AM

"Is it some misguided impulse to control the user, that makes people design forms that validate a field the moment you leave it, and force you to fill in fields in a particular order?"

LOL

That's exactly what IBM is doing in the beta forums via the Notes client. You need to enter the field values (subject, platform etc) in a strict order. Otherwise the database prompts that you left out a mandatory field. :-)

2) The crack that whip validation paradigm
Tim Tripcony | 2/20/2008 10:40:09 AM

Something that is often overlooked is that input validations don't have to refer to the field containing them. Although I typically do all my validations via LotusScript now, you can also cram all your validations into a single field that displays a single prompt for all failed validations. Only real downside is that Notes wants to focus the field it thinks failed, so if you put all the validations into the first editable field, for example, it'll bounce the user back to the very beginning even if that field passed... one of many reasons to validate via script instead of the standard field event.

3) The crack that whip validation paradigm
Karl-Henry Martinsson | 2/20/2008 10:59:02 AM

What I do in a couple of my forms is that I have code in QuerySave(), where I check the required fields for content and data type. If they fail, I usually add the field name to a string, so I get a list of all the empty fields that I can display in a message box. In some cases I simply display one prompt per error, but I am working on putting it all in one big string I can display to the user.

Something like this:

If source.FieldGetText("Claimant_LossType")="" Then

errmsg = errmsg + Space(10) + "Coverage Code" + Chr$(10)

End If

If Instr(Ucase(source.FieldGetText("ShowLossTypeList")), Ucase(source.FieldGetText("Claimant_LossType")))>0 Then

If source.FieldGetText("Claimant_Category")="" Then

errmsg = errmsg + Space(10) + "Loss Type" + Chr$(10)

End If

End If

If source.FieldGetText("InjuryType")="" Then

errmsg = errmsg + Space(10) + "Claimant Type (minor, standard, major)" + Chr$(13)

End If

If source.FieldGetText("SeriousClaim")="" Then

errmsg = errmsg + Space(10) + "Serious Claim" + Chr$(10)

End If

If source.FieldGetText("PDType")="" Then

errmsg = errmsg + Space(10) + "Loss" + Chr$(10)

End If

If source.FieldGetText("Claimant_Type")="" Then

errmsg = errmsg + Space(10) + "Type" + Chr$(10)

End If

If errmsg <> "" Then

result = Msgbox("You need to fill out the following" & Chr$(10) & "fields to setup the claimant:" + Chr$(10) + errmsg + Chr$(13) + "Do you want to cancel saving and edit the claimant?",MB_YESNO + MB_ICONEXCLAMATION,"Required field(s) missing")

If result = IDYES Then

Call source.FieldSetText("SaveOptions","0")

Continue = False

Goto endsub

End If

End If

4) The crack that whip validation paradigm
Ed Lee | 2/20/2008 11:01:55 AM

Hello, there is a very simple method to do this that I borrowed from somone else. I apologies for not remembering who.

Create a hidden computed field that has all your validation in it, for example:

REM {Field Validation};

REM {Used by QuerySave event.};

REM {This field builds the complete validation error message for all missing/incorrect info. If it is blank, then all validations have been satisfied, but if it is not blank, at least one has failed};

REM {If a status reason is available then the user should choose one};

statusReasonChoices:=@Trim(@DbLookup( "" : "NoCache" ; @DbName ; "vwLUPAllStatuses" ; status ; 2 ; [FailSilent]));

fieldList:=

@If(@Trim(companyName)= ""; "Please enter the company name"; "") :

@If(@Implode(statusReasonChoices) != "" & statusReason = ""; "Please enter the status reason"; "") :

@If(statusReason *= "Confirmed":"Pending Activation":"Closed Lost":"Closed Won" & MCCCustomerID = ""; "Please enter the MCC Customer ID"; "") :

@If(confirmedDailyBudget = "" ; "" ; @If(confirmedDailyBudget < 0 | confirmedDailyBudget > 1000; "The confirmed daily budget must be a number between 0 and 1000"; "")) ;

@If(@IsError(fieldList) ; "There was an error while trying to save the document. For some reason, one or more of the fields could not be validated. " ; @Trim(fieldList))

Then on the QuerySave event of the form get the text of the validation field. If it has something in it then it must have failed validation so I bring up a dialog box and place error messages in a nicely formatted manner.

I can send a example database if you want. The code I borrowed also places the user back to the first field that falied validation

5) The crack that whip validation paradigm
Ed Lee | 2/20/2008 11:06:22 AM

Just to add to my previous post, I got my code from Kevin Pettitt at www.LotusGuru.com.

{ Link }

Thank you Kevin.

Ed

6) SuperNTF has an easily configured all-in-one validation routine
Kevin Pettitt | 2/20/2008 11:13:23 AM

I blogged about the general approach a while ago here: { Link }

It handles both the message construction AND the issue of where to put the cursor after validation failure.

The SuperNTF template on OpenNTF (accessible via www.superntf.org) integrates this approach so that's your best source for example code. The next release, due soon, will go one better and allow you to write the validation and field focus formulas on form configuration docs, making it possible to adjust validation without design modification. If anyone wants to see that sooner email me offline at K evin d ot Pe ttitt a T g mail.

7) attributes of the ideal validation interface
Andre Guirard | 2/20/2008 11:21:25 AM

A couple of people posted suggestions above for how to do a gentler validation.

I am opposed to any system that puts up a dialog listing all the errors at once, and then the information is not available when the user gets out of the dialog. They won't remember the whole list, so they can only fix the one field the focus changes to, and then they have to save again. This is more annoying than the usual style of validation.

Ideally, the attempt to save should open a floating dialog that lists the problems -- like a properties dialog, it should stay in the foreground but not be modal, and if the user clicks a message in it, focus would move to the relevant field (and the error window would move to not cover that field).

This is probably not practical in the Notes client as currently implemented.

A second choice is to have the error messages appear in a stand-out color just above the affected field. You can do this by scattering computed text all over your form, but it's a lot of work -- probably more than that birthday present is worth. And you might want an action button to move to the next error field, if the form is very long.

Another possibility is to show the error messages all in a block (at the top of the form, say), and if the user clicks a message it repositions to that error. This can be done with passthru HTML in a computed text with JavaScript onclick code.

8) The crack that whip validation paradigm
Wayne Sobers | 2/20/2008 11:46:37 AM

There is a difference between general composition (like and email) and straight data entry (like invoice details).

Normally I will validate on field exit but display a dialog with valid choices for the user.

As users become more proficient with the application, keyboard sequence and inline correction become more important to the users "flow". Additionally, I and a lot of the users in our company are keyboard jockeys, and only use the mouse when we absolutely have to.

9) The crack that whip validation paradigm
Kevin Pettitt | 2/20/2008 12:38:58 PM

@7 Andre - good point about seeing a big list of validation errors and then not being able to reference that list afterward while you're busy fixing things. A few thoughts:

- This is less a problem when the form is relatively short, the validations are simple "value required" types, and you have an on-form indication of "required field" (e.g. a star icon next to label, as done in the SuperNTF example form).

- Instead of a messagebox, you could use a popup layer to show the list of errors/missing info so that it would continue to be visible while editing. You might also use a "sidebar" frame to achieve this, but you'd have to code your forms to use Auto Frame.

- If you have more complex validation requirements and/or a serious need for "idiot proofing" the data entry, there is probably no substitute for some sort of field by field computed text that appears when a save is attempted. Using an easily configured validation routine of the sort I've described is just not going to suffice.

- I've also seen forms that have a box off to one side that as you tab from field to field shows data entry requirements for that field - basically just a more in your face form of field help, which can be thought of as "pro-active validation".

10) on "popup layers"
Andre Guirard | 2/20/2008 1:38:57 PM

Kevin, I would love to use a "popup layer" to show the current list of problems. The difficulty I have with this is that, for a form of any length, there's no way to get the layer to move around with the cursor focus, so it will frequently be off-screen. I've been playing around with this, and if I use a literal layer, I can control its visibility during editing, but not its position or size.

Maybe if we used a form with a fixed header, like the memo form, and displayed the errors there...

11) The crack that whip validation paradigm
Charles Robinson | 2/20/2008 3:08:18 PM

I've hacked a non-modal but always-on-top window into Notes, but it sometimes caused the client to crash so I couldn't deploy it. It would be really nice if DialogBox could have one more parameter: IsModal. Not that we really need a function/method with 14 parameters, but it really would be a nice bit of functionality. Or maybe add two more properties to a form: "Show as dialog" with a child selection of "Display as a modal dialog".

12) The crack that whip validation paradigm
Charles Robinson | 2/20/2008 3:42:21 PM

@10 - Can layers cross over the form header boundary? I know with frames they can't, but I haven't tried it with a form header.

13) The crack that whip validation paradigm
Kevin Pettitt | 2/20/2008 3:45:54 PM

Andre, the layer approach is indeed limited when dealing with longer forms. In such cases the sidebar frame approach is probably worth exploring. But it also depends on how the forms are structured.

If you employ tabbed or accordion tables such that you can keep the scrolling to a minimum or eliminate it, then you're fine. But even if you have your form broken into more traditional sections, you could always place multiple layer popups - one for each section - such that each shows only the problems with the currently visible part of the form. And since you might not want to show them problems affecting parts of the form they can't see anyway, this might work well in some cases. Then of course there are times when a wizard approach might work, which would eliminate the scrolling problem.

14) Come back tomorrow
Andre Guirard | 2/20/2008 5:03:28 PM

I have a way in mind to do this without having to pepper the form with hidden layers and what-not. Kevin, you might consider whether this is something you want to add to SuperNTF. Look for a new entry about it tomorrow morning. For now, I have to try and get some actual work done...

15) Javascript?
Lars Berntrop-Bos | 2/20/2008 6:29:12 PM

The Notes client does JavaScript. I've seen webpages floating boxes around the page, following the scrolling around. Can't we use this for the validation message?

16) Give the user the ability to provide the text WITHIN the dialog...
Peter Herrmann | 2/21/2008 1:17:13 AM

If you use the *Input Translation* event rather than Input Validation, then you can prompt the user nicely:

@If(@IsDocBeingSaved & @ThisValue="";

@Prompt([OkCancelList]; "Priority"; "Select a priority"; @Subset(dspPriorities;1); dspPriorities);

@ThisValue)

In words: if the doc is being saved and the field is blank, prompt the user with a list of choices.

I have been there and back on centralised validation and LSUI techniques and found (for me) that the Zen approach and going with the flow is best. So, I use the formula events for each field.

17) DeveloperWorks forum validation
Scott Leis | 2/22/2008 3:23:18 AM

@1 - It's not just beta forums.

The Notes/Domino 6 and 7 forum, which has been live for years, does this too. It's very annoying.

18) The crack that whip validation paradigm
Julian Robichaux | 2/22/2008 8:41:16 AM

Just got back from vacation, so I'm a little late to this party, but I posted some generic LotusScript field validation code to OpenNTF a couple months ago:

{ Link }

The concept is that you take all the validation code out of Formula events and put it in code you can call when the form is saved or refreshed. The library is generic enough that you can control what happens with the validation messages too: show them all at once, or one at a time, or whatever.

It also works on the web, which is kind of fun.

19) The crack that whip validation paradigm
Charles Robinson | 2/22/2008 9:56:26 AM

"It also works on the web, which is kind of fun."

You're demented, but it's one of the things I like about you. :-)

20) The crack that whip validation paradigm
Ben Poole | 2/22/2008 12:21:56 PM

"In-line" validation of Notes documents drives me mad, so I heartily agree with the spirit of this post. That said, I have coded solutions that do just this, *because that's what the user-base wanted*. In some data entry scenarios, they want to be led bit-by-bit through the form via validation. I still think @Failure dialogs are a somewhat brutish way of accomplishing that, but hey.

I have a generic validation class I use which provides a list of errant fields, keyed by their labels, together with an error count and a reference to the first field which failed validation. This can be pumped into one big dialog (not ideal, for reasons Andre outlines), or into the form itself -- and in that scenario, the layer idea seems a good one to me :o)

 Add a Comment
Subject:
   
Name:
Comment:  (No HTML - Links will be converted if prefixed http://)
 
Remember Me?     Cancel

Search this blog 

Disclaimer 

    About IBM Privacy Contact