I've built a similar calendar in Power Apps. My implementation is a monthly view, but the logic can be adapted for your weekly (7-day) requirement. Let me share my approach and code – hopefully it guides you in the right direction.
My Calendar Structure
conHeader_7 → Header container
├── icPrevMonth → Navigation icon (Previous)
├── lblFormHeader_7 → Displays "January 2026"
└── icNextMonth → Navigation icon (Next)
conActionBar_12 → Action bar container
├── galCategoryColorCode → Legend showing status colors
├── btnFetchCalMonthData → Hidden button to fetch/filter data
├── ddProjStatusFilter_1 → Dropdown to filter by project status
├── DatePickerCanvas1 → Date picker control
└── icReset_7 → Reset button
conMainCalendar → Main calendar container
├── galWeekday → Horizontal gallery for day names (Sun-Sat)
│ └── lblWeekdayName → Label showing day name
│
└── MonthDayGallery2_1 → Gallery with 42 cells (6 rows × 7 days)
├── lblCalDate → Shows the day number (1, 2, 3...)
└── galCalEvents → Nested gallery showing events for that day
├── Circle1 → Status color indicator
└── btnProj → Event/project button
Key Variables I Use
| Variable |
Purpose |
ctx_firstDayOfMonth |
First day of the currently displayed month |
ctx_firstDayInView |
First day visible in the calendar grid (might be from previous month to fill the row) |
ctx_lastDayOfMonth |
Last day of the current month (with time set to 11:59 PM for accurate filtering) |
ctx_dateSelected |
The date user has selected |
colCalMonthData |
Collection that holds filtered events for the current month |
My Code with Explanations
1. Reset Icon (icReset_7) – OnSelect
This resets all filters and reinitializes the calendar to today's month:
// Reset the dropdown and date picker to default values
Reset(ddProjStatusFilter_1);
Reset(DatePickerCanvas1);
// Refresh data from the source (Excel/SharePoint)
Refresh(EV_ProjectList);
// Calculate the first day of the current month
// Example: If today is Jan 15, this gives Jan 1
UpdateContext({
ctx_firstDayOfMonth: DateAdd(Today(), 1 - Day(Today()), TimeUnit.Days)
});
// Set additional context variables
UpdateContext({
ctx_dateSelected: Today(),
// Calculate the first day visible in calendar grid
ctx_firstDayInView: DateAdd(
ctx_firstDayOfMonth,
-(Weekday(ctx_firstDayOfMonth) - 2 + 1),
TimeUnit.Days
),
// Calculate last day of month with time set to 11:59 PM
// This ensures events on the last day are included in filters
ctx_lastDayOfMonth: DateTimeValue(
Text(
DateAdd(DateAdd(ctx_firstDayOfMonth, 1, TimeUnit.Months), -1, TimeUnit.Days),
"[$-en-US]yyyy-mm-dd"
) & " 11:59 PM"
)
});
// Trigger the hidden button to fetch filtered data
Select(btnFetchCalMonthData)
2. Hidden Button (btnFetchCalMonthData) – OnSelect
This button fetches and filters the data into a collection:
With(
{
// Create a filtered dataset based on conditions
wFilterProject: Filter(
EV_ProjectList,
// Status = 0 means active/open projects
Status = 0
// Only include events within the current month range
&& DueDate >= ctx_firstDayOfMonth
&& DueDate <= ctx_lastDayOfMonth
// Apply dropdown filter (99 = "All", otherwise match selected status)
&& (ddProjStatusFilter_1.Selected.ID = 99 || ProjectStatus = ddProjStatusFilter_1.Selected.ID)
)
},
// Store the filtered results in a collection for the calendar to use
ClearCollect(colCalMonthData, wFilterProject)
)
3. Month Day Gallery (MonthDayGallery2_1) – Items
Creates 42 cells (6 weeks × 7 days) to display the full calendar grid:
// Array of numbers 0-41 representing each cell in the calendar
// 6 rows × 7 columns = 42 cells
// Each number is used to calculate the actual date (ctx_firstDayInView + Value)
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41]
4. Events Gallery (galCalEvents) – Items
Filters events for each specific day cell:
Sort(
Filter(
colCalMonthData,
// Match events where DueDate equals this cell's date
// ThisItem.Value is the cell number (0-41)
// Adding it to ctx_firstDayInView gives the actual date
DueDate = DateAdd(ctx_firstDayInView, ThisItem.Value, TimeUnit.Days)
),
// Sort events by ID (you could also sort by time)
ID,
SortOrder.Ascending
)
5. Day Number Label (lblCalDate) – Text
Displays the day number (1, 2, 3, etc.) for each cell:
// Calculate the actual date for this cell and extract just the day number
Day(DateAdd(ctx_firstDayInView, ThisItem.Value, TimeUnit.Days))
6. Weekday Header Gallery (galWeekday) – Items
Displays the day names (Monday, Tuesday, etc.):
// Built-in function that returns all weekday names in user's locale
// Returns: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
Calendar.WeekdaysLong()
7. Previous Month Icon (icPrevMonth) – OnSelect
Navigates to the previous month:
// Move ctx_firstDayOfMonth back by 1 month
UpdateContext({
ctx_firstDayOfMonth: DateAdd(ctx_firstDayOfMonth, -1, TimeUnit.Months)
});
// Recalculate the view boundaries for the new month
UpdateContext({
// Find the first visible day (Monday of the week containing the 1st)
ctx_firstDayInView: DateAdd(
ctx_firstDayOfMonth,
-(Weekday(ctx_firstDayOfMonth) - 2 + 1),
TimeUnit.Days
),
// Calculate last day of the new month
ctx_lastDayOfMonth: DateAdd(
DateAdd(ctx_firstDayOfMonth, 1, TimeUnit.Months),
-1,
TimeUnit.Days
)
});
// Refresh the data collection for the new month
Select(btnFetchCalMonthData)
8. Next Month Icon (icNextMonth) – OnSelect
Navigates to the next month:
// Move ctx_firstDayOfMonth forward by 1 month
UpdateContext({
ctx_firstDayOfMonth: DateAdd(ctx_firstDayOfMonth, 1, TimeUnit.Months)
});
// Recalculate the view boundaries for the new month
UpdateContext({
ctx_firstDayInView: DateAdd(
ctx_firstDayOfMonth,
-(Weekday(ctx_firstDayOfMonth) - 2 + 1),
TimeUnit.Days
),
ctx_lastDayOfMonth: DateAdd(
DateAdd(ctx_firstDayOfMonth, 1, TimeUnit.Months),
-1,
TimeUnit.Days
)
});
// Refresh the data collection for the new month
Select(btnFetchCalMonthData)
9. Header Label (lblFormHeader_7) – Text
Displays the current month and year:
// Formats the date as "January 2026", "February 2026", etc.
Text(ctx_firstDayOfMonth, "mmmm yyyy")
How to Adapt This for Your Weekly View
For a 7-day weekly view instead of monthly, here are the key changes:
| Aspect |
My Monthly View |
Your Weekly View |
| Main Variable |
ctx_firstDayOfMonth |
Use ctx_weekStart |
| Grid Items |
[0..41] (42 cells) |
[0..6] (7 cells only) |
| Navigation |
DateAdd(..., ±1, Months) |
DateAdd(..., ±7, Days) |
| Header Text |
"mmmm yyyy" |
Text(ctx_weekStart, "dd mmm") & " – " & Text(DateAdd(ctx_weekStart, 6, Days), "dd mmm yyyy") |
| Data Filter Range |
First to last day of month |
ctx_weekStart to ctx_weekStart + 7 days |
Hope this helps explain the approach! The core concept is:
- Set a reference date (first day of month/week)
- Calculate view boundaries (first visible day, last day)
- Fetch filtered data into a collection
- Use gallery + nested gallery to display the grid and events
- Navigation buttons update the reference date and refresh data
If this helps resolve your issue, please consider marking the response as Verified so it can help others facing a similar scenario. If you found this helpful, you can also click "Yes" on "Was this reply helpful?" or give it a Like.