I admit, designing a calendar in FileMaker is an involved process. Nonetheless, it's a common requirement, so I’ll walk you through the process step by step. I'm going to piggyback on our previously published post, but for this calendar, we're going to specify Monday as the start of the week as opposed to Sunday.
Of course, there are several different ways that we can structure a calendar. One option would be to create 42 separate relationships and portals to represent events for each calendar day. Why 42? There are seven days in a week and we need six rows to cover the number of potential weeks in a month, 7 * 6 = 42. Also, you’d have to create 42 fields to store the calendar days that would then be used to set up the relationships between the calendar and event tables. This approach can make managing edits or updates cumbersome for developers because of the volume of records.
Luckily with FileMaker 18, and as early as FileMaker 11, we can use filtered portals to create calendars. There are performance issues to be aware of when applying portal filters, particularly when using related record data as part of filter calculations. However, in this case, we'll be using global variables as our filter criteria so that dramatically decreases the amount of structure needed to create the calendar view. Take a look!
Relationship graph for 42 days
The relationship graph required for the filtered portal technique
Users typically expect to view calendars in a grid or chart format, so that's what we'll do. Unlike the calendar we designed previously, our calendar is going to be based on the week starting on Monday. Do note that FileMaker considers Sunday to be the first day of the week.
Let’s take a look at July 1, 2019, which was a Monday, so it falls nicely into the first cell of the first row. After seven days, we start a new week/row and after 31 days we have five rows.
You may be wondering why we need to create six rows instead of five. Let’s take a look at December 2019. December 1 falls on Sunday, the last day of week/row 1. And, the last day of the month December 31, falls on Tuesday, the second day of week/row 6. A month could pass through six weeks if it starts on a weekend. Tricky, right?
Not all of the 42 cells are relevant for a given month. However, we like to include all 42 cells because that allows us to customize the presentation of the calendar. We can gray out the unnecessary cells or we can display the days of the preceding and/or proceeding months.
To specify a month, we'll go through the same process outlined in our original post. We choose a date (in the field datePicked), for example, December 5, 2019. To see a calendar for December, we need to figure out the first and last days of the month. The first day of the month is easy; based on datePicked, we use the same month and year and set the day to the first:
Date ( Month ( datePicked ) ; 1 ; Year ( datePicked ) )
Now we have to determine the last day of the month. We'll back into that by finding the first day of the following month and then subtract one from that day:
Date ( Month ( datePicked ) + 1 ; 1 ; Year ( datePicked ) ) - 1
The results are 12/1/2019 and 12/31/2019. Next, we have to figure out how the days in December fall within the grid. We know that the first day of the month falls in week/row 1 so we can use this formula:
Div ( date - 1 ; 7 ) * 7 + 1
If you’d like to look into the logic of the calculation or change the calendar to start on any other day, please read our post about how to find the preceding Sunday or Monday or what have you.
December 1 falls on Sunday and the Monday that starts that week is November 25. We start there and fill in each of the 42 cells using global variables.
$$day01 = 11/25/2019
$$day07 = 12/1/2019
$$day08 = 12/2/2019
$$day36 = 12/30/2019
$$day37 = 12/31/2019
$$day38 = 1/1/2020
$$day42 = 1/5/2020
At most, 37 of the 42 portals contain days for a given month. It's up to you to decide if you want to display the dates for other months or not. For our purposes, we're going to gray out the unnecessary cells.
We use a script to dynamically generate the global values to display the days of the month because who has time to create 42 variables manually?
Let ([varName = If ( Left ( $varName ; 1) ≠ "$" ; "$" ) & $varName ;varType = GetValue ( FilterValues ( "Text¶Number¶Date¶Time¶Timestamp" ; $varType ) ; 1 ) ;varValue = $varValue ;
f = "Let ( ~varName~ = ~varValue~ ; \"\" )" ;fGetAs = "Let ( ~varName~ = GetAsXX ( ~varValue~ ) ; \"\" )" ;formula = If ( IsEmpty ( $varType ) ; f ; Substitute ( fGetAs ; "XX" ; $varType ) )] ;
EvaluationError ( Evaluate (Substitute (formula ;[ "~varName~" ; varName ] ;[ "~varValue~" ; Quote(varValue) ]) // close Substitute) ) // close Evaluate
) //close Let
This is a complex calculation but fortunately you can copy and paste it between files.
I find designing the overall look and feel of the calendar layout to be the most challenging part. I’ve created enough calendars to have picked up some tricks to share with you.
Now that we have our global variables, we can place them as merge text on the layout and arrange them accordingly.
Since we're only going to display the days of the specific month, we apply conditional formatting to the merge field if the cell is empty. Let’s start with <<$$day01>>.
events: : date = $$day01
The other portals include the same filter criteria; however, you reference the global variable associated with the respective column/row, i.e., $$day02, $$day03, all the way to $$day42.
Let’s take our calendar a step further and add the ability to filter calendar events based on calendar type. This allows us to filter events by different criteria such as holidays, birthdays, personal, etc. We must create a table to store calendar type and also update our relationship graph.
Finally, we go back to the calendar layout and set up conditional formatting on the title field. I like to specify different color formats based on the calendar type to help users visually distinguish between the various calendar types.
Feel free to use this filtered portal calendar sample file to create calendars in FileMaker yourself.
Learn more FileMaker platform design tips such as how you use placeholders and Material Design icons.
This article is also posted on FileMakerProGurus.com.