API
@-Formulas
JavaScript
LotusScript
Reg Exp
Web Design
Notes Client
XPages
 
Custom Interface In ND6
Notes/Domino 6 introduced a new kind of view/form action button: check box action button. Using this new feature, it would be possible to build an interface to your application that can be customized. In this tip, we'll show you how to create a very simple custom interface for your ND6 users.

The interface we're talking about (just to show off the technique) is one where the user chooses which of three frames they want to see in their interface. When they open the database, all three frames are shown. They can go to an action button and turn on or off any of the three frames.

First, we need content for the frames. To make things simple, let's show pages in the frames. So create four pages: Frame 1, Frame 2, Frame 3, and Frame [0]. The "[0]" is an indicator for no content. Frames 1, 2, and 3 will just contain some simple text to help you identify the frame - maybe the words Frame # (where # is either 1, 2, or 3) in large text. Frame [0] should tell the user to select one or more frames to display.

The next thing we need to do is define the framesets. There are eight total combinations, so there are eight framesets needed. The combinations can be outlined as:
(Technically, the frameset with no frames has 1 frame - the Frame [0] page)

So create the eight frameset design elements. The aliases are the important part here. So the frameset design elements you end up with are:
Frameset NameFrameset Alias
Frames 1 and 2frames12
Frames 1 and 3frames13
Frames 1, 2 and 3frames123
Frame 1frames1
Frames 2 and 3frames23
Frame 2frames2
Frame 3frames3
Frame [0]frames

Then make sure the frames are set up to hold the correct frames in the correct proportion. (In other words, the "Frames 2 and 3" design element should have two frames, each 50% of the width of the screen, with the left content as the "Frame 2" page and the right content as the "Frame 3" page). Frame [0] has only one frame and should have Page Frame [0] as its content.

Next, we need a way for the user to choose which frame(s) to display. There will be a form for the user to fill out. We'll get into the details of this form in a little bit, but for now create a form. Call it Check Box Actions. Save the form for now - we'll get back into it in a second.

The Notes client is going to need some kind of interface to launch into. So create another frameset. Give it a name of Main Navigation. The frame should have two frames (one on top of the other). The top frame should be 30 pixels high, without any scrolling. The content should be the Check Box Actions form. The reason it's 30 pixels high is because that is the height of an action bar in Notes. The action bar is all we want to show in this frame. The bottom frame (called "Bottom") should have a relative height. Its content should be the Frames 1, 2 and 3 frameset. Set the database properties to launch into this frameset. So the user will always launch into the three frame interface.

Let's go back to the Check Box Actions form. There should be two fields on the form. They should both be hidden all the time. The first is called FramesToShow and is an editable text field with a default value of "frames123" (since all frames are shown at first). The second is called SaveOptions and is a computed text field with a value of "0". This is the age-old trick of setting up a form so it can't be saved by the Notes client.

The real magic happens in the action bar. Go to the action bar, create a checkbox action. To do this, create a regular action but make the type "Checkbox" instead of "Button". The action name is Show Frame 1. With checkbox actions, there is a value that tells the Notes client whether it should be checked or unchecked. This is a formula:

@Contains(FramesToShow; "1")

So this action is going to look at the FramesToShow field on the current document for a "1" somewhere in the value. If "1" is somewhere in the value, the checkbox will be checked, otherwise it will be unchecked.

The action checkbox still has a value that tells Notes what to do when clicked. That is done in the programmer's pane. What we want to do is update the FramesToShow field to include or exclude the Frame 1 frame (depending on if it's currently hidden or shown) and then refresh everything. Here's the formula:

Has1 := @If(@Contains(FramesToShow; "1"); @True; @False);
Has2 := @If(@Contains(FramesToShow; "2"); @True; @False);
Has3 := @If(@Contains(FramesToShow; "3"); @True; @False);
NewValue := "frames" + @If(Has1; ""; "1") + @If(Has2; "2"; "") + @If(Has3; "3"; "");
@SetField("FramesToShow"; NewValue);
@Command([ViewRefreshFields]);
@SetTargetFrame("Bottom");
@Command([OpenFrameset]; NewValue)

The first thing we do is found what frames are currently being displayed, based on the value in FramesToShow. Then we set the variable NewValue to the string "frames" plus the names of the frames to show. If frame 1 is currently being displayed, add in an empty string (to not show frame 1 any more), otherwise add in a string of "1" to now show the frame. For frames 2 and 3, show them (by appending their string name) if they are currently being shown or hide them (by appending an empty string) if they are being hidden.

The variable NewValue will have one of our 8 combinations, which correspond to the aliases of the framesets defined earlier. So now it's just a matter of updating everything. The first thing we update is the FramesToShow value on the current document. The next thing we update is the check box values by refreshing the fields on the current document. The final thing we do is load up a different frameset in the lower part of the main navigation, using the alias that has already been computed.

The checkbox buttons Show Frame 2 and Show Frame 3 are almost identical to what we've seen. The value to tell Notes if it should be checked or not uses a "2" or "3" in the formula. And the only line of the formula executed when the button is clicked that is different is the setting of NewValue. For Show Frame 2 it is:

NewValue := "frames" + @If(Has1; "1"; "") + @If(Has2; ""; "2") + @If(Has3; "3"; "");

and for Show Frame 3 it is:

NewValue := "frames" + @If(Has1; "1"; "") + @If(Has2; "2"; "") + @If(Has3; ""; "3");

The proper frame is being changed and the other frames are keeping their setting.

That's it. Now, you should be able to open the database in your ND6 client. All three checkboxes should be checked by default. When you click on any of the checkboxes, the checkbox should be toggled on/off and the proper list of frames should be shown. When all three are unchecked, the page that tells you to check something should be shown.

Warnings

Since we are reloading the entire lower frameset every time, if you decide to use forms in any of the frames, the user would be prompted to save changes when switching navigation. I wouldn't recommend using this if you're using forms, anyway.

Another warning is that settings are not kept. Every time the database is opened, all three frames are shown no matter what. You could always do something with environment variables instead of the FieldsToShow field if you wanted to maintain settings from one session to another. But that's up to you.

Finally, the actual example here is pretty cheezy. The real power of this is having two or three frames as part of a "navigation" frame on the left side of your application. Maybe you could have your main navigation frame and then an optional help frame that appears if the user want it to appear. Your Main Navigation frameset would have the top action bar still, but what was called "Bottom" in this example would actually be a navigation frame on the left. There's lots of layout options here, and some will make more sense than others. The one described here doesn't make much practical sense, but the point was to show you how to set this up, not to make something that is functional from the first instant.