Securing Your Buttons
by Geoff Wells ( geoff_wells@database-systems.com )

RATING: Advanced
PLATFORM: Macintosh & Windows
VERSION: FileMaker 5
BONUS FILE: MENU.FP5, USERS.FP5

    In this third installment of my security series, I'll be expanding on some of the ideas presented in the first article published in ISO Issue 48, Protecting Your Work Beyond Built-in Security <http://filemakermagazine.com/m/a.read/issue.48/article.4/>. In that article we learned how to prevent access to different layouts on an individual user basis. This month, we will continue to enhance the user interface with 'grayed out' buttons that control access to scripts based on various conditions.

These functions use a technique that has become known as the 'portal trick'. John Mark Osborne first presented this technique at the 1998 Devcon in Monterey. It is very simple to learn and extremely useful. I highly recommend spending a few minutes to become familiar with how it works.

If a portal on a layout has no records that satisfy the conditions of the relationship on which the portal is based, nothing within the portal is visible or available. Graphics or buttons placed on the rows of the portal cannot be seen and are not 'clickable'. This is the basis for the 'portal trick'. By making the portal just one row deep and also making the portal itself invisible, anything placed within the single row will appear and disappear as the relationship becomes true or false.

In the April demo, if one of the layout buttons (Red, Green, or Blue) was clicked without the appropriate layout access privilege, the buttons did nothing. From a human interface point of view it would be better if the button was 'grayed out' and not 'clickable'.

This is how you do it:

Open the "MENU.FP5" file from April's bonus technique files in folder 48-4. Define three new Global Container fields called "Button{Red}", "Button{Green}", and "Button{Blue}. Place them anywhere on the "Main" layout, out of the way of the existing contents.

Select and copy the existing Red button. Switch to 'Browse' mode and paste the Red button into the Button{Red} global. Repeat this process with the Green and Blue buttons pasting each one into the appropriate field. In Layout mode select all three global button fields; go to "Format:Field Format..." and turn off "Allow entry into field".

After copying all three buttons switch to layout mode and select the original "Red" button graphic. Go to the fill color palette and choose the second red from the bottom. Do this to each button in turn so that each appears to be a 'washed out' version of the original.

When the full color button, (that we will place in a portal) disappears we want the 'washed out' version to appear in its place. Since everything placed within the portal will disappear it is necessary to make the 'washed out' button part of the background.

On a Macintosh, create a background graphic by holding down the 'shift-control-command' keys and typing '4'. Drag the cross hairs cursor across the area you want to copy and when you release the mouse button the clipboard will contain a graphic that can be pasted onto the layout. Use this technique to make a single graphic that is slightly larger than all three buttons.

For Windows, copy the three buttons and paste into a graphics program. In FileMaker use the rectangle tool to make a graphic that is 454 pixels x 84 pixels, (View:ObjectSize...) Paste it into your graphics program behind the three buttons and position it so that there is a 2 pixel border around the three buttons. Copy it back into FileMaker and use the graphic to replace the original buttons, which can now be deleted.

Make each of the global button fields 120 pixels x 80 pixels and set Format:Graphic to Crop. Place each button field exactly over the top of its respective 'washed out' graphic.

In the April version of this article a conditional calculation within each script determined if the user had access to a particular layout. Use exactly the same formulas to create calculation fields for the left side of the visibility relationships. Open the GoToRed script (called OLD-GoToRed in this month's technique file) and copy the formula from the 'If' statement. Define a calculation called ButtonVisibility{Red} with a number result and paste the formula just copied.

ButtonVisibility{Red} =

GetRepetition(LayoutLockRed, 1) and GetRepetition(CurrentKey, 1) or
GetRepetition(LayoutLockRed, 2) and GetRepetition(CurrentKey, 2) or
GetRepetition(LayoutLockRed, 3) and GetRepetition(CurrentKey, 3) or
GetRepetition(LayoutLockRed, 4) and GetRepetition(CurrentKey, 4) or
GetRepetition(LayoutLockRed, 5) and GetRepetition(CurrentKey, 5) or
GetRepetition(LayoutLockRed, 6) and GetRepetition(CurrentKey, 6) or
GetRepetition(LayoutLockRed, 7) and GetRepetition(CurrentKey, 7) or
GetRepetition(LayoutLockRed, 8) and GetRepetition(CurrentKey, 8)

Copy the formulas from the GoToGreen and GoToBlue scripts and use them to create the fields ButtonVisibility{Green} and ButtonVisibility{Blue}.

ButtonVisibility{Green} =

GetRepetition(LayoutLockGrn, 1) and GetRepetition(CurrentKey, 1) or
GetRepetition(LayoutLockGrn, 2) and GetRepetition(CurrentKey, 2) or
GetRepetition(LayoutLockGrn, 3) and GetRepetition(CurrentKey, 3) or
GetRepetition(LayoutLockGrn, 4) and GetRepetition(CurrentKey, 4) or
GetRepetition(LayoutLockGrn, 5) and GetRepetition(CurrentKey, 5) or
GetRepetition(LayoutLockGrn, 6) and GetRepetition(CurrentKey, 6) or
GetRepetition(LayoutLockGrn, 7) and GetRepetition(CurrentKey, 7) or
GetRepetition(LayoutLockGrn, 8) and GetRepetition(CurrentKey, 8)

ButtonVisibility{Blue} =

GetRepetition(LayoutLockBlue, 1) and GetRepetition(CurrentKey, 1) or
GetRepetition(LayoutLockBlue, 2) and GetRepetition(CurrentKey, 2) or
GetRepetition(LayoutLockBlue, 3) and GetRepetition(CurrentKey, 3) or
GetRepetition(LayoutLockBlue, 4) and GetRepetition(CurrentKey, 4) or
GetRepetition(LayoutLockBlue, 5) and GetRepetition(CurrentKey, 5) or
GetRepetition(LayoutLockBlue, 6) and GetRepetition(CurrentKey, 6) or
GetRepetition(LayoutLockBlue, 7) and GetRepetition(CurrentKey, 7) or
GetRepetition(LayoutLockBlue, 8) and GetRepetition(CurrentKey, 8)

Since these calculations will produce a result of '1' only when the user has access to a particular layout, it can be used to control the visibility of the buttons that have the GoToLayout scripts attached.

It's a good idea to include a field in all your files that always equals '1'. It will be used to set up relationships between files that will include all records and as the 'right' side of a 'true' relationship. A calculation that evaluates to true or false (0 or 1) can become the 'left' side of a 'portal trick' relationship that controls whether some element on a layout is or is not visible.

    Note:

The USER.FP5 file already contains a relationship based on the "Constant" fields that is used in the USER.FP5 file to display the three "LayoutLock" fields that are actually in the MENU.FP5 file. We can reuse the 'Constant' field in MENU.FP5 to create three self-relationships with the 'ButtonVisibility' fields.

A self-relationship is one where both sides of the relationship use fields that are contained in the same file. The fields in the left hand list (the 'current' file) can be a global but the field in the right hand list (the 'related' file) must be a text, number or calculated field that can be indexed. The 'ButtonVisibility' fields use globals in their calculations so they must be placed on the left-hand side of a relationship specification.

Define three new self-relationships from each of the 'ButtonVisibility' fields to the 'Constant' field. Call them Visible{Red}, Visible{Green}, and Visible{Blue}.

Place a single row portal for each of the new relationships around each of the corresponding buttons. Set the fill and line color of the portals to transparent.

Either edit the existing GoToLayout scripts or create three new ones that have the single step "Go to Layout ["Color"] where Color is either "Red", "Green" or "Blue". Attach the scripts to the corresponding global button fields and you are done.

Watch the buttons change color as the layout locks are altered in the User.FP5 file. Click the buttons and notice that they only work in full color activated mode.

Securing Conditional Scripts

So far we have only used the lock and key technique to control access to layouts, but there is no reason the same logic cannot be extended to include any script that requires secure access.

The fields labeled 'LayoutLocks' for this article do not have to control access to layouts or be tied to a user. They can dynamically control the conditional execution of any script.

You might, for example, have a function that branches to different routines contingent on whether the current user is a supervisor or a data entry person. A user could be prevented from viewing or modifying certain types of records or allowed to change only their own record.

Dynamic keys that are set from within the program could indicate the status of an order - filled, shipped, backordered, etc. Your script could then branch to different functions based on a simple truth test.

Using the fields in this month's technique files, we can set up an "Example" script based on the visibility calculations:

If ["ButtonVisibility{Red}"]
Show Message ["Do Red Stuff"]
End If
If ["ButtonVisibility{Green}"]
Show Message ["Do Green Stuff"]
End If
If ["ButtonVisibility{Blue}"]
Show Message ["Do Blue Stuff"]
End If

The above example will show all, some or none of the messages based on the contents of the layout lock fields in the USER.FP5 file.

Happy FileMaking!

Geoff Wells is a self proclaimed "Beachologist". Together with his wife Vicky, he has taken it upon himself to investigate and report on each and every beach in his new home of Eleuthera (Bahamas). Heading up the Caribbean office of Advanced Database Systems is a tough job but someone has to do it. Email using geoff_wells@database-systems.com or visit <http://www.database-systems.com>.