Scenario #1
I want my users to confirm the update of a cell value with the built-in Confirmation Dialog for Blazor. If I use the keyboard (Enter, Tab) to close the edit the Confirmation dialog will popup, but after closing it the Grid hangs.
Scenario #2
If I edit a cell and press enter very quickly, the grid is not able to get the new value inserted after confirming it through the dialog.
Scenario #3
If you press Enter very quickly to confirm the value for deletion, the value is not always removed.
I need to lock the "expand" column in the Grid(Locked=true).
When I scroll horizontally, the first column with the expand/collapse icon scrolls out of view. I would like a way to lock it.
Selection performance suffers if the Grid has a large page size and uses child components in column templates:
https://blazorrepl.telerik.com/QHaLcVbl25YrVZU821
This is because the Grid doesn't apply performance optimizations for templates and always re-renders them.
Please expose a setting to disable re-rendering if it's not necessary.
Hello,
Hi
The reset button is not working when we use the column template with the Telerik grid. How to solve this problem? Can you please send it example for reference?
Example Link :
Working Without Column Template
=>https://demos.telerik.com/blazor-ui/grid/column-menu
Not Working With Column Template
=>https://demos.telerik.com/blazor-ui/grid/custom-column-menu
Thanks
I want to add a custom sort comparer but I don't want to perform the whole sorting manually through the OnRead event.
Please allow adding custom expressions that will be applied to the query that the DataSource package does for easier customizations of the data operations.
Consider this test page: https://blazorrepl.telerik.com/cSEQOTQY53LRL4je36
This happens only when using a column menu - ShowColumnMenu="true".
===
A possible workaround is to use a FilterButtonsTemplate and clear the filters programmatically if the filter descriptor is empty:
@using Telerik.DataSource
@using Telerik.DataSource.Extensions
<TelerikGrid TItem="@Employee"
OnRead="@OnReadHandler"
Pageable="true"
FilterMode="@GridFilterMode.FilterMenu"
FilterMenuType="@FilterMenuType.CheckBoxList"
ShowColumnMenu="true"
Height="400px">
<GridColumns>
<GridColumn Field="@(nameof(Employee.EmployeeId))" Filterable="false" />
<GridColumn Field="@nameof(Employee.Name)">
<FilterMenuTemplate Context="context">
<TelerikCheckBoxListFilter Data="@NameOptions"
Field="@(nameof(NameFilterOption.Name))"
@bind-FilterDescriptor="@context.FilterDescriptor">
</TelerikCheckBoxListFilter>
</FilterMenuTemplate>
<FilterMenuButtonsTemplate Context="filterContext">
<TelerikButton OnClick="@( async () => await ApplyFilterAsync(filterContext) )"
ThemeColor="primary">Filter</TelerikButton>
<TelerikButton OnClick="@( async () => await ClearFilterAsync(filterContext) )">Clear</TelerikButton>
</FilterMenuButtonsTemplate>
</GridColumn>
<GridColumn Field="@nameof(Employee.Team)" Title="Team">
<FilterMenuTemplate Context="context">
<TelerikCheckBoxListFilter Data="@TeamsList"
Field="@(nameof(TeamNameFilterOption.Team))"
@bind-FilterDescriptor="@context.FilterDescriptor">
</TelerikCheckBoxListFilter>
</FilterMenuTemplate>
</GridColumn>
<GridColumn Field="@nameof(Employee.IsOnLeave)" Title="On Vacation" />
</GridColumns>
</TelerikGrid>
@code {
List<Employee> AllGridData { get; set; }
#region custom-filter-data
List<TeamNameFilterOption> TeamsList { get; set; }
List<NameFilterOption> NameOptions { get; set; }
private async Task ApplyFilterAsync(FilterMenuTemplateContext filterContext)
{
var hasFilters = filterContext.FilterDescriptor.FilterDescriptors.OfType<FilterDescriptor>().Any(x => !string.IsNullOrEmpty(x.Value.ToString()));
if (hasFilters)
{
await filterContext.FilterAsync();
}
else
{
await filterContext.ClearFilterAsync();
}
}
private async Task ClearFilterAsync(FilterMenuTemplateContext filterContext)
{
await filterContext.ClearFilterAsync();
}
//obtain filter lists data from the data source to show all options
async Task GetTeamOptions()
{
if (TeamsList == null) // sample of caching since we always want all distinct options,
//but we don't want to make unnecessary requests
{
TeamsList = await GetNamesFromService();
}
}
async Task<List<TeamNameFilterOption>> GetNamesFromService()
{
await Task.Delay(500);// simulate a real service delay
// this is just one example of getting distinct values from the full data source
// in a real case you'd probably call your data service here instead
// or apply further logic (such as tie the returned data to the data the grid will have according to your business logic)
List<TeamNameFilterOption> data = AllGridData.OrderBy(z => z.Team).Select(z => z.Team).
Distinct().Select(t => new TeamNameFilterOption { Team = t }).ToList();
return await Task.FromResult(data);
}
async Task GetNameOptions()
{
if (NameOptions == null)
{
NameOptions = await GetNameOptionsFromService();
}
}
async Task<List<NameFilterOption>> GetNameOptionsFromService()
{
await Task.Delay(500);// simulate a real service delay
List<NameFilterOption> data = AllGridData.OrderBy(z => z.Name).Select(z => z.Name).
Distinct().Select(n => new NameFilterOption { Name = n }).ToList();
return await Task.FromResult(data);
}
#endregion custom-filter-data
async Task OnReadHandler(GridReadEventArgs args)
{
//typical data retrieval for the grid
var filteredData = await AllGridData.ToDataSourceResultAsync(args.Request);
args.Data = filteredData.Data as IEnumerable<Employee>;
args.Total = filteredData.Total;
}
protected override async Task OnInitializedAsync()
{
AllGridData = new List<Employee>();
var rand = new Random();
for (int i = 1; i <= 15; i++)
{
AllGridData.Add(new Employee()
{
EmployeeId = i,
Name = "Employee " + i.ToString(),
Team = "Team " + i % 3,
IsOnLeave = i % 2 == 0
});
}
await GetTeamOptions();
await GetNameOptions();
}
public class Employee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
public string Team { get; set; }
public bool IsOnLeave { get; set; }
}
// in this sample we use simplified models to fetch less data from the service
// instead of using the full Employee model that has many fields we do not need for the filters
public class TeamNameFilterOption
{
public string Team { get; set; }
}
public class NameFilterOption
{
public string Name { get; set; }
}
}
I want to compare special characters (such as umlauts) to other user input.
I have the following Grid setup:
Exception: System.ArgumentException: Operator 'IsEqualTo' is incompatible with operand types 'DateOnly?' and 'DateTime'
Hi,
documentation missing one extremely "silent" breaking change in grid data binding.
When binding/refreshing(subsequent reload) data to VARIABLE, there is "random" need to call grid.Rebind(); Mostly, when data are loaded outside of the grid, ie by some button, or another component. Used together with selected items and grouping enabled.
<TelerikGrid Data="@GridData" SelectionMode="GridSelectionMode.Single" SelectedItems="..."
OnRowClick="@...r" @ref="GHL" ....>
prior v6.0, everything is OK:
protected async Task ReloadGrid(int? xid)
{
GridData= await LoadDatafromservice<TItem>...;
}
After upgrading same code, it silently not displaying data or cras.
new breaking behavior at v6.0 - hotfix, but "ugly one":
protected async Task ReloadGrid(int? xid)
{
GridData= await LoadDatafromservice<TItem>...;
GHL.Rebind(); //required, otherwise grid content(rows) is not update. Later the grid crash when selecting row etc. Old "rows" are still displayed;
}
Its weird to gues, where rebind is needed and where not. Previous versions acting as expected(async - task = no problem).
Make it documented, "what is correct" and when.
Or if it is a bug, please move it out from feature request.
Thanks
Please expose the current data of the Grid and TreeList when using Data or OnRead. This will spare the need to cache data for the second time in-memory, or repeat all data operations. The benefit is that the app can:
When clicking on the Add Button in a Grid, a new item is created and displayed in edit mode.
Problem is, the OnEdit event is not triggered. I need to set a default value for new items and added the code in the OnEditHandler with if(args.IsNew){ //set default value}.
Unfortunately this does not work because the event is not triggered. This makes me wonder what "args.IsNew" is for if not for the usecase described above.
A workaround is to initialize the collection of the selected items:
<TelerikButton OnClick="@LoadData">Load Data</TelerikButton>
<TelerikGrid Data=@adminUsers Height="300px" Pageable=true PageSize=10 SelectionMode="@GridSelectionMode.Multiple"
@bind-SelectedItems="SelectedAdminUsers">
<GridColumns>
<GridCheckboxColumn SelectAll="true"></GridCheckboxColumn>
<GridColumn Field=@nameof(User.DisplayName) Title="User Name" />
<GridColumn Field=@nameof(User.Department) Title="Department" />
<GridColumn Field=@nameof(User.Status) Title="Status" />
<GridColumn Field=@nameof(User.EmployeeId) Title="Employee Id" />
</GridColumns>
</TelerikGrid>
@code
{
public IEnumerable<User> SelectedAdminUsers { get; set; } = Enumerable.Empty<User>();
public List<User> adminUsers { get; set; }
void LoadData()
{
adminUsers = Enumerable.Range(1, 200).Select(x => new User
{
EmployeeId = x,
Status = $"status {x}",
Department = $"department {x}",
DisplayName = $"name {x}"
}
).ToList();
}
public class User
{
public string DisplayName { get; set; }
public string Department { get; set; }
public string Status { get; set; }
public int EmployeeId { get; set; }
}
}
<TelerikGrid Data="@GridData"
FilterMode="Telerik.Blazor.GridFilterMode.FilterRow"
SelectionMode="@GridSelectionMode.Multiple"
@bind-SelectedItems="SelectedItems">
<GridColumns>
<GridCheckboxColumn Width="35px"/>
<GridColumn Field="@(nameof(Data.Name))" />
</GridColumns>
</TelerikGrid>
@code{
public class Data
{
public string Name { get; set; }
}
public List<Data> GridData { get; set; }
public IEnumerable<Data> SelectedItems { get; set; }
protected override void OnInitialized()
{
GridData = new List<Data>();
SelectedItems = new List<Data>();
GridData.Add(new Data{Name="abc"});
GridData.Add(new Data{Name="abe"});
GridData.Add(new Data{Name="xyz"});
}
}
1. Filter the above grid by "abc" (the filtered grid will display "abc" correctly as the only entry)
2. Click into the "SelectAll" Checkbox (SelectedItems will wrongly contain "abc" AND "abe" !!!)
3. Click on "ClearFilter" Button --> the grid will display both "abc" and "abe" as selected !!!
It might be an indexing problem because the "SelectAll" Logic always seems to ignore the last character of the search string while the filtering of the display takes all characters into account.
This bug has cost be many hours and stomach pain! Please let me know, if this will be fixed soon. If not I will have to implement my own filtering (which makes me wonder why I'm using Telerik UI).
I have a grid that i use to display a number of different items with, some that have the need to display child or hierarchical grids, and some that donĀ“t.
At the moment, all of the items show the "plus" button to expand the child grid, event though there is nothing there to show.
When a collection is null I think that the "plus" button to expand the hierarchical, or child grid, should be hidden.
Or at least I should be able to hide that button manually by choice.
Regards Magnus.
For example, I'd like something like this:
Field Name: record.TotalSales -> Auto-generated column title: "Total Sales" with inserted space
ADMIN EDIT: See also the idea below about "AutoGeneratedTitles" Func<string, string> property where the user could perform whatever processing they liked upon the default value. Please leave your comment on what approach you would prefer to be exposed.