Monday, April 16, 2007

Programming Embedded Outlines

Last time, I talked a bit about programmable tabbed tables. They really come in handy and are a powerful interface construct, especially when used for certain tasks, such as progressive disclosure (more on that in a future post). Programmable tabbed tables make simple work of seemingly complex tasks, such as constructing a multi-step wizard to walk a user through a process. I think by now that most developers are familiar with the techniques behind programming a table, but did you know that you could use the same idea with embedded outlines? If not, please read on...

When you have an embedded outline and you click a link on the outline, you can, of course, have Notes highlight your selection.

You: "Yeah, ok, great...tell us something we don't know".

Me: "Wait...don't go away...this will be cool I promise. Did you also know that you can programmatically set the outline selection?"

You: " need, it gets highlighted when I click it"

Me: "Ah...that's true. But...what if you go about selecting the element associated with a certain outline element WITHOUT clicking on the outline?"

You:(in a Homer Simpson-esque way)* "Hmmm...go on..."

Here's the deal. I've had several developers ask me through the years why there is a 'Name' property for an embedded outline. This is the one I'm referring to:

The name in this case can be used programmatically, just like in a tabbed table. When you place the outline on the form and create a document based on that form, a new field called "$OUTLINE_NAME" (where OUTLINE_NAME is the name you provide in the embedded outline properties) is added to the document. This field holds a number that corresponds to the outline entry currently selected. The outline entries are labeled 1 through (max number of entries) in the order that they appear in the design (see below).

Thus, if you wanted to highlight the fourth entry in the embedded outline, your code would be a simple:

@SetField("$SectionEmbedOutline"; 4);

At this point, you might still be wondering why you would actually use this. Let me show you a scenario from one of my production applications that should help illustrate the idea. In the last post, I told you about an application in which I use a programmable tabbed table and embedded outline to display various sections to a user. The sections on this form can vary based on document status, user input, etc. The embedded outline is used to make navigating through the sections easy. That is, if the user wants to jump from the first section to the last, they can just click the appropriate link in the outline. But many times the user wants to progress through the form in the logical way that was designed based on business process rules. In this case, the user is certainly free to use the outline, but we have also provided them with simple 'Next and 'Previous' links that allow them to navigate one section at a time (see the screenshot below).

In order to make sure that the appropriate link is highlighted in the embedded outline (which is another visual reminder to the user of where they are) when these links are triggered, we make use of the programmable nature of the outline using the simple formula language snippet detailed earlier.

I think this is pretty slick on Lotus' part. What about you?

Don't forget about the fact that it might be desirable to reset the outline highlight to the first entry the next time the user opens the document (as I discussed for programmable tables in my last post). You can handle this scenario in the same way. Either set the $OUTLINE_NAME field back to 1 when the user saves the document or do so when the document is being loaded in the UI.

Finally, there's one little 'GOTCHA' to be aware of when using this technique. The number you use to highlight a particular outline entry can actually change based on the entries that are displayed in the UI, so you have to account for this in your code. For example, assume that you have an outline with six entries. In a particular scenario, the first two entries on the outline are hidden. In this situation, the third entry is considered entry number 1 as far as programmatic access is concerned. This can be a bit tricky if you are showing and hiding things a lot. If you are careful and put some thought into the way the entries are arranged on your outline, this usually isn't too bad...nothing a simple @If can't handle, but it's important you know about it so you don't end up pulling out your hair!

OK...that's it...another short and sweet post. If you weren't already aware of this technique, I hope it comes in handy for you some time in the future. As always, feel free to leave your comments or drop me a line if you have any questions. Cheers!

*Disclaimer: I am not implying that my readers are like Homer Simpson...I just like when he says that! :-D


Elf said...

I've used smiliar techniques in Notes-solutions where we use questionaires. In those you have to go step by step but also be able to go back. Works very well.

Martin Perrie said...

Thanks for another interesting post, Chris. That's not something I've used before.

I guess you also need to be wary of your user wanting to "just" rearrange the order of the outline entries.

Nathan T. Freeman said...


Given that you can programmatically control the entries in an Outline as well, there's some interesting possibilities here.

Like, outline-based vertical tabbed tables that can be rearranged on a whim. Or maybe some programmable drag-targets.


Kevin Pettitt said...

Hi Chris,

Very cool post on programmatic outlines. I was able to successfully pull off some of the outline manipulation tricks you wrote about in the context of a more traditional framest/nav outline/view , but I could only get a view postopen to hightlight the outline as desired using lotusscript. This worked great except that I haven't figured out a way to restore focus to the NotesView frame.

The other strange thing, and maybe this is the expected behavior, is that the $outlinname field never appears in the document properties as an actual item on the document - at least not in my tests. This doesn't necessarily stop me from doing the manipulation, but I wanted to ask you see any different behavior.

I got really excited when I read your post because, as I alluded to in my last post, I sometimes want to use "actions" in outline entries to open a view in the view frame and do some other stuff as well. The problem there is that the outline highlights are lost after you close and reopen the database, making it necessary to stick to the "named element" outline entry type. Or so I thought. The big design goal I had was to avoid the need to code any view events that would do all the extra "stuff" that could have been done all within the outline entry. My problem then becomes how to record where the outline was the last time it was open on a user by user basis, without introducing any dependencies outside of the Navigation Form/Embedded Outline. I may not need all this given my other workarounds, but its nice to have the option available.


Chris Blatnick said...

@Kevin...Indeed, I may be completely wrong on the point of Notes creating the $outlinename field on the form. I'm thinking that perhaps my code is doing that somewhere. I'll have to track that down and see. I apologize for the confusion on that!

Michael M said...

I like the idea, Chris. But I can't get it to work. I have to click twice on the embedded outline entry to get the selection highlighted. I believe more formula is the same as yours. If I need to create the $outlinename field, should it be CFD? Any insight would be appreciated...thanks!

dogu said...


I hit a bit of a snag with this. If I use the code that sets the highlight on the embedded outline, then clicking the outline does not move the hightlight unless I also set the embedded outline highlight value.

It's not a huge deal, unless users want to do the 'rearrange the outline' thing.

Did I miss something or is this behaviour expected?



Chris Blatnick said...

@Michael & Doug...I think you are both expressing the same issue. I guess I forgot the fact that you also have to set the value of $outlinename in the code behind each outline entry. Thus, your outline entry has to be an action rather than pointing at a particular design element. Not really too much of a big deal, but something that takes a little more work to maintain. Give that a try and let me know how it works out.

dogu said...


Thanks. I was kind of figuring that was the case; glad to know I was heading down the right path.


michael m said...

Thanks, Chris. For what it's worth, I ended up having to use @PostedCommand([RefreshHideFormulas]) in order to get the outline entries to stay highlighted (selected).

Dave H said...

Thanks Chris, I really like the idea and have it working with @Formula fine, however I cant seem to replicate with LotusScript. I need to force required fields and prefer to do with LScript. I am doing a doc.ReplaceItemValue then a uidoc.reload / uidoc.refreshideformua as well as a uidoc.refresh and it wont work?? anyone have any ideas?

Dave H said...

Please disregard. I was cstr'ing the value and that was it. FYI you only need a uidoc.refresh not the others.

Curtis said...

Wondering if anyone else has tried this while using 2 embedded outlines across 2 frames? Within the same frame I can get this to work, but cross frame I can't seem to make this work. Any suggestions?

Anonymous said...

Do you have this as a demo I can download?