Non scrolling view headers and dynamic resizing in Domino (Notes Web-based)

 

 

Generating a simple but functional view in Domino/Notes for use on the web or intranet is pretty straightforward. Domino lets you design the view more or less the same as if you were generating for the Notes client with a few restrictions, then handles the whole view "behind the scenes" when rendering on the web. In Notes/Domino 6 you even get alternate row colouring straight out of the box on your browser.

Of course, standard, unmodified Notes views look awful on the web; for a start they look just too Notes-like, the font is a serif one, and it looks very unprofessional. However, with very little use of HTML and CSS you can make your views look very nice indeed: very un-Notes like which seems to be the aim of every Notes-for-the-web developer I have ever spoken to.

Let's assume that you've got your view up on the web or intranet (details later). Two things are missing to make it really impressive to your customers: fixed (non-scrolling) table headers and dynamic resizing of the visible view area depending on how big your user has his browser window (or, indeed, his screen resolution). Both are fixable in a big way, very simply.

Domino? Notes? Yes, it is a bit of a mismash of naming terms here. Let's be clear what I mean. Domino is the server based engine which renders all your web pages. Notes is the client your customers will use in a non-browser environment. Although II got my CLP (admin) and CLP (developer) in a purely Notes environment I have concentrated on a pure web interface (ie ditch the Notes bit, keep the Domino bit) for the last 18 months and can assure it you it has massive benefits, not least in a consistent, familiar interface for your customers.

Your web page HTML

We'll assume for the moment that you have designed a simple Notes view. We'll call it MyView for the purposes of this demo. But as mentioned above, we don't ever want to display (render) a raw Notes view straight onto the web, so we'll display it via a form called $$ViewTemplate for MyView which allows you to create a web page to whatever format you want and drop the view in it somewhere by use of the $$ViewBody field.

So far so teaching-grandmother-to-suck-eggs (but at least we're all singing off the same hymn sheet). Mixed metaphors, I know. But did you know that 8 out of 10 people don't believe what's reported in statistics?

For the purposes of this demo, we'll also assume that your $$ViewTemplate for MyView form has nothing special in it (yet).

[<div id="mainContent">

<H1>Non scrolling table demo</H1>

<div id="myViewContent">]

{$$ViewBody}

[</div>

Incidentally note the use of square bracket to start and stop pass-thru HTML. If your view doesn't display this is almost certainly because the $$ViewBody field is somehow still considered to be in pass-thru HTML by Domino. Sometimes is takes some fiddling to set/unset the area where your pass-thru HTML is to make Domino take notice. Sorry, Grandma, here's your sucked eggs back.

Changes required

The <div> block surrounding the $$ViewBody field is, of course, used so that we can refer to the view (rendered by Domino as a table) in CSS. So your CSS might say:

#myView {
width: 50%;
height: 200px;
overflow: auto;
}

#myViewContent table{
font-family: arial;
font-size: 0.9 em;
color: blue;
}

To stop the table scrolling the headers (rendered by Domino as <th> elements) do the following to your CSS:

#myViewContent table th{
position: relative;
top: expression(document.getElementById("myViewContent").scrollTop -2);
background-color: whitesmoke;
}

This calculates where you have scrolled to in the table (ie how many pixels) and places the table heading at that point, effectively overwriting anything on screen at that point (which will be one of the rows of the view you are currently looking at). That is why you need a background colour on the table header, as otherwise you would see the table content behind your table heading! Try it and see:

Header 1 Header 2 Header 3
NotesIsGreat
NotesIsGreat
DominoIsFantastic
NotesIsGreat
DominoIsFantastic
NotesIsGreat
DominoIsFantastic
NotesIsGreat
DominoIsFantastic

This table should appear as a scrollable area (unless you have your screen absolutely maximised, in which case you need to shrink it down a bit). Also the gold coloured headings should remain on-screen when you scroll.

Remember, this is an IE 5+ only solution. If you're using Firefox, Opera etc then it should degrade gracefully and just be a fixed table.


Dynamic resizing of your table

Yes, that too can now be accomplished by a line of CSS. Using the same example as above, change your CSS for the <div> block surrounding the embedded view field thus:

#myViewContent {
width: 100%;
overflow: auto;
height: expression(document.body.clientHeight - 50);
}

I added in the width purely to force the browser to use the entire space available to it, width-wise. You might want to change this to a percentage or a fixed value. The interesting bit is the height calculation. It tells the browser to work out how much space there is in the current window, subtract a fixed amount that I have arbitrarily set at 50 pixels here to take into account the page footer but will differ in your case (a certain amount of trial and error is called for), and then expand the div (and hence view aka table) to fill the window, height-wise (assuming you have enough data to do so)..

Try it! If you then resize your browser window the height of the containing div block is dynamically recalculated. Wow! Sure to earn some brownie points for you.

It's already implemented in the above example: shrink and expand your screen and you will see the view (table) dynamically expand. You might have to increase your resolution to see the full effect.

Tip

This dynamic resizing can also be put to good use in getting the footer of your screen to always be displayed at the foot of your (visible) screen without running around in circles getting CSS to behave nice. If you web page follows a traditional 3 column approach, for instance, calculate the height of the first column (div block) as:

height: expression(document.body.clientHeight - 90);

or, if your footer is in a named div block:

height: expression(document.body.clientHeight - document.getElementById("footer").clientHeight - 17)

(the '-17' is simply to adjust the vagaries of IE as it doesn't seem to take into account some border and margin sizes)

then your 90px footer will always be displayed at the bottom of the screen no matter how big the user makes it. Of course if he makes it tiny it will disappear in the usual way, but I view that as graceful degradation.

Caveats

Well, there just had to be one or two, didn't there?

The CSS expression is recalculated whenever you resize your browser. That's no overhead at all. But it is also recalculated whenever a javascript thread terminates.

Well, that's probably OK too, if you've just got onClick, onMouseOver, and onMouseOut events on your web page. But if you have a onMouseMove then the browser will try and recalculate your CSS expression about 20 times a second. Now you know why you're running a Pentium 3.4Ghz processor, because otherwise it just makes your web page slow to a crawl.

Luckily I don't ever remember having to use something so processor intensive as a onMouseMove so all my web pages work just fine, as I'm sure yours will too!

The other caveat is that all this code is designed to work in IE quirks mode; if you code in strict compliance mode (by prepending the following line before the <HTML> tag:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">

in front of the HTML, then some of the above javascript just be amended to work. Instead of using

document.body.clientHeight

we would use

document.documentElement.clientHeight

Additionally we would have to change the javascript expressions to include the characters "px" otherwise IE will ignore the value without a unit in strict mode:

height: expression((document.body.clientHeight - 90) + "px");

Whatever, don't mix and match because you might not get the desired result.