Tutorials/Power Apps/From Dates to Data: Adding Event Management to Your Power Apps Calendar
Power Appsintermediate

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.

NA
Narmer Abader
@narmer · Published June 3, 2026

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 NameData TypePurpose
TitleSingle line of textBrief booking name (e.g. “Client call”)
StartTimeDate and TimeWhen the booking begins
EndTimeDate and TimeWhen the booking ends
BookerSingle line of textName of the person who reserved
NotesMultiple lines of textOptional details

Add a handful of test records so you can verify the app works.

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:

powerfxItems of galDays (extended with NextDay)
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.

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:

powerfxItems of galDayEvents
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:

powerfxOnSelect of galDayEvents
Set( varCurrentBooking, ThisItem );
Set( varShowBookingForm, true )

Now create the form overlay. It consists of two layers:

  1. A full‑screen label acting as a backdrop and click shield – name it lblFormBackdrop.

    • Fill: RGBA(0, 0, 0, 0.4)
    • Height: App.Height
    • Width: App.Width
  2. 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 Default to varCurrentBooking.Title.
  • Date Picker for Start Date – set Default to:
    powerfxDefault of Start Date picker
    If( IsBlank( varCurrentBooking ),
       Today(),
       Date( Year( varCurrentBooking.StartTime ),
             Month( varCurrentBooking.StartTime ),
             Day( varCurrentBooking.StartTime ) )
    )
  • Dropdown for Start TimeItems = 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 NotesDefault = 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:

powerfxOnSelect of OK button
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 + Time combines 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:

powerfxOnSelect of Cancel button
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:

powerfxOnSelect of Delete button
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 Items of galDayEvents to filter colBookings instead of the direct data source. This avoids delegation warnings entirely and improves responsiveness.

Common Mistakes & Troubleshooting

  1. 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.
  2. Blank varCurrentBooking when adding – Without the IsBlank check in the defaults, the form will error. Test both new‑record and edit modes early.
  3. 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.
  4. 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