TreeList Toolbar Searchbox
In addition to the main filtering options, you can add a SearchBox in the TreeList Toolbar.
In this article:
Basics
The SearchBox lets the user type their query and the TreeList will look up all visible string columns with a case-insensitive Contains
operator, and filter them accordingly. You can change the filter delay, and the fields the TreeList will use - see the Customize the SearchBox section below.
The SearchBox is independent from the standard filters. If you have filters applied, the SearchBox will respect them and add additional filtering criteria. Thus, you can also apply filtering to results returned from it.
To enable the SearchBox, add the <TreeListSearchBox>
tag in the <TreeListToolBarTemplate>
.
SearchBox in the Telerik TreeList
@* A search panel in the TreeList Toolbar *@
<TelerikTreeList Data="@Data"
ItemsField="@(nameof(Employee.DirectReports))"
Pageable="true">
<TreeListToolBarTemplate>
<span class="k-toolbar-spacer"></span> @* add this spacer to keep the searchbox on the right *@
<TreeListSearchBox />
</TreeListToolBarTemplate>
<TreeListColumns>
<TreeListColumn Field="Name" Expandable="true" Width="320px" />
<TreeListColumn Field="Id" Editable="false" Width="120px" />
<TreeListColumn Field="EmailAddress" Width="220px" />
</TreeListColumns>
</TelerikTreeList>
@code {
public List<Employee> Data { get; set; }
// sample model
public class Employee
{
// hierarchical data collections
public List<Employee> DirectReports { get; set; }
// data fields for display
public int Id { get; set; }
public string Name { get; set; }
public string EmailAddress { get; set; }
}
// data generation
// used in this example for data generation and retrieval for CUD operations on the current view-model data
public int LastId { get; set; } = 1;
protected override async Task OnInitializedAsync()
{
Data = await GetTreeListData();
}
async Task<List<Employee>> GetTreeListData()
{
List<Employee> data = new List<Employee>();
for (int i = 1; i < 15; i++)
{
Employee root = new Employee
{
Id = LastId,
Name = $"root: {i}",
EmailAddress = $"{i}@example.com",
DirectReports = new List<Employee>(),
};
data.Add(root);
LastId++;
for (int j = 1; j < 4; j++)
{
int currId = LastId;
Employee firstLevelChild = new Employee
{
Id = currId,
Name = $"first level child {j} of {i}",
EmailAddress = $"{currId}@example.com",
DirectReports = new List<Employee>(),
};
root.DirectReports.Add(firstLevelChild);
LastId++;
for (int k = 1; k < 3; k++)
{
int nestedId = LastId;
firstLevelChild.DirectReports.Add(new Employee
{
Id = LastId,
Name = $"second level child {k} of {j} and {i}",
EmailAddress = $"{nestedId}@example.com",
}); ;
LastId++;
}
}
}
return await Task.FromResult(data);
}
}
The result from the code snippet above
Filter From Code
You can set the TreeList filters programmatically through the component state.
If you want to set an initial state to the TreeList, use a similar snippet, but in the
OnStateInit event
The result from the code snippet below.
Set programmatically Searchbox Filter.
@* This snippet shows how to set filtering state to the TreeList from your code
Applies to the SearchBox filter *@
@using Telerik.DataSource;
<TelerikButton OnClick="@SetTreeListFilter" ThemeColor="primary">Set filtered state</TelerikButton>
<TelerikTreeList Data="@Data"
ItemsField="@(nameof(Employee.DirectReports))"
Height="400px"
Pageable="true"
Width="850px"
@ref="TreeListRef">
<TreeListToolBarTemplate>
<TreeListSearchBox />
</TreeListToolBarTemplate>
<TreeListColumns>
<TreeListColumn Field="Name" Expandable="true" Width="320px" />
<TreeListColumn Field="Id" Width="120px" />
<TreeListColumn Field="Address" Title="Email Address" Width="220px" />
<TreeListColumn Field="HireDate" Width="220px" />
</TreeListColumns>
</TelerikTreeList>
@code {
public TelerikTreeList<Employee> TreeListRef { get; set; } = new TelerikTreeList<Employee>();
async Task SetTreeListFilter()
{
var filteredState = new TreeListState<Employee>()
{
SearchFilter = CreateSearchFilter()
};
await TreeListRef.SetStateAsync(filteredState);
}
private IFilterDescriptor CreateSearchFilter()
{
var descriptor = new CompositeFilterDescriptor();
var fields = new List<string>() { "Name", "Address" };
var searchValue = "root: 1";
descriptor.LogicalOperator = FilterCompositionLogicalOperator.Or;
foreach (var field in fields)
{
var filter = new FilterDescriptor(field, FilterOperator.Contains, searchValue);
filter.MemberType = typeof(string);
descriptor.FilterDescriptors.Add(filter);
}
return descriptor;
}
public List<Employee> Data { get; set; }
public class Employee
{
public List<Employee> DirectReports { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public DateTime HireDate { get; set; }
}
public int LastId { get; set; } = 1;
protected override async Task OnInitializedAsync()
{
Data = await GetTreeListData();
}
async Task<List<Employee>> GetTreeListData()
{
List<Employee> data = new List<Employee>();
for (int i = 1; i < 15; i++)
{
Employee root = new Employee
{
Id = LastId,
Name = $"root: {i}",
Address = $"{i}@example.com",
HireDate = DateTime.Now.AddYears(-i),
DirectReports = new List<Employee>(),
};
data.Add(root);
LastId++;
for (int j = 1; j < 4; j++)
{
int currId = LastId;
Employee firstLevelChild = new Employee
{
Id = currId,
Name = $"first level child {j} of {i}",
Address = $"{currId}@example.com",
HireDate = DateTime.Now.AddDays(-currId),
DirectReports = new List<Employee>(),
};
root.DirectReports.Add(firstLevelChild);
LastId++;
for (int k = 1; k < 3; k++)
{
int nestedId = LastId;
firstLevelChild.DirectReports.Add(new Employee
{
Id = LastId,
Name = $"second level child {k} of {j} and {i}",
Address = $"{nestedId}@example.com",
HireDate = DateTime.Now.AddMinutes(-nestedId)
}); ;
LastId++;
}
}
}
return await Task.FromResult(data);
}
}
Customize the SearchBox
The TreeListSearchBox
component offers the following settings to customize its behavior:
Attribute | Type and Default Value | Description |
---|---|---|
Class |
string |
a CSS class rendered on the wrapper of the searchbox so you can customize its appearance. |
DebounceDelay |
int (300) |
the time in milliseconds with which searching is debounced. Filtering does not happen on every keystroke and that can reduce the flicker for the end user. |
Fields |
List<string> |
The collection of fields to search in. By default, the component looks in all string fields in its currently visible columns, and you can define a subset of that. |
Placeholder |
string ( Search... (localized)) |
Specifies the placeholder attribute of the SearchBox component. |
Width |
string |
Specifies the width of the SearchBox component. |
Customize the SearchBox to have a long filter delay, search in certain fields only and use a custom placeholder
@* Increased delay, a subset of the columns are allowed for filtering and a custom placeholder *@
<TelerikTreeList Data="@Data"
ItemsField="@(nameof(Employee.DirectReports))"
Pageable="true">
<TreeListToolBarTemplate>
<TreeListSearchBox DebounceDelay="1000"
Fields="@SearchableFields"
Placeholder="Search Name..." />
</TreeListToolBarTemplate>
<TreeListColumns>
<TreeListColumn Field="Name" Expandable="true" Width="320px" />
<TreeListColumn Field="Id" Editable="false" Width="120px" />
<TreeListColumn Field="EmailAddress" />
</TreeListColumns>
</TelerikTreeList>
@code {
List<string> SearchableFields = new List<string> { "Name" };
List<Employee> Data { get; set; }
// sample model
public class Employee
{
// hierarchical data collections
public List<Employee> DirectReports { get; set; }
// data fields for display
public int Id { get; set; }
public string Name { get; set; }
public string EmailAddress { get; set; }
}
// data generation
// used in this example for data generation and retrieval for CUD operations on the current view-model data
public int LastId { get; set; } = 1;
protected override async Task OnInitializedAsync()
{
Data = await GetTreeListData();
}
async Task<List<Employee>> GetTreeListData()
{
List<Employee> data = new List<Employee>();
for (int i = 1; i < 15; i++)
{
Employee root = new Employee
{
Id = LastId,
Name = $"root: {i}",
EmailAddress = $"{i}@example.com",
DirectReports = new List<Employee>(),
};
data.Add(root);
LastId++;
for (int j = 1; j < 4; j++)
{
int currId = LastId;
Employee firstLevelChild = new Employee
{
Id = currId,
Name = $"first level child {j} of {i}",
EmailAddress = $"{currId}@example.com",
DirectReports = new List<Employee>(),
};
root.DirectReports.Add(firstLevelChild);
LastId++;
for (int k = 1; k < 3; k++)
{
int nestedId = LastId;
firstLevelChild.DirectReports.Add(new Employee
{
Id = LastId,
Name = $"second level child {k} of {j} and {i}",
EmailAddress = $"{nestedId}@example.com",
}); ;
LastId++;
}
}
}
return await Task.FromResult(data);
}
}