Home     Files    FM 101

Global Container Fields    

By Fenton Jones

We're going to look at how to use global container fields to create layout effects, such as alternating background color and highlighting.

It's difficult to look at a full-screen list view of rows (records) when they're all the same color. You can leave darker spaces or stick lines beneath each record to separate them. But my experience is that it not only takes up a little extra room, but is actually distracting, making it harder to focus on the data.

It also violates a general rule of layout that I've discovered, which is, "Show the minimum of layout objects that are needed to distinctly display the relevant data." Something is needed to "distinctly" show the data; just plopping it on a background isn't enough. But too many layout elements can be worse than too few. Every line draws some attention, so make sure it is needed. You can also lessen the confusion of interfaces by reducing contrasts, ie. using a light gray next to a slightly darker one rather than too much black and white.
Notice also that you only want the "relevant" data. If there is too much information it also becomes difficult to quickly see what you need.

Alternating Row Background for Lists
The best way to show lists I've found is to have alternating rows of light gray and white, or similar colors. The data is clearly visible and distinct from the adjacent records.
This capability is built-in as an option in Portal views, and is easy enough to create for other lists.

It uses a global container field to hold the alternate color(s) and a calculation field to display it. Remember that a global field is available to all records. So all that is needed is a calculation that is true for every other record.

Layout steps
First create a global field, RowBack_g, type Container. In Layout Mode, create a new blank "Graphics" layout. Click on the Body tab and choose a light gray fill, so you can see the next steps. Put RowBack_g on it, most any size will do.
Give it a line but make the fill transparent. Choose Graphics from the Format Menu, then check Reduce or Enlarge image and uncheck the Proportional box. This will allow whatever you paste in to completely fill the box no matter what size it is.

Select the Rectangle tool over in the Tool Bar and draw a box on the layout. Fill it with white. Copy it. Now switch to Browse Mode, click RowBack_g and Paste. It should fill with white. (Having to copy in Layout, then paste in Browse is annoying, and a little confusing, but unavoidable.)

Calculation
In order to only have this color appear on every other record we need a calculation field, also with a container result;
RowBack_c = If (Mod(Status(CurrentRecordNumber), 2) = 1, RowBack_g, "")

The Mod function divides by a number (2 in this case), then returns the remainder. This returns 1 for the 1st record, 0 for the 2nd, 1 for the 3rd, 0 for the 4th, etc..
Since Status(CurrentRecordNumber) is recalculated for every found set, it will always be this pattern no matter what records are showing.

List View Layout Steps
Go to the List View layout, in Layout Mode. Put RowBack_c across the whole body, a little wider than the last field on the right. Use the Size info box to make it the same height as the Body. Put it right up against the top (Header), but not into it. You can tell if you can just see the little dotted line. (I set my Rulers to pixels with 1 pixel increments.)

A tip (from Beverly Voth) makes it fill the Body perfectly. Use the Field Borders dialog, Format Menu (Cmd-Opt-B) to set the border lines on for all sides. Then in the line width set it to none. This allows the background color to completely fill the size you've set.
Choose Graphic from the Format Menu, check Reduce or Enlarge, no Proportional for RowBack_c as well.

Send RowBack_c to the back of the layout (Cmd-Shft-Opt-J). Choose the lightest gray for the Body color (use the Body tab). Switch to Browse Mode and voila, alternating row backgrounds.
If it doesn't work, drop RowBack_c down a pixel, using the arrow key. It often gets sucked up into the Header.
Once you get it just how you want it, you might want to lock it, so that you can select fields on top of it easily without accidently missing them and selecting RowBack_c.
Another minor tip, whenever you need to do any layout work in the body, click on a row in Browse Mode that has the background color first before switching to Layout Mode; otherwise you get the default graphic picture, making it impossible to see anything else.

Set all your fields on the row to be transparent. Borders are optional. I find that the top and bottom ones are unneeded. A clean way to show off columns of right-aligned numbers is to set them to have only a left border, with a medium gray line color. Put a pixel or two between fields. It looks clear but uncrowded.

Easy Row Outliner
Another great side-effect of the RowBack_c field is that it can function as a fast and easy row outline highlight. For best display the other fields should be non-entry. Rowback c must be enterable (Field Formats, Format Menu, or Cmd-Opt-F).
When you click on a row, the edge of RowBack_c turns black, instantly outlining the current row. It's very useful in wide column layouts that go off the screen, so you can still be sure which record you're on, without having to always glance over at the little vertical bar on the left.

Highlight with Color
There is another more graphic way to highlight the edge with color. It involves a little more effort and has one serious drawback. It only involves a simple script, but it causes the screen to redraw. Still, if you want to really highlight a wide record for important editing or viewing, it may be worth it.
The steps can be added to a script that goes from another layout, such as a Form view layout, to a List view, so the current record will not only be active, but highlighted.

Define another global field, RowBox_g, type Container. Go to the Graphics layout, Layout mode, and put it on the layout. This time stretch it to about the same size as you'd want it. Set it to Reduce or Enlarge, just to be safe. Now draw a another box with the Rectangle tool, the same size as RowBox_g. This time set the fill to transparent and the line color on and colored. Copy the box. Switch to Browse Mode and Paste it into RowBox_g. It should look the same.

Define a new calculation field, RowBox_c, with a container result.
If (Serial_ID = Serial_ID_g, RowBox_c, "")
[You'll also need the usual fields, Serial_ID, auto-entered serial number (type text), and a global, Serial_ID_g, type text. You almost always need these.]
Now you need a Script:

If ["Serial_ID <> Serial_ID_g"]
   Set Field ["Serial_ID_g", "Serial_ID"]
   Exit Record/Request
End If

Put RowBox_c on the List View layout, on top of the fields. The easiest way is to Option Shift-Drag RowBack_c a little, then double-click it and change it to RowBox_c (since they're the same height). Hit Cmd-Shft-Opt-F to bring it to the front. (Use them keys.)
I like to make RowBox_c a pixel or two narrower in width than Rowback c, so I can select either, by clicking at the far right.

If the fields below are not editable, you can attach the script directly to RowBox_c (Format Menu, Button). Then just clicking on a row will highlight it.
But if they are editable, you'll need a small button to trigger the highlight. It can be in the box, on the left. Or the highlight could be the result of any navigational script, by tagging the above script at the end.
Set RowBack_c to be non-enterable if you're using the small button method, so it doesn't trap the cursor if you click somewhere else first.

Background Highlight
You could use pretty much the same setup to do a background highlight color. Then you wouldn't need the RowBox_g field with the box. Just redefine RowBack_g to be repeating (3). On the Graphics layout, Format it to show the 3 repetitions. Paste a background highlight color in the second one (while you're at it, paste a darker gray into the third repeat now too).

Get it by changing the RowBox_c calculation a little. RowBack Hc =
If (Serial_ID = Serial_ID_g, GetRepetition(RowBack_g, 2), "")
Put it on the layout just above the RowBack_c field.

Conditional Background Highlight
One more possibility. You can have more than one calculated background color. Since this doesn't depend on a script, it won't cause the screen to redraw.
I found that I needed this in a case where I wanted to show that some records were different from the others, while still keeping my regular alternating background on the rest. The first part of the calculation could be any condition you want; it will override the alternating color when it is true.
For the darker gray in the 3rd repetition of RowBack_g, use this calculation in place of RowBack_c.
RowBack Alt c =
If (Mod(Status(CurrentRecordNumber), 3) = 1, GetRepetition(RowBack_g, 3), "")

Option-Drag RowBack_c to make this new field, just above it on the layout. This will show the darker shade of gray on every third record. I used a simple variation of the first calculation, but it could be anything.

To be efficient, you could put the calculations together, so that you only needed one calculation field instead of two to do both backgrounds.
RowBack_c=
If (Mod(Status(CurrentRecordNumber), 3) = 1, GetRepetition(RowBack_g, 3),
If (Mod(Status(CurrentRecordNumber), 2) = 1, RowBack_g, ""))

This is known as a "nested" calculation. Notice that the Mod, 3 argument goes first, so it can override and give us a different color. Also, the default is written last, on a line by itself. This not only makes it easier to read, but easier to count those darn parentheses. Two If's requires two parentheses at the end. You could even put each argument and result on a different line, as the calculation dialog ignores typed carriage returns.

Send comments, questions, toys to Fenton Jones

Top