Friday, November 2, 2012

Modal windows in FileMaker 12

As a new major feature in FileMaker Pro 12 a setting for the script step New Window was added enabling for modal and floating windows. You can also decide if the maximize, minimize and restore buttons should be active in the window title bar and if the window is resizable. At first I was very psyched on this new feature but soon discovered that the old method for creating modal windows was the one I still preferred. I guess that this topic will split developers into two camps, those who prefers working with two-dollar-variables (persistent variables) or global fields, and those who don´t.

Personally I belong in the latter category that prefere one-dollar-variables that only reside inside the current script, mainly because I don´t need to maintain a mental retain-counter in my head for which script need what values. But now I'm "jumping the gun" a little bit, lets start from the beginning.

The Classic method
Prior to FileMaker 12 the only real method for creating a modal window was via a loop that encapsulated a pause that waited for the users input. Of course there are several ways that this could be tweaked but the standard way (according to me) required two scripts. One that contains the loop, pause and logics being performed and one very simple helper-script that simply passed along any button-clicks that the user performed.

A skeleton for the main script could look like this


And the helper looks like this
The "magic" that makes it all happen is a setting for the buttons on the layout in the modal window. All buttons call the helper-script with a string as script parameter. The parameter is passed to the main script as soon the the pause is bypassed (the script continues running). The magic setting for the button is that it should continue any already running scripts (in our case the main script) when it is done running its own steps.

When defining a button, change the valuelist "Current Script" from Pause to Resume as seen on the picture below.

The helper-script will exit and return any parameter you sent when defining the button. When the helper-script exits, the resume commands bypasses the pause in the main script and proceeds with the next script-step. As a bonus we can use the get(ScriptResult) function to get the string parameter that was passed to the helper-script (since it exited returning the script parameter as script result). Now the main script knows which button the user clicked and since we have passed the pause the main script will continue executing.

All we need to do now is to throw a couple of If-statements to decide what actions to perform.

This was a quick guide to what I would call the classic method for creating modal windows and it works just as well in earlier versions then FileMaker 12.


The FileMaker 12 way
Since FileMaker added the possibility of making modal windows natively one could argue that the need for a loop is obsolete. In a way that is correct but one must also keep in mind factors like best practice when developing. The main script might be less complex without the loop but instead we must create scripts for every button splitting our logics into more scripts.

When creating a new modal window in FileMaker 12 we simply set the window type to Modal. But that does not pause the script and await user input. Thus once the windows is opened the script should exit leaving the modal window open for the user to work in. Once the user is done working he clicks either the OK or Cancel buttons calling one of two scripts.

The script performed when clicking OK should validate the data entered by the user, save it to database or simular and then proceed to do some cleanup like closing the window and clearing global fields and two-dollar-variables (persistent variables).

The script performed when clicking Cancel should not validate or save data but still must perform the same cleanup as the OK button did.


So what to argue about?
If the "FileMaker 12 method" is a simpler and faster script to write, why not just use that? First of all I want to clarify that the following is just my own opinions and if you don´t agree thats great, please use the native modal windows and I´m sure you´ll make it work just fine! This is not criticism any way =)

There are a few problems with the native modal windows. The biggest reason that I don´t use it is because I can´t use one-dollar-variables. The reason that I can´t use them is because the script that opens the modal window is done once the window is open and thus clearing the variables. The script performed when clicking OK will not be able to use the values I stored and this makes adding stuff like related records and so on very hard. If I want my script to add a related record I need to carry the primary key value from the parent record to the secondary key field in the child table.

Now I guess that some of you are thinking "not a problem, just store it in a global field or two-dollar-variable" but thats just the thing, I do not want to do that!
Since both global fields and two-dollar-variables are persistent I must make absolutely sure to clear the values no matter what button the user clicks in the modal window. If I do not clear the values I risk a conflict between old values and new values the next time the user views the modal window. The bugs produced od that can be extremely bad and hard to find since it´s of the kind that makes you say "It works when I do it".

Of course it is not impossible to write scripts that clears variables and globals and its not even hard, but it requiers that you maintain the cleanup work in all three scripts (or more if you have mor then two buttons). If you allow for the "red X" close window button to be active you must also make sure that the cleanup work is done if the uses simply closes the window. And what happens if another developer helps out with your script. Does he know absout all the scripts he must update if all he wants to do is add another two-dollar-variable? It´s very easy to forget and thus adding a bug...

Another reason for the classic method of modal windows is that the majority of menu commands are disabled when a script is running. As long as the script is in the loop the user will not be able to access much from any menu or toolbar in FileMaker. You could do the same in the FileMaker 12 method but that would require a lot of custom menus. A modal dialog is modal because it should be impossible to exit it without your code controlling the result, when using the classic method you get that for free.

Personally I´m the type of person that prefers long scripts unless it serves a purpose to divide it into several smaller ones. The most obvious purpose being reusable code, a script that can be called as a subscript by several other scripts. A long script does not scare me as long as it is well commented and don´t nest control statements like loops and Ifs to deep. The classic method keeps ALL logics inside the main-script and thus makes it east to maintain and search for potential errors.

In some odd cases you may want to open a modal window inside a modal window. An example being if you open a modal window to add a person to a CRM but realize half way through that the company the persons works at is not yet added. You want to open the modal Add Company window without closing the already open Add Person window. When the company is added the window is closed and the user can continue to add the person uninterrupted. If you work with two-dollar-variables in this case you must be very careful when naming the variables since they are not contained inside a script. If the Add Person script set a two-dollar-variable and then the Add Company also set one with the same name you are in real truble.

Also.. it is not at all possible to open a modal window while standing in a modal window if you use the FileMaker 12 way ;-) This can only be done when using the classic way.

I am absolutely not being a critic against the new modal window feature in FileMaker 12, it´s great for lots of users. But as a professional developer and being a bit of old-school I will only use the classic method since it prevents a lot of potential errors and keeps me in control of my users actions.

Whichever method you choose to use I hope this post was helpful in some way.

No comments:

Post a Comment