Fixing the Domino CheckBox Bug

Jake Howlett, 27 November 2002

Category: Forms; Keywords: Bug CheckBox POST form

The fact that Domino has a bug shouldn't really come as a shock to any of us. Any software application of that size is bound to have one or two. What is shocking is that Domino R5 has a bug that shows no sign of being fixed despite the fact that it has been officially documented. This article will discuss the bug and a simple solution. On the way I hope to introduce you to a few new concepts and to a way to "debug" Domino forms.

The problem (or "limitation" as Lotus would have us call it):

Likelihood is that you won't see the problem at all. It all depends on how you create your Submit buttons to save a web document. If you always use the convention of a button that uses the following as its formula then you will be okay:

@Command([FileSave]); @Command([FileCloseWindow])
However, I know that I am not alone in prefering to create my own buttons that use, amongst other things, the following JavaScript call in the the onclick event:

document.forms[0].submit();
What's the difference? Not much. As far as the interaction between server and browser is concerned the method is the same. The reason I prefer to use my own buttons is by-the-by really.

The problem is when you use a JavaScript button to submit a form that contains a CheckBox field. If you submit a new document, with some values selected, then all appears well. However, if you then reopen the document in edit mode, deselect all the values and resubmit, the changes are lost. Now, I don't know about you, but I call that a pretty major bug. Not Lotus! They pass it off like so:

This issue was reported to Lotus Quality Engineering and has been determined to be a software limitation of web browsers.

To fix it they suggest using the "normal" @Formula button. The fact that this is a complete cop-out on their behalf I will cover later.

Some background investigating:

Before I cover the simple, yet ingenious, solution I think it's important that you understand what is happening in the background. In doing so I hope it gives you the knowledge and confidence to do some Domino-form-debugging of your own in the future.

When you submit a form from a browser to a web server all the fields on the form get encoded in to a HTTP "request" string that is to the server. This is normally an invisible step in the whole surfing experience but, with the aid of "packet sniffers" like Ethereal, we can take a peak at this hidden layer.

Note: Ethereal is something I plan to write about in more detail in an article all of its own so I will just go over the basics of using it here.

With Ethereal launched and capturing all traffic on port 80, open the form in question and submit some field values. When you stop Ethereal's capture you will see a list of all the packets exchanged between the client and the server, as below:

Ethereal after a capture

In it you can see a list of the information sent between the two machine. If you then right-click on the top-most entry there is an option "Follow TCP Stream". Selecting this will present you with a box as below:

An Ethereal packet stream

In the box above you can see the whole of the conversation between client and server that resulted from pressing the submit button. The uppermost red part is the data that was POSTed to the server. The blue part at the bottom is the server's response. In this case it's simply the HTML to display a "Form processed" message.

Note: Hopefully you've learnt something even by now and can see how useful the ability to see this data could be.

In the above example I was using a very basic form that consists of one text field and one checkbox. It looks like the one below:

A simple Domino form

With this in mind let's look at the text of the POST portion of the above conversation and dissect it (I've removed some of the irrelevant parts):

POST /CheckBox.nsf/Problem?OpenForm&Seq=1 HTTP/1.1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 4.0; T312461)
Host: epsdomsvr01
Content-Length: 41

__Click=0&TextField=test%20one&CheckBox=1


All make sense? The important part is in bold at the end. The number called content-length tells the server how many bytes of data to expect and the last line is the data itself. Look at the last line in detail. It consists of what are called content-pairs. Each content-pair is made up of the name of a field and its value. In this case we have the internal Domino field called "__Click", the field called "TextField" with value of "test one" and the "CheckBox" with its alias value of "1".

Now let's look at the same form being submitted but without any of the checkbox having a selection:

POST /CheckBox.nsf/Problem?OpenForm&Seq=1 HTTP/1.1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 4.0; T312461)
Host: epsdomsvr01
Content-Length: 30

__Click=0&TextField=test%20one


Notice the difference? The content-length is shorter and the "CheckBox" is not sent to the browser. At this point you might be thinking that this is the bug. It's not. According to the W3C's HTML Specification a checkbox without a value is not considered a content-pair and so the browser is right in not sending field with the POST data.

The problem is a limitation of Domino and not as Lotus would have you believe with the browser.

What I can't quite understand is why the problem is only when you use JavaScript to submit the form. The above transcripts show the data sent when you use JavaScript. Let's compare that with the data sent when you use a button with the normal @Formulas:

__Click=e9b2f3906a21cd3480256c7e004af6f1%2F%24Body%2F0.1C4&TextField=test%20one

Notice the difference? The "__Click" field has a value other than its default of "0". This field is normally set by the onclick event of our @Formula buttons and tells Domino which button we pressed. Surely then this must be the key to it all. But why? What significance does this hold? If it can be done when you click one button then why not another and how on earth can it possibly be a browser limitation!? Lotus?

A solution:

Waiting for acceptance of this limitation being on the side of lotus would be like expecting a month of Sundays. We need a fix. Luckily I can give you one and ingeniously simple. What we need to do is fool the Domino server in to thinking there is a value being passed to the CheckBox field. If we can make this blank when there are no other options checked we can clear all the options in the field in the back-end document. Consider the form below:

The solution

The trick here is to add an extra hidden text field immediately after the CheckBox field, with the same name and with no value.

Let's see what difference this makes. First by looking at the make up of the CheckBox field and its possible values.

CheckBox field

If in the normal form you select the first and last values the POST data looks like:

__Click=0&TextField=test%20one&CheckBox=1&CheckBox=-1

So, for each selection, a separate content-pair is encoded and passed to the server. So, as long as we send these values all at once and not with any other content-pairs in between, we can pass an extra one in on the end. This is what the extra "fake checkbox" is for. Consider the same POST data but with our hidden field tagged on:

__Click=0&TextField=test%20one&CheckBox=1&CheckBox=-1&CheckBox=

Now for the clever part. If you deselect both values and submit it again the hidden text field is still considered a content-pair even without a value and so is still passed along like so:

__Click=0&TextField=test%20one&CheckBox=

Domino at the other end translates this as meaning that it should set the value of the checkbox from the listed values "1" and "-1" to simply "". Because there's no value in the field that can be "" then all selections are removed as we'd expect. Et voila!!

You can try all this for yourself as I've kindly included the two simple forms in this demo database for you to download.

Summary:

Whether this is a bug or a feature or a limitation of Domino isn't really important. More important is the fact that you can get round most of these things if you apply some "logical hacking" to the situation. While I can't help thinking this shouldn't be necessary I do quite like the eureka moments that often ensue ;o)

If you liked, hated or plain didn't get this article I want to hear your opinions. I've always wanted to discuss Domino development from this angle but have shied away as I don't know what the interest would be.