PK Information | Software & Business Consulting

View Original

Creating a Calendar Tool

Update

In search of a pre-made calendar solution in FileMaker? We’ve released a demo file of the same calendar this tutorial creates—for free! This file demonstrates a completely functioning calendar app that utilizes up-to-date UI and design principles. Either use it as a reference for your own projects, or it can be used as a stand-alone calendar app for all of your scheduling needs!

See this product in the original post

Calendars are a key part of any event software. If you use FileMaker to track events, appointments, meetings, etc., there will be time where you or your client will think of how helpful it would be to view your events on a calendar. If you want to make a calendar in FileMaker but don’t know where to begin, look no further! This tutorial will walk you though the theory and the steps to create a calendar natively in FileMaker. If you want to follow along, we have included a demo file at the end of this tutorial.

The Theory

Before we get into the actual tutorial, let’s think about what we are actually trying to do. What we want is to view event records for a specific day, while also showing the context of a full month. The best way to do this in FileMaker is in a portal showing all events for that date. On a calendar, the days are arranged in a grid. The layout of the day portals is what makes calendars in FileMaker a little tricky. Let’s look at a month on the calendar.

While there are a max of 31 days in a month, there are actually 42 squares on this calendar because the month does not start on the first, and you need extra days to make a nice even rectangle. Most months will only need 35 squares for 5 weeks, but May starts on a Friday, and therefore needs an extra week to include for the 31st. 

This calendar shows extra days at the end of April and the beginning June to fill in the extra squares at the beginning and end of the calendar. While you can choose to not show those dates, you will still have to account for them so the first day of the month lands on the correct day of the week.

To make our calendar, we will need two tables: one for the events, and one for the calendar itself. The key part of the calendar is the relationship between events and the calendar. We already know we need 42 portals to create the calendar, but we don’t need to make 42 relationships to show the events. All we need to add to the relationship graph is this:

This relationship shows all events between the date of the first square of the calendar (April 26th for the month of May) and the date of the last square on the calendar (June 6th). We will use portal filtering to display a single day’s events in each day portal. I prefer to use portal filtering because of how self-contained it is. Instead of adding 30+ relationships to the relationship graph, you only add one relationship, and filter the portals themselves to show events for that day. Creating a calendar in FileMaker is a complex task, and this contains the complexity to a single layout, without cluttering up your relationship graph.

Now that we have a plan, let’s start building the calendar! 

Build a Calendar with Single Day Events

As mentioned before, you will need two tables for the calendar: Events and Calendar. The events table contains the information you want to display on the calendar. In this tutorial, the table is named events, but it could also be named appointments, meetings, schedule, etc. It all depends on what works for your solution. If your event table has a date field, you already have everything you need here!

The next table you need is a calendar table. This table only needs a few fields and should only have one record. We use a zz prefix for developer-facing fields to group them at the bottom of the field list. zzG denotes a global field, zzSV is a scripted value, and zzC is a calculation.

  • zzG_Month

  • zzG_Year

  • zzSV_FirstDisplayDate

  • zzSV_LastDisplayDate

  • zzC_DisplayDate

The first two fields control the what month the calendar is viewing, the second two fields set the boundaries for that month, and the last field combines the month and year in a nice viewable format.

Now that we have the table structure done, let's add our single relationship. If all the events in your solution are single day events, set up the relationship so the date of the event is greater than or equal to the first display date, and less than or equal to the last display date. We will set the display date in a script when the calendar is first opened. If your solution has events that last more than one day, we will discuss setting up a calendar with multi-day events later on.

The next step is to set the boundaries of the calendar by setting the fist and last display dates. I am doing this in a script as part of the navigation to get to the calendar. To get the first display date, you can use the formula: GetAsDate ( Div ( $FirstOfMonth ; 7 ) * 7 ). We know that we need 42 day portals to fill out the month, so the last display date is the first display date + 42.

Now that we have the first display date and the last display date, we can create date variables to filter all the portals for that calendar month.

The next step is to create the layout objects. Make one portal exactly how you want it, then duplicate it to make the rest of the portals. For the simple one day portal, I have a button bar displaying the name of the event, and a button bar above the portal displaying the day for the square using the calculation Day ( $$Date[1] ). The portal is filtered by Date of the event = $$Date[1].

The button bar in the portal is tied to a script that opens a popup with event details, but you can give this button whatever function you want. Even if you do not want the events to do anything when clicked, I would recommend tying the button to a script anyways, because adding it now is much easier than going back and editing all 42 buttons later.

Once the portal is the way you want it, duplicate it and update the $$Date for portal filtering, and the calculation for the display date. Once you have created all the portals (and run the script to generate the dates), you should end up with something like this:

The last thing to do is add some niceties. May needs all 5 calendar rows, but June only needs 4 rows. To hide the last row of days if it is not needed, use the logic if $$Date[36] (the first portal on the last row) is on or after the first of next month, hide the row.

Let ([
~Date = $$Date[36] ;
~Calc = Date ( CALENDAR::zzG_Month + 1 ; 1 - 1 ; CALENDAR::zzG_Year ) ; 

~DateDay = Day ( ~Date );
~CalcDay = Day ( ~Calc ) 
];

~DateDay < ~CalcDay
)

While it is great to view the calendar for the current month, let’s give users the option to go back or forward a month with arrows. I added two arrow buttons on either side of the display date that change the current month. The arrows will call a script that increments or decrements the field zzG_Month (and zzG_Year if necessary) then re-runs the calendar setup script.

Let ( 
[
~Date = Date ( CALENDAR::zzG_Month + 1 ; 1 ; CALENDAR::zzG_Year ) ; 
$Month = Month ( ~Date ) ; 
$Year = Year ( ~Date )
];
1
)

Finally, regardless of how big you make the portals, there will always be some limit for the number of events that can be displayed on a single day. You could make the portals scrollable, but that does not let the user know that there are more events that they cannot see. What I opted for is a button bar that will display the number of events beyond the square of the calendar day. The calendar can hold a max of 4 events in a day, so if there are more than 4 events that day, I display a message that says “and x more”. The logic for this message is "And " & $$DateRequestCount[1] - 3 & " more" because the message itself covers up the last portal row. I set $$DateRequestCount in the setup script as I generate the $$Date variables.

If you only need a calendar to display events for a single day, then you are done! If you want to take your calendar to the next level, this next method allows you to display multi-day events.

Build a Calendar with Multi-day Events

First, your event table is going to need a few extra fields. You probably already have a start and end date, in your system, but to make the calendar look nice, you will also need placeholder stop and start dates. The placeholder dates are the first and last day of the week containing the entire event. Your relationship is going to use the placeholder dates instead of the single date of the event. We will get to why this is important later, but for now, set up your relationship so the end placeholder date is greater than or equal to the first display date, and the start placeholder date is less than or equal to the last display date.

This is NOT what we want!

So much better!

Because the relationships and the portal filtering use the placeholder dates, even single events will need the placeholder dates to be set. You can set the placeholder dates in a loop as you load the calendar, but that adds a lot of extra weight to the system. If you can, set up a script trigger wherever the date fields can be edited that set the placeholder dates to the sunday before the start date and the saturday after the end date.

This formula sets the placeholder date to the sunday before the first day of the event
EVENT::StartDate - DayOfWeek ( EVENT::StartDate ) + 1

This formula sets the placeholder date to the saturday after the last day of the event
(EVENT::EndDate - 1 ) - DayOfWeek ( (EVENT::EndDate - 1 ) ) + 7

If you want to go a little further and make nice rounded edges on your buttons, it’s going to take a little bit of trickery. My single day portal actually has 4 different buttons layered on top of each other with a different hide condition on each button. If that seems over the top, use a single rectangular button for each day, and don’t worry about hide conditions.

Something to remember as you set up your first day portal is how much updating the rest of the portals will require. Each time a $$Date variable is used, it will need to get updated for each portal.

Once you have your buttons the way you want, add the portal filtering. Because we are now using a date range instead of a single date, it will look a little different.

$$Date[1] ≥ EVENT::zzD_PlaceholderStart and 
$$Date[1] ≤ EVENT::zzD_PlaceholderEnd

Final step is to duplicate your portal! Because this one is more complicated, I recommend creating the empty portals with the portal filtering first, then adding your buttons. It might seem like a daunting task, but power through it. With your new calendar, you will be able to track events like a pro. Enjoy!

Note: When I first created this calendar, I learned a lot from The Support Group’s advice on how to do so.


PK Information Systems is a FileMaker-certified development agency serving the Tampa Bay and Knoxville regions. We believe that great software can change everything. Would a robust scheduling tool simplify scheduling and save you time? Contact us today!

SUBSCRIBE

Sign up with your email address to receive future posts like this directly to your inbox.

See this form in the original post