Filter the Grid by selected items
Environment
Product | Grid for Blazor, TreeList for Blazor |
Description
How can I achieve the following with the Blazor Grid:
- How to filter the Grid, so that it shows only the selected items on different pages.
- If specific items are selected, I want to sort only the selected items.
Solution
To simulate filtering by the selected items:
Get the
SelectedItems
data and assign it as Grid data. Thus, the Grid will show only the selected items. This will allow the user to perform the desired data operations only to the selected items.To clear this "filter" and show all items (not only the selected ones), assign the actual data source to the Grid.
Consider and choose the desired UI for triggering that custom filtering, for example, a filter button or menu. Use the needed template to declare the custom filter UI in the Grid. Useful options can be the Toolbar or the Checkbox Column Header(in case you are using CheckBox selection).
Override the
Equals
method so that the selection is preserved during filtering.
The data assignment will vary depending on the data binding type you are using for the Grid. See examples below:
Data binding through the Data parameter
Assign the SelectedItems
to the Data
parameter of the Grid. Refresh the Grid each time you change its data so the changes are visible in the viewport.
@*Select several items on different pages and then click the filter button in the Checkbox Column Header*@
<TelerikGrid Data=@GridData
SelectionMode="@GridSelectionMode.Multiple"
@bind-SelectedItems="@SelectedEmployees"
FilterMode="@GridFilterMode.FilterMenu"
Sortable="true"
Pageable="true">
<GridColumns>
<GridCheckboxColumn Width="90px">
<HeaderTemplate>
<TelerikButton OnClick="@FilterSelected" Icon="SvgIcon.Filter" ThemeColor="@(selectedOnly? "primary" : "base")"></TelerikButton>
<TelerikButton OnClick="@ClearFilter" Icon="SvgIcon.FilterClear" Enabled="@selectedOnly"></TelerikButton>
</HeaderTemplate>
</GridCheckboxColumn>
<GridColumn Field=@nameof(Employee.Name) />
<GridColumn Field=@nameof(Employee.Team) Title="Team" />
</GridColumns>
</TelerikGrid>
@if (SelectedEmployees != null)
{
<ul>
@foreach (Employee employee in SelectedEmployees)
{
<li>
@employee.Name
</li>
}
</ul>
}
@code {
private List<Employee> GridData { get; set; }
private IEnumerable<Employee> SelectedEmployees { get; set; } = new List<Employee>();
private bool selectedOnly { get; set; }
private void FilterSelected()
{
GridData = new List<Employee>(SelectedEmployees);
selectedOnly = true;
}
private void ClearFilter()
{
GridData = GetData();
selectedOnly = false;
}
protected override async Task OnInitializedAsync()
{
GridData = GetData();
}
private List<Employee> GetData()
{
var data = new List<Employee>();
for (int i = 0; i < 30; i++)
{
data.Add(new Employee()
{
EmployeeId = i,
Name = "Employee " + i.ToString(),
Team = "Team " + i % 3
});
};
return data;
}
public class Employee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
public string Team { get; set; }
public override bool Equals(object obj)
{
if (obj is Employee)
{
return this.EmployeeId == (obj as Employee).EmployeeId;
}
return false;
}
}
}
Data binding through the OnRead event
Bind the Grid through the OnRead
event.
Toggle a flag when the user initiates the filtering. Then call the Rebind
method - this will force the Grid to fire its OnRead
event.
Depending on the flag value, you can make the request based on the corresponding data source - the SelectedItems
collection or the actual data source.
@*Select several items on different pages and then click the filter button in the Checkbox Column Header*@
@using Telerik.DataSource.Extensions
<TelerikGrid @ref="@GridRef"
TItem="@Employee"
OnRead="@ReadItems"
SelectionMode="@GridSelectionMode.Multiple"
@bind-SelectedItems="@SelectedEmployees"
FilterMode="@GridFilterMode.FilterRow"
Sortable="true"
Pageable="true">
<GridColumns>
<GridCheckboxColumn Width="90px">
<HeaderTemplate>
<TelerikButton OnClick="@FilterSelected" Icon="SvgIcon.Filter" ThemeColor="@(selectedOnly? "primary" : "base")"></TelerikButton>
<TelerikButton OnClick="@ClearFilter" Icon="SvgIcon.FilterClear" Enabled="@selectedOnly"></TelerikButton>
</HeaderTemplate>
</GridCheckboxColumn>
<GridColumn Field=@nameof(Employee.Name) />
<GridColumn Field=@nameof(Employee.Team) Title="Team" />
</GridColumns>
</TelerikGrid>
@if (SelectedEmployees != null)
{
<ul>
@foreach (Employee employee in SelectedEmployees)
{
<li>
@employee.Name
</li>
}
</ul>
}
@code {
private TelerikGrid<Employee> GridRef { get; set; }
private IEnumerable<Employee> SelectedEmployees { get; set; } = new List<Employee>();
public List<Employee> SourceData { get; set; }
private bool selectedOnly { get; set; }
private void FilterSelected()
{
selectedOnly = true;
GridRef?.Rebind();
}
private void ClearFilter()
{
selectedOnly = false;
GridRef?.Rebind();
}
protected async Task ReadItems(GridReadEventArgs args)
{
await Task.Delay(1000); //simulate network delay from a real async call
var datasourceResult = new Telerik.DataSource.DataSourceResult();
if (selectedOnly)
{
datasourceResult = SelectedEmployees.ToDataSourceResult(args.Request);
}
else
{
datasourceResult = SourceData.ToDataSourceResult(args.Request);
}
args.Data = datasourceResult.Data;
args.Total = datasourceResult.Total;
}
protected override void OnInitialized()
{
SourceData = GenerateData();
}
private List<Employee> GenerateData()
{
var data = new List<Employee>();
for (int i = 0; i < 30; i++)
{
data.Add(new Employee()
{
EmployeeId = i,
Name = "Employee " + i.ToString(),
Team = "Team " + i % 3
});
};
return data;
}
public class Employee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
public string Team { get; set; }
public override bool Equals(object obj)
{
if (obj is Employee)
{
return this.EmployeeId == (obj as Employee).EmployeeId;
}
return false;
}
}
}