Custom Prompts In LotusScript
In LotusScript, prior to R5, you were limited to an Input Box for getting any kind of text input from the user. What if you want something else?
In R5, Lotus added the PickListCollection, PickListStrings, and Prompt methods to the NotesUIWorkspace class. These help, but what if your client isn't on R5, or what if you want something even more customized?
That's where creating your own dialog box comes in handy. First, create a subform in your database. Call it whatever you want; for this example let's call it DialogBoxSubform. On the subform, add a layout region. Size it to whatever size you're going to need for your dialog box. Inside the layout region, add a text block. Inside the text block, put in your instructions. Then, add a new field inside the layout region. Again, it can be named whatever you want. Be sure to not use a name that is the same as a field name on your form (use a new name). For the demo let's use DialogBoxDropDown. Set the field to be of type ComboBox. This will give us a drop-down type field where only one value can be chosen. Any of the other field types can be used, but this is just how the demo is going to use it. Move to the second tab and instead of specifying the choices (which you can, but this way will be "cooler") say "use formula for choices". And in the formula window, enter DialogBoxChoices. This is the name of a field that doesn't exist anywhere. Since it's the name of a field and not text, don't use any quotes around the name.
Now, back to your form. Wherever you have the need for this custom dialog box (an action button, for example), you'll need to create the choices. This is done by creating a field on the back-end document. That field is DialogBoxChoices (the same field used in the formula window of the combo box field properties). That field doesn't exist anywhere, but it can be built inside the script. This means that the choices for that drop-down can be determined at run time (and changed every time the script is run, if you want). Here's some sample script that will do that:
Dim ws As New NotesUIWorkspace
Dim uidoc As NotesUIDocument
Dim doc As NotesDocument
Dim item As NotesItem
Set uidoc = ws.CurrentDocument
Set doc = uidoc.Document
While doc.HasItem("DialogBoxChoices")
Call doc.RemoveItem("DialogBoxChioces")
Wend
Set item = New NotesItem(doc, "DialogBoxChoices", "")
Call item.AppendToTextList("This is option 1")
Call item.AppendToTextList("This is option 2")
' Continue adding more elements in this fashion...
After this part of the script, you will have the choices for your drop-down list defined on the document. Then, when the dialog box appears, the drop-down will see that it needs to go to the field DialogBoxChoices for its options and it will grab them from the back-end document.
Continuing with the script, the dialog box needs to be shown:
Dim retValue As String
If ws.DialogBox("DialogBoxSubform", True, True, False, False, False, False, "Dialog Box", doc) Then
retValue = doc.GetItemValue("DialogBoxDropDown")(0)
End If
The dialog box method returns true if the user clicks OK and false if the user clicks Cancel. So putting it as the condition to the If statement means checking to see if the user clicked OK. Inside the If block, grab the return value from that field on the dialog box. Here is where making sure that a new field name is used is important. And notice that the "NoNewFields" parameter on the Dialog Box call was set to False - otherwise the new field wouldn't be added to the document. Getting the value is just a matter of getting the value from the back-end document in the usual format. From then on you can use it however you want.
This method can be used in edit mode on an existing document. Note that there's the chance that those fields will be stored with the document (if the user wants to save their changes). In your action, before exiting, you can remove all instances of DialogBoxChoices and DialogBoxDropDown to save the disk space.
Will This Work In Read Mode?
Yes, it will work in read mode. The last used parameter to the call to the DialogBox method is the handle to the back-end document. If that parameter was omitted, the code would still work as-is in Edit Mode but wouldn't work in read mode. In read mode, you need to pass in the document that was just changed so the field options will be shown, and passing in the document in edit mode doesn't hurt anything. So the code above will work in both edit mode and read mode. But what you do after the code may be dependent on the document's mode.
Why use this instead of the LotusScript Prompt method? Well, like I said earlier, if your clients aren't yet on R5, then Prompt isn't an option. But even if they are, this technique can still be used. The format of a prompt box (where things appear, etc.) can't be changed. Using this method, you can control your dialog box. Maybe you want instructions to the left and a list box 4 rows tall to the right. You can design the layout region any way you want.
Will this work in views?
Yes and no. It will work in views, but only as long as you have a back-end document to work with. Notice how the Save method was never called in the script - so the fields won't be saved with the document. But you do need a back-end document so the dialog box can get its options from somewhere. So if you're going to use it in a view, then you'll want to get the UnprocessedDocuments collection from the current database (this is a collection of the selected documents in the view) and get a handle to the first document in that collection. If that collection is empty (if the count is 0) then this technique won't work.
Another Alternative:
The back-end document has been mentioned a few times in the above paragraph. If you are in a situation where you might not have a back-end document (in a categorized view, for example), then you can always create your own back-end document that never gets saved. For example:
Dim s As New NotesSession
Dim ws As New NotesUIWorkspace
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim item As NotesItem
Dim retValue As String
Set db = s.CurrentDatabase
Set doc = db.CreateDocument
Set item = New NotesItem(doc, "DialogBoxChoices", "")
Call item.AppendToTextList("This is option 1")
Call item.AppendToTextList("This is option 2")
' Continue adding more elements in this fashion...
If ws.DialogBox("DialogBoxSubform", True, True, False, False, False, False, "Dialog Box", doc) Then
retValue = doc.GetItemValue("DialogBoxDropDown")(0)
End If
Note that the back-end document was never saved. It will be discarded when the script is over, but can be used during the script.