Column Filter Menu in Blazor Grid
- 6 minutes to read
The column filter menu displays a drop-down list of all unique values within a column and allows users to filter column data. A size grip in the corner of the filter menu allows users to change the menu’s width and height.
Use the following properties to display the filter menu buttons in the column headers:
- DxGrid.FilterMenuButtonDisplayMode
- Specifies when the Grid displays filter menu buttons in column headers.
- DxGridDataColumn.FilterMenuButtonDisplayMode
- Specifies when the column displays the filter menu button.
Note
The Grid cannot create filter item lists for columns associated with certain data types (for instance, arrays and images). If you do not implement a filter menu template for such a column, the column filter menu displays the following text instead of filter items: “No filters are available for this column”.
After you have applied a filter to a column, other filter menus display values that match the specified filter criteria. Hold down Shift and click a filter button to show all values.
Customize Filter Items
When a user clicks a filter menu button, the Grid creates a list of default filter items. The CustomizeFilterMenu event fires before the filter dropdown appears. Handle this event to customize the list (the DataItems property of the event argument).
Note that each filter menu item can only filter data by a single column value (cannot hold a complex filter condition). To implement complex criteria, create a filter menu template.
The code sample below shows how you can modify text in filter menu items. This example adds IDs to customer names.
<DxGrid Data="@customers"
FilterMenuButtonDisplayMode="GridFilterMenuButtonDisplayMode.Always"
CustomizeFilterMenu="OnCustomizeFilterMenu">
<Columns>
<DxGridDataColumn FieldName="ContactName" Width="180px" />
<DxGridDataColumn FieldName="Company" />
<DxGridDataColumn FieldName="Country" Width="140px" />
</Columns>
</DxGrid>
@code {
DateTime data { get; set; }
private Customer[]? customers;
protected override async Task OnInitializedAsync() {
customers = await CustomerData.GetData();
}
void OnCustomizeFilterMenu (GridCustomizeFilterMenuEventArgs e) {
if (e.DataColumn.FieldName == "ContactName") {
e.DataItems.ForEach(di => {
int? CustomerID = customers.Where(c =>
c.ContactName == di.Value.ToString()).FirstOrDefault()?.ID;
di.DisplayText = di.DisplayText + " (ID " + CustomerID + ")";
});
}
}
}
Custom Filter Menu Content (Template)
To apply a complex filter condition in a filter menu (for instance, a date range), create a filter menu template. You can create a template for an individual column (FilterMenuTemplate) of for all columns in the Grid (DataColumnFilterMenuTemplate).
The template’s context
parameter also contains the FilterCriteria property. Use this property to specify the filter criteria applied to the column and handle the FilterCriteriaChanged event to react to filter criteria changes.
<DxGrid Data="GridData"
FilterMenuButtonDisplayMode="GridFilterMenuButtonDisplayMode.Always"
SizeMode="Params.SizeMode">
<Columns>
<DxGridDataColumn FieldName="OrderDate" Width="140px">
<FilterMenuTemplate>
<Grid_Filtering_ColumnFilterMenu_DateRange FilterContext="context" />
</FilterMenuTemplate>
</DxGridDataColumn>
<DxGridDataColumn FieldName="ProductName" MinWidth="100" />
<DxGridDataColumn FieldName="CategoryId" Caption="Category" Width="130px">
<EditSettings>
<DxComboBoxSettings Data="Categories" ValueFieldName="CategoryId" TextFieldName="CategoryName" />
</EditSettings>
</DxGridDataColumn>
<DxGridDataColumn FieldName="UnitPrice" DisplayFormat="c2" Width="140px" />
<DxGridDataColumn FieldName="Quantity" Width="110px" />
<DxGridDataColumn FieldName="Discount" DisplayFormat="p0" Width="110px" />
<DxGridDataColumn FieldName="Total"
UnboundType="GridUnboundColumnType.Decimal"
UnboundExpression="[UnitPrice] * [Quantity] * (1 - [Discount])"
DisplayFormat="c2"
Width="110px">
<FilterMenuTemplate>
<Grid_Filtering_ColumnFilterMenu_CustomRange FilterContext="context" Items="TotalPriceIntervals" />
</FilterMenuTemplate>
</DxGridDataColumn>
<DxGridDataColumn FieldName="Shipped"
UnboundType="GridUnboundColumnType.Boolean"
UnboundExpression="[ShippedDate] <> Null"
Width="100px" />
</Columns>
</DxGrid>
@code {
static IReadOnlyList<CustomRangeFilterItem> TotalPriceIntervals { get; } = CreateTotalPriceIntervals();
object GridData { get; set; }
IReadOnlyList<Category> Categories { get; set; }
protected override async Task OnInitializedAsync() {
Categories = (await NwindDataService.GetCategoriesAsync()).ToList();
var invoices = await NwindDataService.GetInvoicesAsync();
var products = await NwindDataService.GetProductsAsync();
GridData = invoices.Join(products, i => i.ProductId, p => p.ProductId, (i, p) => {
return new {
ProductName = i.ProductName,
CategoryId = p.CategoryId,
OrderDate = i.OrderDate,
UnitPrice = i.UnitPrice,
Quantity = i.Quantity,
Discount = i.Discount,
ShippedDate = i.ShippedDate
};
});
}
static IReadOnlyList<CustomRangeFilterItem> CreateTotalPriceIntervals() {
var prop = new OperandProperty("Total");
var result = new List<CustomRangeFilterItem>();
var step = 100M;
for(var i = 0; i < 10; i++) {
var start = step * i;
var end = start + step;
result.Add(new() {
Criteria = prop >= start & prop < end,
DisplayText = $"from {start:c} to {end - 0.01M:c}"
});
}
result.Add(new() {
Criteria = prop > 1000,
DisplayText = $"> {1000:c}"
});
return result;
}
}
Limitation
Filter values for date columns are rounded to dates and do not take into account time values.