If the grid has Filterable=true, at the moment, all columns must have a Field defined. If a column does not have a Field, an exception similar to this one will be thrown:
Error: System.ArgumentNullException: Value cannot be null.
Parameter name: name
at System.Type.GetProperty(String name, BindingFlags bindingAttr)
at Telerik.Blazor.Components.Grid.TelerikGridFilterHeaderBase`1.get_PropInfo()
at Telerik.Blazor.Components.Grid.TelerikGridFilterHeaderBase`1.get_PropType()
at Telerik.Blazor.Components.Grid.TelerikGridFilterHeaderBase`1.get_PropTypeName()
at Telerik.Blazor.Components.Grid.TelerikGridFilterHeaderBase`1.ResetFilterText()
at Telerik.Blazor.Components.Grid.TelerikGridFilterHeaderBase`1.OnInit()
at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
Instead, when no Field is provided, filtering, sorting and other operations that require a model field must be disabled internally without an exception.
For the time being, a workaround is to set Filterable=false to the desired column.
Here is an example where the workaround is highlighted
@
using
Telerik.Blazor.Components.Grid
@
using
Telerik.Blazor.Components.Button
<TelerikGrid data=
"@Histories"
height=
"600px"
Pageable=
"true"
PageSize=
"20"
Sortable=
"true"
Filterable=
"true"
>
<TelerikGridColumns>
<TelerikGridColumn Field=
"Casecode"
/>
<TelerikGridColumn Field=
"Historytext"
/>
<TelerikGridColumn Field=
"Createdate"
Title=
"Create Date"
/>
<TelerikGridColumn Filterable=
"false"
>
<Template>
@{
var CurrentRecord = context
as
CaseHistory;
if
(CurrentRecord.Blobid > 0)
{
<TelerikButton OnClick=
"@(() => MyCustomCommand(CurrentRecord))"
>Open</TelerikButton>
}
}
</Template>
</TelerikGridColumn>
</TelerikGridColumns>
</TelerikGrid>
@result
@functions {
public
class
CaseHistory
{
public
int
Id {
get
;
set
; }
public
int
Casecode {
get
;
set
; }
public
string
Historytext {
get
;
set
; }
public
DateTime Createdate {
get
;
set
; }
public
int
Blobid {
get
;
set
; }
}
IEnumerable<CaseHistory> Histories = Enumerable.Range(1, 50).Select(x =>
new
CaseHistory
{
Id = x,
Casecode = x,
Historytext =
"text "
+ x,
Createdate = DateTime.Now.AddDays(-x),
Blobid = (x % 3 == 0) ? x : -x
});
string
result {
get
;
set
; }
void
MyCustomCommand(CaseHistory itm)
{
result = $
"custom command fired for {itm.Id} on {DateTime.Now}"
;
StateHasChanged();
}
}
If you create a second Grid on the page, it will clear the SearchBox input value of the first Grid.
<p><TelerikButton OnClick="@ToggleSecondGrid">Toggle Second Grid</TelerikButton></p>
<TelerikGrid Data="@GridData">
<GridToolBar>
<GridSearchBox />
</GridToolBar>
<GridColumns>
<GridColumn Field=@nameof(Product.ProductName) Title="Product Name" />
</GridColumns>
</TelerikGrid>
@if (ShowSecondGrid)
{
<TelerikGrid Data="@( new List<Product>() )">
<GridColumns>
<GridColumn />
</GridColumns>
</TelerikGrid>
}
@code {
List<Product> GridData { get; set; }
bool ShowSecondGrid { get; set; }
async Task ToggleSecondGrid()
{
ShowSecondGrid = !ShowSecondGrid;
}
protected override void OnInitialized()
{
GridData = new List<Product>();
for (int i = 1; i <= 5; i++)
{
GridData.Add(new Product()
{
ProductId = i,
ProductName = "Product " + i.ToString(),
UnitPrice = (decimal)(i * 3.14),
UnitsInStock = (short)(i * 1),
Discontinued = false
});
}
}
public class Product
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public decimal? UnitPrice { get; set; }
public short? UnitsInStock { get; set; }
public bool Discontinued { get; set; }
}
}
My grid starts with Groupable=false and at some point I may need to make it groupable. The group panel appears, but I cannot drag the column headers to it to actually group.
---
ADMIN EDIT
A workaround is to hide the grid so it can re-initialize with the new groupable setting:
Is Groupable: @IsGroupable
<TelerikButton OnClick="@ToggleGroupable">Toggle Groupable</TelerikButton>
@if (isGridVisible)
{
<TelerikGrid Data=@GridData @ref="@GridRef" Groupable="@IsGroupable" Pageable="true" Height="400px">
<GridColumns>
<GridColumn Field=@nameof(Employee.Name) Groupable="false" />
<GridColumn Field=@nameof(Employee.Team) Title="Team" />
<GridColumn Field=@nameof(Employee.IsOnLeave) Title="On Vacation" />
</GridColumns>
</TelerikGrid>
}
@code {
bool IsGroupable { get; set; }
bool isGridVisible { get; set; } = true;
TelerikGrid<Employee> GridRef { get; set; }
async Task ToggleGroupable()
{
//save state (sorting, paging,...) - it will be lost when we hide the grid
var state = GridRef.GetState();
//hide the grid so it can later re-initialize with the new groupable setting
isGridVisible = false;
await InvokeAsync(StateHasChanged);
await Task.Delay(20);
IsGroupable = !IsGroupable;
isGridVisible = true;
//afte the grid re-initialized and rendered with the new setting, restore its state
await InvokeAsync(StateHasChanged);
await Task.Delay(20);
await GridRef.SetState(state);
}
public List<Employee> GridData { get; set; }
protected override void OnInitialized()
{
GridData = new List<Employee>();
var rand = new Random();
for (int i = 0; i < 15; i++)
{
GridData.Add(new Employee()
{
EmployeeId = i,
Name = "Employee " + i.ToString(),
Team = "Team " + i % 3,
IsOnLeave = i % 2 == 0
});
}
}
public class Employee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
public string Team { get; set; }
public bool IsOnLeave { get; set; }
}
}
---
I would like to set increase the searchbox width with a parameter.
---
ADMIN EDIT
Here is a CSS workaround:
<style>
.custom-searchbox-width .k-grid-search {
width: 50%;
}
</style>
<TelerikGrid Data=@GridData Pageable="true" Height="400px" Class="custom-searchbox-width">
<GridToolBar>
<span class="k-toolbar-spacer"></span> @* add this spacer to keep the searchbox on the right *@
<GridSearchBox />
</GridToolBar>
<GridColumns>
<GridColumn Field="@(nameof(Employee.EmployeeId))" />
<GridColumn Field=@nameof(Employee.Name) />
<GridColumn Field=@nameof(Employee.Team) Title="Team" />
<GridColumn Field=@nameof(Employee.IsOnLeave) Title="On Vacation" />
</GridColumns>
</TelerikGrid>
@code {
public List<Employee> GridData { get; set; }
protected override void OnInitialized()
{
GridData = new List<Employee>();
var rand = new Random();
for (int i = 0; i < 15; i++)
{
GridData.Add(new Employee()
{
EmployeeId = i,
Name = "Employee " + i.ToString(),
Team = "Team " + i % 3,
IsOnLeave = i % 2 == 0
});
}
}
public class Employee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
public string Team { get; set; }
public bool IsOnLeave { get; set; }
}
}
---
I want to place the Pager on top of the Grid. I know it can be handled with a Pager component integration in the Grid Toolbar, but I want to use the Toolbar for other purposes/actions. Please allow control over the Pager position.
I noticed Telerik Blazor grid is rendered into two tables. One for the headers and one for the contents.
My assumption is that Allyable Scan expects to find a th element inside the second table and it did not find any. Is my assumption correct?
Element source:
<table role="grid" style="width: ;">
Here's the reproducible:
@using System.ComponentModel.DataAnnotations
@* Used for the model annotations only *@
<strong>REPRO: activate the validation for the Name field to see the issue - click Save with an empty input</strong>
<TelerikGrid Data=@MyData EditMode="@GridEditMode.Popup" Pageable="true" Height="500px"
OnUpdate="@UpdateHandler" OnDelete="@DeleteHandler" OnCreate="@CreateHandler">
<GridToolBar>
<GridCommandButton Command="Add" Icon="add">Add Employee</GridCommandButton>
</GridToolBar>
<GridColumns>
<GridColumn Field=@nameof(SampleData.ID) Title="ID" Editable="false" />
<GridColumn Field=@nameof(SampleData.Name) Title="Name" />
<GridCommandColumn>
<GridCommandButton Command="Save" Icon="save" ShowInEdit="true">Update</GridCommandButton>
<GridCommandButton Command="Edit" Icon="edit">Edit</GridCommandButton>
<GridCommandButton Command="Delete" Icon="delete">Delete</GridCommandButton>
<GridCommandButton Command="Cancel" Icon="cancel" ShowInEdit="true">Cancel</GridCommandButton>
</GridCommandColumn>
</GridColumns>
</TelerikGrid>
@code {
public class SampleData
{
public int ID { get; set; }
[Required(ErrorMessage = "aa something else")] // the first word is 1 or 2 characters to show the issue
public string Name { get; set; }
}
async Task UpdateHandler(GridCommandEventArgs args)
{
SampleData item = (SampleData)args.Item;
// perform actual data source operations here through your service
// if the grid Data is not tied to the service, you may need to update the local view data too
var index = MyData.FindIndex(i => i.ID == item.ID);
if (index != -1)
{
MyData[index] = item;
}
}
async Task DeleteHandler(GridCommandEventArgs args)
{
SampleData item = (SampleData)args.Item;
// perform actual data source operation here through your service
// if the grid Data is not tied to the service, you may need to update the local view data too
MyData.Remove(item);
}
async Task CreateHandler(GridCommandEventArgs args)
{
SampleData item = (SampleData)args.Item;
// perform actual data source operation here through your service
// if the grid Data is not tied to the service, you may need to update the local view data too
item.ID = MyData.Count + 1;
MyData.Insert(0, item);
}
public List<SampleData> MyData { get; set; }
protected override void OnInitialized()
{
MyData = new List<SampleData>();
for (int i = 0; i < 50; i++)
{
MyData.Add(new SampleData()
{
ID = i,
Name = "Name " + i.ToString()
});
}
}
}
When you zoom out, the span that displays the Grid pager's content has its style set to display: none, and it does not always reappear when you zoom in after that.
Reproduction
1. Run this REPL