The conversation
A dialogue is a conversation between two people. Two people usually have conversations like this:
- Pilot: (putting sandwich back on the tray) "What do you think about the economy?"
- Co-pilot: (not looking up from the phone) "I need a raise, what about you?"
- Pilot: (wiping up garlic-bread crumbs) "Well, I'll be eating at the five-star this week."
- Co-pilot: (frowning at the game) "Their chicken soup is tasty."
Those two people are exchanging information in a way that allows them to tend to other things during the conversation.
Sometimes two people switch to a conversational mode that becomes tightly focused:
- Pilot: "We are running out of gas."
- Co-pilot: "Switch to the other tank."
- Pilot: "Did that an hour ago."
- Co-pilot: "This is not good. We'll be over water for another hour."
- Pilot: "I've got an idea, but you are not going to like it."
In this mode the co-pilot is now ignoring the Solitaire game and the pilot is ignoring the sandwich.
A dialog box is a window where a person has a conversation with a computer. JMP has two kinds of dialog boxes: modeless and modal. The find/replace dialog is modeless; it remains open and switches its focus between windows as easily as the pilot switched from the economy to food. JMP's save dialog is modal; once JMP enters the save-a-file mode, nothing else can get in the way until the file is saved or the save is canceled. JSL can create custom dialogs, modeless or modal, to give you some information and get an answer back.
Getting answers
The life of a modal dialog box:
- Build a display box tree
- Open a window to own and show the display box tree
- Wait for the window to close
Item 1, build the tree, is often done as the argument to the New Window function. Items 2 and 3 are the New Window function. Here's an alert box modal dialog.
rdata = New Window( title, <<MODAL></MODAL>
<
Just thought you should know...
This little window's two-way dialog is very simple:
- JMP: "Wake up! This thing happened!"
- You: "OK"
There is no data to return. The New Window function does return a value; it tells if you pressed the OK button
{Button( 1 )}
or closed the window with the OS-provided close button
{Button( -1 )}
It is returning a list with one element. You could test for Cancel vs OK using rdata["Button"] which will be -1 or 1. You probably don't care since you didn't put a CANCEL button in the dialog.
View more...Not only do you need to supply the title and text, you need an icon. I like the addin for built in icons for a quick project like this. You can make custom bitmaps too, if you need them.
@Justin_Chilton Built-In JMP Icons
The "Error" icon might not exist on the Mac.or a warning icon of a different size
warning!
The trash
A long time ago JMP put the contents (display boxes) of a window into an internal structure called The trash before asking the OS to close the window. The trash evolved over time to solve many problems and sometimes create unintended side effects. One side effect was to make a modal dialog's display boxes available to JSL for a short time after the dialog was closed, and this was how some users retrieved answers from modal dialogs...literally getting them out of the trash.
- Pilot: (tossing garlic-crumb napkin in the trash) "mmmm. good."
- Co-pilot: (wrinkling nose) "I think I'll empty that now. Or maybe in a bit."
Problems with The trash revolve around how much it fills up and when to empty it. In early versions of JMP the trash was emptied when the next window was displayed, or some variation. When the trash is emptied, its contents are gone, and those modal dialog box variables vanish too. It mostly worked, most of the time, but it kept evolving, trying to solve various problems. Eventually @hecht_jmp put a state-of-the-art solution into JMP that resolved the issues with the trash...but required a bit more of a plan for getting answers back from modal dialogs.
Getting answers the right way
If you want more data returned, you have to ask for it with <:
rdata = New Window( "modal dialog test",
<<MODAL></MODAL>
It said "Enter your name" before I typed over it.
{answer = "Craige", Button( 1 )}
You can use rdata["answer"] after the New Window() returns to get the value from the text box in the variable answer. (Do the cancel test first.)
Is a List like an Associative Array?
All of the examples above return a list. The items in the list all look like simple assignment statements or some kind of function call. A little used, poorly understood feature of JMP is subscripting lists using those names, rather than the more usual numeric index.
result = New Window( "Tell us about yourself",
<<MODAL></MODAL>
Bob is about to press OK
The value in result might be
{name = "Bob", title = "programmer", Button( 1 )}
or, if Bob cancels,
{name = "Bob", title = "programmer", Button( -1 )}
If( result["Button"] == 1,
Write( Eval Insert( "\!n\[^result["name"]^ is a ^result["title"]^]\" ) )
, // else
Write( "\!nthe dialog canceled." )
);
Bob is a programmer
The list does act a bit like an associative array, though it is done with a sequential lookup. (If you need an associative array, make one. Don't use this list behavior...it is a poor substitute.)
Modal dialog semantics
When your user presses the cancel button on a modal dialog, they expect nothing to be changed. Any JSL in a modal dialog should be operating the dialog without making changes to variables in the rest of your program. Here's a bigger example; it has a modeless dialog for launching reports:
You can work in other windows while this window is open; it is a modeless dialog.
Each time you press the Make Report button, another window opens:
A report showing the values from the modeless launcher.
There is also a Set Parameters button that opens a modal dialog with a validation routine. This cancel button will not apply any changes to the launcher above.
The validation routine opens yet another modal dialog.
- Pilot: (squinting) "This looks complicated!"
- Co-pilot: "We can do this. It has comments!"
// here's a simple modal window. It provides a warning, but no data is returned.
alert = Function( {title, text, icon = "error"},
New Window( title, <<MODAL></MODAL>