Thursday, January 10, 2008

SnTT: Canceling an Embedded Editor Transaction

If you use embedded editors in your design, you may have run across this issue. The user starts to edit a document, only to decide that they want to select another one from the view or cancel edit mode. Unfortunately, this isn't handled very elegantly by Notes. What you get is the error message shown below.


Basically, once you start editing a document in an embedded editor control, Notes expects you to save the document. Since this is the case, we can use this fact to make a simple addition to our embedded editor. Here's my approach.

Create a new action (via a button, link, whatever makes sense) to allow the user to cancel the edit transaction. Since Notes needs the document to be saved, add some computed for display (CFD) fields on the embedded editor form to hold the initial values of the fields you are exposing for editing. Set the value of the fields like this:

@If(@IsDocBeingLoaded; field_1; @ThisValue)
@If(@IsDocBeingLoaded; field_2; @ThisValue)
@If(@IsDocBeingLoaded; field_3; @ThisValue)
etc.

When the doc is opened in the embedded editor, these CFD fields will get set to the starting values of their corresponding fields. If you want to cancel the edit transaction, you just need to set the fields back to their initial values, then save the doc. Something like this:

@SetField("field_1"; field_1_OnOpen);
@SetField("field_2"; field_2_OnOpen);
@SetField("field_3"; field_3_OnOpen);
@Command([ViewRefreshFields]);
@PostedCommand([FileSave])

This is an elegant way to handle a fairly common scenario when using embedded editors.

Labels: , ,

permalink | leave a comment

Tuesday, August 07, 2007

Using an Embedded View as a Picklist

[Hi Everybody...Chris here. I'm very happy to be able to present to you the first guest post on Interface Matters. I thought this was a cool technique and since it was demonstrated to me using the Kwik-E-Mart database, how could I refuse! ;-) So, please welcome Keil Wilson with a great post on using an embedded view as a picklist. Take it away, Keil...]

The problem…
I’ve built dozens of applications that included Picklists (either @Picklist or NotesUIWorkspace.Picklist) to allow the users to select one or more documents from a list of documents. Generally, this Picklist is called from a button on a form that tests if the user pressed ‘OK’ or ‘Cancel’ and then performs some action using the selected document(s). The Picklist function in Notes is very cool for a number of reasons, but one of the biggest is that it just uses a Notes View to display a list of documents from which the user can pick. This gives you all of the formatting controls available to Notes Views and can help provide a consistent user experience so that the list of documents displayed in the Picklist looks just like the lists of documents displayed in your Notes Views. You can include the view icons or graphics, categories, and you can filter that list of documents displayed using view categories.

What if your users want to select documents from one of two or three different categories, though? What if, for instance, the users want the Picklist to show all accounts sometimes, current accounts sometimes, and past accounts sometimes? You have three different buttons on your form, right? If the user presses the wrong button, then they have to push Cancel to close that Picklist and then click the correct button. What if you could just have one Picklist that can display all three categories depending on which radio button or combo box selection the user chooses? We all work with similar dialogs on a regular basis, like the “Choose address book” combo box on the Select Addresses dialog in the mail file or the “Server” selection combo box in the open database dialog.

This was my challenge recently, and while the solution I developed wasn’t without compromise, I think it gets pretty close to a Picklist with multiple options for the documents displayed in the list.

About this example…
This review will use Chris’ Kwik-E-Mart Squishee Order System as an example (get the database now). The challenge here was to add an action on to the “Kwik-E-Mart Squishee Order Form” form that would allow the user to copy an existing Squishee order item. To do this, the user would select the existing item from a Picklist like control that could be filtered to show only those Squishee order items on the current order form, or show all Squishee order items in the whole system.

  

Check out the video demo of this in action...

The above dialog box is triggered from a simple action hotspot on the “Kwik-E-Mart Squishee Order Form.” There are six design elements involved in the technique I used here. There are two embedded views (Current Customers & All Customers), two shared actions (OK & Cancel), the “Copy an Order” dialog box (on which the two views are embedded in a programmable table), and the modified “Kwik-E-Mart Squishee Order Form” originally created by Chris (the only change was the addition of the “Copy Order” action hotspot). The key concepts here are: 1) a dialog box with a two row programmable table that displays each embedded view based on a radio button selection, 2) the use of the action button bar on the embedded views to create/display the “OK” and “Cancel” buttons, and 3) storing of the selected document’s NoteID in the Notes.ini file for later use after the dialog box has gone out of scope. All of these are simple concepts (often discussed before by Chris and other developers), but they come together to make a flexible and functional solution.

So let’s start with the views…
In the Kwik-E-Mart Squishee Order System, there was an existing view that did almost exactly what I wanted. So I did what any good coder does…I copied it, modified it slightly, and am now taking credit for its form and function. In fact, I did that twice. So the embedded view on Chris’ “Kwik-E-Mart Squishee Order From” has been adapted to work in the “Copy an Order” dialog box. It is important to note here, that because I’m working with essentially the same view that Chris had already taken the time to create, test, and format beautifully, not only did that lighten my work load, but it also provides a pretty consistent look and feel on my new dialog when compared to the existing system. Once I had modified the views’ selection formulas and columns to meet my needs, I cleared all of the action buttons from the view. Now all I needed were my two new action buttons.

Actions are the key…
The view action buttons are the key to this whole solution, as well as the weakest point. In order to determine which document(s) were selected in the embedded view, I needed a way to trigger some event within the embedded view. I tried several different things, like Queryclose (which doesn’t fire in an embedded view), but nothing worked. Finally, after some research on the developerWorks forums (and reading posts like this one from Jamie Grant), I decided to try replacing the dialog box form’s “OK” and “Cancel” buttons with view action buttons. Notes gives developers a lot of control of the look of view action buttons, but their placement above the view is pretty much locked down. It is this unorthodox placement for the “OK” and “Cancel” buttons that gave me the biggest pause about this approach.

Because both embedded views display the same type of documents and I wanted to do the same thing with the selected document regardless of which view was displayed, I was able to create two shared actions (one for “OK” and one for “Cancel”) that would go on both views. I had to do a lot of tweaking on the format of the view action bar for each view. If you’ve never tweaked the action bar properties (accessing these properties is less than intuitive), you can right-click in the Action Pane in Domino Designer and select “Action Bar Properties…”, or you can click anywhere in the Action Pane and select “Action Bar” in the properties box list. Use the Notes help and take some time exploring all the action bar properties options and what they do. I’ll explain what the buttons do, but you can download the sample database to see the code.

The code behind these action buttons is very simple. The OK button does four things:
1. Get a handle to the parent form/document currently open in the UI (our dialog box).
2. Get a handle to the document that is currently selected in the embedded view.
3. Copy the NoteID of the selected document to an environment variable in the Notes.ini.
4. Close the dialog box using the UI handle we got earlier.

The “Cancel” button does three things:
1. Get a handle to the parent form/document currently open in the UI (our dialog box).
2. Clear any value in the Notes.ini variable (this indicates the user pressed “Cancel”).
3. Close the dialog box using the UI handle we got earlier.

Using the environment…

Back on the “Kwik-E-Mart Squishee Order From” our “Copy An Order” button has called our dialog box and is waiting for the user to select their Squishee order item to copy. Then the user presses “OK” (or “Cancel”), the dialog box closes and control comes back to the “Copy An Order” code. This code does the following three things (again, download the database to see actual code):
1. Test the return from the dialog box to see if the user selected something. This is done by checking if the environment variable we set earlier has a valid NoteID in it. If there’s nothing but an empty string (“”), then the user pressed “Cancel.” If there’s anything but an empty string or a valid NoteID in that variable, then we’ve got an error.
2. Assuming the user has pressed “OK”, we then create a new copy of the selected document and associate it with the current “Kwik-E-Mart Squishee Order Form.”
3. Finally, we refresh the embedded view and the current UI document. This causes the new document to be displayed in the embedded view.

And Then?!
So how could I have done this better? I was a bit uncomfortable about writing/reading stuff in the Notes.ini file (maybe that’s just a hold over from my R4 past), but everything seems to be pretty stable. The other major concern I had was about the location of the “OK” and “Cancel” buttons. Does anyone find the non-standard layout of the buttons unappealing or problematic? I tested this with the users and no one commented on it at all. Is it possible that button location is a bigger deal to me than it is to my users? I’m interested to hear how others could (or already have) improved on this approach. Thanks for reading.


About The Author: I've been a Notes/Domino developer and consultant in Nebraska for about 10 years. I've spent the last several years working on a Notes Client focused development project for a government agency in Nebraska. The scope of this project requires innovative solutions to typical Notes Client limitations (one of the reasons I love Interface Matters). In my past lives I spent time at several small companies managing networks, manning help desks, implementing Crystal Reports/Crystal Enterprise solutions, developing and administering training, and writing code in Notes, VB6, SQL, Java, and C#.


Labels: , , ,

permalink | leave a comment

Thursday, June 14, 2007

Show & Tell Thursday: Download Edition (My Cup Runneth Over)

Since I promised at both ILUG and Lotus Developer2007, I figured I better get some of my example databases out here for you to check out. I've also received a lot of e-mail with questions about various concepts over the last few months, so those might be included here as well. Finally, I'm including other databases I've made available in the past on this post as well, just so this becomes a comprehensive index of all the downloads to date. Read down through the list and see if there are any goodies you'd like to have. If you find anything that's of real use to you and you'd like to show your appreciation, you can go help Eileen and contribute to her cause!

As always, feel free to shoot me a mail (chris AT interfacematters.com) if you've got questions. I can't guarantee I'll answer right away (or that I'll know the answer), but I promise I will reply.

Disclaimer 1: All of these examples are proof of concepts. While many of the techniques come from applications I've developed and am using in production, I strip all extraneous code down to the bare minimum so you can focus on the mechanics of how the technique works. If you choose to use these ideas, please remember to use error checking and applicable standards based upon your company's best practices.

Disclaimer 2: I never said I was a good programmer! :-)

Disclaimer 3: Snausages...they really don't taste that good...









Building A Wizard Using Programmable Tabbed TablesI like Wizards...both the kind that can do cool magic tricks like turn your wife into a horny toad (no, you pervs...a horny toad) and the "really helpful from a usability standpoint" kind. Wizards are great for walking users through a multi-step process one task at a time. They're very easy to create with a programmable tabbed table you pull up in a dialog box. This demo shows you how.
Notes Is Like An Onion...It's Got LayersHere is the example database that I used for my Speedgeeking session at ILUG. We can stay up all night, swappin' manly stories about layers and in the morning...I'm makin' waffles!
Advanced User Interface Techniques for the Notes ClientThis was a demo database that I used for my session of the same name at Lotus Developer2007. It combines many of the past demos such as drag & drop, cascading menus, ordering a squishee (i.e. embedded editors) and the Super Burrito Configurator (woo hoo)!!!
Cool DocsThe demo that I put together on the plane on the way to Lotusphere. Just a quick idea of how a database experience can be changed in somewhat dramatic ways with just a little tweaking of the UI. Let your imagination be your guide! :-) Keep in mind that this is not a full solution...that's something I hope to work on it the future. This sample database also shows you how to easily collapse an embedded, single category view and includes code for creating "expand" and "collapse" functionality for the view as well. A nice usability touch for your embedded elements.
Fun With the DOM...Playing With The Action BarA sample snippet that demonstrates how you can use the Document Object Model to manipulate HTML elements. Since the Domino-generated action bar is just a table, you can get a hold of it and its child elements and do things like change the links, change the text based on the value of a field, turn it into a cascading menu, etc. Read the article and then follow along with the sample db.
Application Activity TrackingDon't forget this nifty little project on OpenNTF. Not only is the concept fairly useful, but what's nice about this one is the activity dashboard that summarizes all of the detail in an easy to read manner. On a related note, don't miss Kevin Pettitt's SuperNTF application, which combines this project and a host of others into a really nice framework for Lotus Notes.
Lotus Developer2007 CSS ExamplesFrom "Advanced CSS Techniques for Domino Web Applications". This zip file includes the stand-alone CSS and HTML files I was using to demonstrate some of the concepts like positioning and advanced selectors. The main Domino-based examples are in the demo database from the CD.



Now it's time to go record another segment for the Taking Notes podcast. That Bruce guy is a task master! :-)

See you on the flipside...

P.S. I'm using box.net to host these files. I tried their service quite a while back and it's really improved a lot. Very slick, easy to use interface. Kudos to them!


Technorati tags: ,

Labels: , , , , ,

permalink | leave a comment

Friday, May 18, 2007

Sample Database: Collapsing An Embedded View

A couple of weeks ago couple of months ago (wow...time is flying!), I wrote up a little post about collapsing a categorized embedded view. It got some interesting responses and also generated a bunch of questions and some calls for a sample database. I finally had a few minutes to put a sample together, so this post is to point you to that (I actually used my 'Cool Docs' database since it was easy to update). Hopefully this may shed some light on any problems you had getting this to work.

You can get the database here.

To test it out, compose a new document with either the "Collapse Embedded View Example" form or the "Collapse Embedded Single Category Example" form.

Don't Forget! When you are testing this in the client, make sure you close the form in design mode. If you don't, the embedded view will continue to stay open and the collapse will never work.


If you have any problems with the sample database, you know where to find me. Have a great weekend everyone!

Labels: ,

permalink | leave a comment

Monday, March 05, 2007

Quick Tip: Collapse All In Embedded View

For all of the great things that embedded views offer us in terms of interface mechanisms, there are some gotchas which are a real pain in the (neck, ass, {insert body part of your choice here}). One of the more annoying ones is the inability to set an embedded view using "Show Single Category" to automatically collapse when the container document is opened. This is especially troubling if there is additional categorization in the view, since everything opens expanded.



There are several hacks and work arounds that people have come up with over the years to address this, some better than others. This tip is an enhancement to one of the hacks I found in the ND 4/5 forum on developerWorks. Originally posted by Andes Mygind, this technique opens the embedded view to the category in question, collapses all the entries, expands the first entry and then closes the window. The result is indeed successful, with the embedded view collapsing nicely, as seen in the figure below.



From a user interface perspective, this solution is less than perfect though, since the act of opening the view and performing the necessary actions can actually be seen by the users. It only takes a second or so, but it is visually jarring as the screen quickly changes. To address this UI problem, I decided to apply an old web trick to hide the "behind the scenes" stuff from the user. That is, I used a frameset with two frames, one of which is set to a height of 0. I then just needed to add one additional line to the code, setting the target frame in which all of the actions should occur. I set the properties of the form in question to open in the specified frameset.



Below is the code, which I have found works beautifully:

REM {I placed this code in the PostOpen event of the container form so that the embedded view is collapsed immediately}:

REM {We don't need to do anything if this is a new document...};
@If(@IsNewDoc;
@Return("");
"");

REM {First, set the target to the hidden frame...this is where all the action happens};
@SetTargetFrame("EmbeddedViewTarget");

REM {The first line opens the view to the value we are using in the Show Single Category option};
@Command([OpenView];"YourEmbeddedView"; txt_Key);
@Command([ViewCollapseAll]);
@Command([ViewExpand]);

REM {This is a call to an agent which doesn't really do anything. I have no idea why this is here really, but this technique doesn't work without it. This agent contains just a single line of code...@Success};
@Command([ToolsRunMacro];"(f9)")

Bonus Tip: When you are testing this in the client, make sure you close the form in design mode. If you don't, the embedded view will continue to stay open and the collapse will never work!

The other neat thing about this technique is that you don't have to place the code in the view's action bar. It can actually be on the container form, which opens up more possibilities for extending the code or for different formatting options.



Finally, in addition to "Collapse All", you can do an "Expand All" in the same way:

@SetTargetFrame("EmbeddedViewTarget");
@Command([OpenView];"YourEmbeddedView"; txt_Key);
@Command([ViewExpandAll]);
@Command([ToolsRunMacro];"(f9)")

If you have thoughts on this approach or ways to improve it, I welcome them in the comments. Cheers!

Labels: , ,

permalink | leave a comment