From Dates to Data: Adding Event Management to Your Power Apps Calendar
Take your static calendar gallery to the next level by enabling users to add, view, edit, and delete events stored in SharePoint.
A calendar that only fills in the numbers of the days is a decent start, but the real power appears when users can interact with their schedule directly on the grid. In this article you’ll extend a gallery‑based calendar with full CRUD (Create, Read, Update, Delete) operations against a SharePoint list. After following along, operators will be able to tap an event to edit or delete it, and add new appointments without ever leaving the month view.
Everything builds on a basic calendar that already shows a 42‑cell grid and can navigate forward or backward a month. If you haven’t created that foundation yet, search the community for “Power Apps gallery calendar” – you’ll find many tutorials that explain the ForAll(Sequence(42), …) pattern and the varMonthStart variable. Here we’ll assume that skeleton is in place and focus on wiring it to live data.
Scenario: Co‑working Room Bookings
Imagine you operate a small co‑working space. Members reserve meeting rooms by the hour. We’ll store those reservations in a SharePoint list called Room Bookings with these columns:
| Column Name | Data Type | Purpose |
|---|---|---|
Title | Single line of text | Brief booking name (e.g. “Client call”) |
StartTime | Date and Time | When the booking begins |
EndTime | Date and Time | When the booking ends |
Booker | Single line of text | Name of the person who reserved |
Notes | Multiple lines of text | Optional details |
Add a handful of test records so you can verify the app works.
Step 1: Add the Data Source and Prepare the Days Gallery
Inside Power Apps Studio open your calendar app and connect to the Room Bookings list. Your existing days gallery (let’s call it galDays) already calculates the dates for a 6‑week grid. To safely filter events without hitting delegation warnings, each cell needs to know both the current day and the next day. Replace the Items property of galDays with this formula:
ForAll(
Sequence(42),
{
DateValue: varMonthStart - Weekday(varMonthStart, StartOfWeek.Sunday) + Value - 1,
NextDay: varMonthStart - Weekday(varMonthStart, StartOfWeek.Sunday) + Value
}
)The new NextDay field gives you an upper bound for date comparisons, which is critical for the nested gallery we’ll add next.
Step 2: Display Events with a Nested Gallery
Inside the template of galDays (the first cell), add a blank vertical gallery and name it galDayEvents. Set its Items property to filter the SharePoint list for events that overlap that day:
Filter( 'Room Bookings', StartTime < ThisItem.NextDay And EndTime >= ThisItem.DateValue )
Make the events visible by tuning these properties of galDayEvents:
- TemplateFill:
ColorFade( White, -10% )(a subtle grey to distinguish from blank days) - TemplatePadding:
1 - TemplateSize:
Self.Height / 2(or whatever fits two events per cell)
Inside galDayEvents place a Label and set its Text to ThisItem.Title. If a day has no bookings, you’ll see only the grey background – that’s fine. To show a placeholder message like “Free” you could add another label with a conditional Text property, but keep it simple for now.
Step 3: Selecting an Event – Pop‑Up Form Setup
When a user taps an event we want to open a form where they can edit details or delete the booking. In the OnSelect of the galDayEvents gallery (the whole gallery, not the inner label), store the selected record and show the form:
Set( varCurrentBooking, ThisItem ); Set( varShowBookingForm, true )
Now create the form overlay. It consists of two layers:
-
A full‑screen label acting as a backdrop and click shield – name it lblFormBackdrop.
Fill:RGBA(0, 0, 0, 0.4)Height:App.HeightWidth:App.Width
-
A white container label – name it lblFormContainer – positioned in the centre of the screen.
Inside the container add:
- A “Room Booking” title label.
- Text Input for Title – set
DefaulttovarCurrentBooking.Title. - Date Picker for Start Date – set
Defaultto:powerfxDefault of Start Date pickerIf( IsBlank( varCurrentBooking ), Today(), Date( Year( varCurrentBooking.StartTime ), Month( varCurrentBooking.StartTime ), Day( varCurrentBooking.StartTime ) ) ) - Dropdown for Start Time –
Items=ForAll(Sequence(48), Time(0, Value*30 - 30, 0))(30‑minute intervals);Default=Time( Hour(varCurrentBooking.StartTime), Minute(varCurrentBooking.StartTime), 0 ). - Repeat the date picker and dropdown for End Date and End Time, mirroring the same logic with
varCurrentBooking.EndTime. - Text Input (multiline) for Notes –
Default=varCurrentBooking.Notes.
All these controls should be surrounded by the container label to create a clean pop‑up.
Step 4: Save, Cancel, and Delete Buttons
Place three buttons in the bottom‑right of the form.
OK (Save) Button
OnSelect:
If( IsBlank( varCurrentBooking ),
// New booking
Collect( 'Room Bookings',
{
Title: txtTitle.Text,
StartTime: DateAdd( dteStartDate.SelectedDate, Time( dteStartTime.Selected.Value64, dteStartTime.Selected.Minutes, 0 ) ),
EndTime: DateAdd( dteEndDate.SelectedDate, Time( dteEndTime.Selected.Value64, dteEndTime.Selected.Minutes, 0 ) ),
Booker: txtBooker.Text,
Notes: txtNotes.Text
}
),
// Existing booking
Patch( 'Room Bookings', varCurrentBooking,
{
Title: txtTitle.Text,
StartTime: DateAdd( dteStartDate.SelectedDate, Time( dteStartTime.Selected.Value64, dteStartTime.Selected.Minutes, 0 ) ),
EndTime: DateAdd( dteEndDate.SelectedDate, Time( dteEndTime.Selected.Value64, dteEndTime.Selected.Minutes, 0 ) ),
Booker: txtBooker.Text,
Notes: txtNotes.Text
}
)
);
Set( varShowBookingForm, false );
Reset( txtTitle );
Reset( dteStartDate );
*// reset other inputs similarly*The helper
DateAdd+Timecombines the date picker’s date with the dropdown’s time. If you store times as strings convert accordingly.
Cancel Button
Simply close the form without saving:
Set( varShowBookingForm, false ); Set( varCurrentBooking, Blank() ); ResetAll()
Delete Button
Only visible when editing an existing record (check !IsBlank(varCurrentBooking) in its Visible property). Its OnSelect:
Remove( 'Room Bookings', varCurrentBooking ); Set( varShowBookingForm, false ); Set( varCurrentBooking, Blank() )
Performance & Delegation Notes
-
The nested gallery uses a two‑condition
Filter(StartTime < NextDay And EndTime >= DateValue). SharePoint allows delegation on date/time comparisons, but retrieving all rows of a large list could still be slow. To keep the app snappy, load only the current month’s events into a collection when the month changes (e.g. in the month‑navigation button actions):powerfxOnSelect of Next Month button (partial)ClearCollect( colBookings, Filter( 'Room Bookings', StartTime >= varMonthStart - 30 // buffer previous month And StartTime <= DateAdd( varMonthStart, 45, Days ) ) )Then change the
Itemsof galDayEvents to filtercolBookingsinstead of the direct data source. This avoids delegation warnings entirely and improves responsiveness.
Common Mistakes & Troubleshooting
- Time zone confusion – Power Apps uses UTC internally while SharePoint displays local time. Always compare with the same time zone, or use
DateAdd(…, TimeZoneOffset())if you need local adjustment. - Blank
varCurrentBookingwhen adding – Without theIsBlankcheck in the defaults, the form will error. Test both new‑record and edit modes early. - Nested gallery not refreshing – The calendar gallery won’t refresh automatically when you add or edit an event. Call
Refresh( 'Room Bookings' )after a save, or better, use a collection and re‑filter. - Form inputs not clearing – After closing the form, call
Reset()on each input to clear old values for the next add operation.
Final Recommendation
Building event management into a gallery calendar transforms a simple date grid into a functional scheduling tool. The nested gallery technique is the core enabler, and once you master it you can extend the same pattern to show tasks, leave requests, or any time‑based data. Remember to keep an eye on delegation and collect data proactively to keep the UI smooth. Start small – wire one SharePoint list, perfect the pop‑up, then layer in additional features like colour coding by booker or drag‑to‑resize.
References
- Original article by Matthew Devaney: Make A Calendar In Power Apps – Part 2
- Microsoft Learn: Delegation overview for canvas apps (check for latest docs)
- Microsoft Learn: Filter function in Power Apps
Learn how small coding practices—like using descriptive names, flattening conditions, and simplifying logic—can make your apps easier to update and less error-prone.
Move past the gallery and discover the hidden patterns for validation, navigation, and smart submission handling in your data entry forms.
PowerShell unlocks admin capabilities that the Power Platform admin center simply doesn’t offer—from recovering deleted apps to blocking trial licenses. Here’s how to wield them safely.