Tutorials/Power Apps/Implementing a Robust Filter Sidebar in Power Apps
Power Appsintermediate

Implementing a Robust Filter Sidebar in Power Apps

Explore a state-management pattern for canvas app filters that gives users the ability to stage, apply, or discard their changes without disrupting the main data view.

NA
Narmer Abader
@narmer · Published June 3, 2026

A polished filter panel can make or break an enterprise canvas app. The easiest approach is to bind a gallery directly to dropdown changes, but this causes the data view to flicker and change while the user is still configuring their search. A better pattern separates the act of configuring filters from the act of applying them. Let’s build a right-side panel that uses two state variables to give users a safe environment to explore filter settings and commit only when they are ready.

Our Scenario: The Expense Auditor

Imagine you are building an app for a department that processes expense reports. Your data source (a SharePoint list named ExpenseReports) contains these columns:

  • Category (Choice: Travel, Meals, Software, Equipment)
  • Status (Choice: Submitted, Under Review, Approved, Rejected)
  • Reviewer (Person or Group)

The main screen contains a Gallery that displays these expenses. We want a filter icon in the header that opens a sidebar panel where users can pick values for these three fields.

The Core Pattern: Draft vs. Applied State

The trick to a smooth user experience is two global variables:

  • var_AppliedFilters – A record containing the exact filter values the gallery is currently using.
  • var_DraftFilters – A record containing the filter values the user is actively editing in the panel.

When the panel opens, both are set to the current gallery selections. While the panel is open, changing a dropdown only updates var_DraftFilters. The gallery remains frozen. When the user hits Apply, var_DraftFilters is copied to var_AppliedFilters (updating the gallery). When they hit Cancel, var_DraftFilters is replaced by var_AppliedFilters and the dropdown controls are reset.

Step 1: Opening the Panel and Initializing State

Place a Filter icon in your app header. Its OnSelect takes a snapshot of the current gallery filter state and shows the sidebar.

powerfxFilter icon OnSelect
// Snapshot of the current gallery filter values
Set(var_AppliedFilters, {
  Category: Dropdown_Category.Selected,
  Status: Dropdown_Status.Selected,
  Reviewer: Dropdown_Reviewer.Selected
});

// Copy the snapshot to the draft variable
Set(var_DraftFilters, var_AppliedFilters);

// Show the sidebar panel and overlay
Set(varShowPanel, true);

Set the Visible property of your sidebar container and the screen overlay to varShowPanel. Set the Visible property of the Filter icon to !varShowPanel.

Step 2: A Screen Overlay That Blocks Clicks

While the panel is open, the user should not be able to interact with the main gallery or header. Add a transparent overlay label (or rectangle) that covers the entire screen outside the panel.

Set its Fill property to a semi-transparent color:

powerfxOverlay label Fill property
RGBA(0, 0, 0, 0.25)

An overlay also gives users a visual clue that they must dismiss the panel before interacting with the rest of the app.

Step 3: Wiring the Dropdown Controls

Each dropdown inside the panel needs its DefaultSelectedItems bound to the draft variable. As the user changes a selection, the OnChange event updates var_DraftFilters.

DefaultSelectedItems for the Category dropdown:

powerfxDefaultSelectedItems of Dropdown_Category
var_DraftFilters.Category

OnChange for every filter dropdown (this keeps the draft record in sync):

powerfxDropdown OnChange (all three)
Set(var_DraftFilters, {
  Category: Dropdown_Category.Selected,
  Status: Dropdown_Status.Selected,
  Reviewer: Dropdown_Reviewer.Selected
});

This may seem redundant since the dropdown already shows the selected value, but it ensures the var_DraftFilters record is always accurate even if a user rapidly changes selections or if you later add preview logic.

Step 4: Apply, Clear, and Cancel

The three action buttons in the panel are the heart of the user experience.

Apply button OnSelect – Commit the draft filters to the gallery and close the panel.

powerfxApply button OnSelect
Set(var_AppliedFilters, {
  Category: Dropdown_Category.Selected,
  Status: Dropdown_Status.Selected,
  Reviewer: Dropdown_Reviewer.Selected
});

Set(var_DraftFilters, var_AppliedFilters);
Set(varShowPanel, false);

Clear button OnSelect – Reset the draft filters to blank and reset the dropdown controls. The gallery stays unchanged until the user clicks Apply.

powerfxClear button OnSelect
Set(var_DraftFilters, {
  Category: Blank(),
  Status: Blank(),
  Reviewer: Blank()
});

Reset(Dropdown_Category);
Reset(Dropdown_Status);
Reset(Dropdown_Reviewer);

Cancel (X) button OnSelect – Discard the draft changes, restore the dropdowns to the last applied state, and close the panel.

powerfxCancel icon OnSelect
Set(var_DraftFilters, {
  Category: var_AppliedFilters.Category,
  Status: var_AppliedFilters.Status,
  Reviewer: var_AppliedFilters.Reviewer
});

Reset(Dropdown_Category);
Reset(Dropdown_Status);
Reset(Dropdown_Reviewer);

Set(varShowPanel, false);

Notice that Cancel does not change var_AppliedFilters. The gallery keeps showing the previous data until the user explicitly commits new filters.

The gallery’s Items property reads from var_AppliedFilters.

powerfxGallery Items property
Where(
  ExpenseReports,
  (IsBlank(var_AppliedFilters.Category) ||
   Category.Value = var_AppliedFilters.Category.Value) &&
  (IsBlank(var_AppliedFilters.Status) ||
   Status.Value = var_AppliedFilters.Status.Value) &&
  (IsBlank(var_AppliedFilters.Reviewer) ||
   Reviewer.DisplayName = var_AppliedFilters.Reviewer.DisplayName)
)
Delegation Warning

The Where() function does not delegate to the data source. It pulls matching records into memory before applying the filter logic. This works well for lists under 2,000 items. If your data source is significantly larger, use Filter() with delegate-friendly operators (such as in on text fields) or consider collecting a limited data set into a local collection on app start.

Common Mistakes and Troubleshooting

Resetting does not clear the dropdown. This happens when DefaultSelectedItems is not bound to the variable that gets updated during the reset. Ensure each dropdown’s DefaultSelectedItems property points to the var_DraftFilters field (e.g., var_DraftFilters.Category).

The Cancel button restores the wrong values. Double-check that Cancel reads from var_AppliedFilters and not from the dropdowns themselves. Reading from the dropdowns would just re-capture the draft state.

The gallery flickers when the panel opens. This indicates your Filter icon is modifying var_AppliedFilters on open. The var_AppliedFilters variable should only change when the Apply button is pressed. Keep your initialization logic in the Filter icon limited to setting var_DraftFilters and the visibility flag.

Person columns behave unexpectedly. A Person or Group field returns a record with multiple properties. When comparing in a filter, using .DisplayName is generally the most reliable approach for simple string matching.

Recommendation

The draft / applied variable pattern is lightweight, reusable across multiple screens, and gives your app a trustworthy, enterprise-grade feel. Once you have it working for a single panel, you can easily extend it to support multiple filter sections (date ranges, text search, multi-select) without changing the core logic.

Users will instinctively understand the workflow: open the panel, explore your options, apply when you are ready, or cancel to back out. It mirrors the behavior users expect from mature web applications.


References