Reproducible:
@using System.Collections.ObjectModel;
<div style="align-self:center;text-align:center" class="alert-danger">
@errorMessages
</div>
<div style="align-self:center;text-align:center" class="alert-success">
@successMessages
</div>
<TelerikGrid Data=@entitlementsExtended
Pageable="true"
Groupable="false"
PageSize="@PageSize"
OnUpdate="@UpdateHandler"
Sortable="false"
FilterMode="Telerik.Blazor.GridFilterMode.FilterMenu">
<GridColumns>
<GridColumn Field="@nameof(EntitlementValueDTOExtended.Description)" Editable="false" />
<GridColumn Field=@nameof(EntitlementValueDTOExtended.Value)>
<EditorTemplate>
@{
CurrentlyEditedEntitlement = context as EntitlementValueDTOExtended;
<div>
<TelerikDropDownList Data="@entitlementOptions" @bind-Value="CurrentlyEditedEntitlement.Value" Width="60px" PopupHeight="auto"></TelerikDropDownList>
</div>
}
</EditorTemplate>
</GridColumn>
<GridCommandColumn Width="300px">
<GridCommandButton Command="Save" Icon="save" ShowInEdit="true">Update</GridCommandButton>
<GridCommandButton Command="Edit" Icon="edit">Edit</GridCommandButton>
<GridCommandButton Command="Cancel" Icon="cancel" ShowInEdit="true">Cancel</GridCommandButton>
</GridCommandColumn>
</GridColumns>
</TelerikGrid>
@code {
int PageSize = 10;
public EntitlementValueDTOExtended CurrentlyEditedEntitlement { get; set; } = new EntitlementValueDTOExtended();
//changing this to List<> works
public ObservableCollection<EntitlementValueDTOExtended> entitlementsExtended { get; set; } = new ObservableCollection<EntitlementValueDTOExtended>();
public static List<string> entitlementOptions = new List<string> { "I", "E" };
public string errorMessages { get; set; } = "";
public string successMessages { get; set; } = "";
protected async override Task OnInitializedAsync()
{
IEnumerable<int> entitlements = Enumerable.Range(1, 50);
//this is a simplified workaround for people needing nested models
foreach (var entitlement in entitlements)
{
EntitlementValueDTOExtended entitlementExtended = new EntitlementValueDTOExtended();
entitlementExtended.Id = Guid.NewGuid();
entitlementExtended.Description = $"descr {entitlement}";
entitlementExtended.Value = $"value {entitlement}";
entitlementExtended.EntitlementTypeId = entitlement;
entitlementsExtended.Add(entitlementExtended);
}
StateHasChanged();
await base.OnInitializedAsync();
}
public async Task UpdateHandler(GridCommandEventArgs args)
{
EntitlementValueDTOExtended item = (EntitlementValueDTOExtended)args.Item;
var matchingItem = entitlementsExtended.FirstOrDefault(c => c.Id == item.Id);
if (matchingItem != null)
{
matchingItem.Description = item.Description;
matchingItem.EntitlementTypeId = item.EntitlementTypeId;
matchingItem.Value = item.Value;
}
successMessages = $"updated grid on {DateTime.Now}";
StateHasChanged();
}
public class EntitlementValueDTOExtended
{
public Guid Id { get; set; }
public string Description { get; set; } = "";
public string Value { get; set; } = "";
public int EntitlementTypeId { get; set; } = 0;
}
ADMIN EDIT: The following knowledge base article has been updated to explain how to use nested models: https://docs.telerik.com/blazor-ui/knowledge-base/grid-bind-navigation-property-complex-object
At the moment, you must use flat models with primitive types for binding the grid. If you don't, the data source operations break and they can't even display "nested" values. Examples here and here.
I would like to be able to use my complex models so I can point a grid's column to a field like MyModel.MyNestedModel.MyPrimitiveField
My be related to binding to a data table and dynamic expando.
TelerikGird with virtual scrolling was working in version 2.7, but after upgrading to 2.10, it is only showing placeholders.
When scrolling, it shows the values for a split second, but then those get replaced by the placeholders.
@page "/test"
<TelerikGrid Data=@GridData
SelectionMode="GridSelectionMode.Single"
ScrollMode="GridScrollMode.Virtual"
Height="300px" RowHeight="20">
<GridColumns>
<GridColumn Field=@nameof(Employee.Name) />
<GridColumn Field=@nameof(Employee.Team) Title="Team" />
</GridColumns>
</TelerikGrid>
@code {
public List<Employee> GridData { get; set; }
protected override void OnInitialized()
{
GridData = new List<Employee>();
for (int i = 0; i < 15; i++)
{
GridData.Add(new Employee()
{
EmployeeId = i,
Name = "Employee " + i.ToString(),
Team = "Team " + i % 3
});
}
}
public class Employee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
public string Team { get; set; }
}
}
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; }
}
}
Reproducible
@page "/"
Is there any way to default the values that are used when I create a new row?
So for example, I have a row where I want to default a date to Jan 1st of the following year. However, when I add the row, it adds nulls to all fields and the date shows up as 1 Jan 1900 and there's a lot of fiddly clicking to set the right date.
Grid with Checkbox Column throws the following error when placed inside EditForm:
InvalidOperationException: Telerik.Blazor.Components.TelerikCheckBox`1[System.Nullable`1[System.Boolean]] requires a value for the 'ValueExpression' ValueExpression is provided automatically when using 'bind-Value'.
Hi there,
currently the grid component does not provide a feature to set a specific position in virtual scrolling mode.
My team has currently implemented a workaround via javascript interop call to set a specific position. The workaround basically calculates the "scroll value" (we reverse engineered this value by looking at the Telerik js code) and passes it to the jQuery scrollTop() function. This results in an update of the scrollbar which in return triggers the OnReadItems event where we fetch the items based on the given skip and take values.
This workaround does not seem to work in all cases and is somewhat unreliable hence i'm requesting an official feature to set a specific position without the javascript hack.
What do you say?
So lonG
Daniel
<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.
Simplest repro code is below - expand a few rows and select items in them, or in the parent grid. I would expect that selection in each grid is independent, but the child grid seems to control the parent selection too, even though it is disabled.
<TelerikGrid Data="salesTeamMembers" PageSize="4" Pageable="true" @bind-SelectedItems="@SelectedItemsMainGrid" SelectionMode="@GridSelectionMode.Single">
<DetailTemplate>
@{
var employee = context as MainModel;
<TelerikGrid Data="employee.Orders" Pageable="true" PageSize="7" SelectionMode="@GridSelectionMode.None">
<GridColumns>
<GridColumn Field="OrderId"></GridColumn>
<GridColumn Field="DealSize"></GridColumn>
</GridColumns>
</TelerikGrid>
}
</DetailTemplate>
<GridColumns>
<GridColumn Field="Id"></GridColumn>
<GridColumn Field="Name"></GridColumn>
</GridColumns>
</TelerikGrid>
@foreach (var item in SelectedItemsMainGrid)
{
<div>@item.Name</div>
}
@code {
List<MainModel> salesTeamMembers { get; set; }
public IEnumerable<MainModel> SelectedItemsMainGrid { get; set; } = Enumerable.Empty<MainModel>();
protected override void OnInitialized()
{
salesTeamMembers = GenerateData();
}
private List<MainModel> GenerateData()
{
List<MainModel> data = new List<MainModel>();
for (int i = 1; i < 16; i++)
{
MainModel mdl = new MainModel { Id = i, Name = $"Name {i}" };
mdl.Orders = Enumerable.Range(1, 15).Select(x => new DetailsModel { OrderId = x, DealSize = x ^ i }).ToList();
data.Add(mdl);
}
return data;
}
public class MainModel
{
public int Id { get; set; }
public string Name { get; set; }
public List<DetailsModel> Orders { get; set; }
}
public class DetailsModel
{
public int OrderId { get; set; }
public double DealSize { get; set; }
}
}
I'm following your example listed here (in ObservableCollection section)
https://docs.telerik.com/blazor-ui/components/grid/selection/overview
The following scenario does not work.
Select an item in the grid.
Clear data set. Grid (simplified) look like this. Notice that the checkbox is selected even though nothing is in the grid.
Uncheck chekcbox.
Check checkbox -> All items from the previous data set will be selected (printed in ul bellow grid)
I have inspected the grid and i does not contain any item in its Data collection so I'm unsure from where does it get the selection.
Best regards,
Robert
Likely related to https://feedback.telerik.com/blazor/1432615-support-for-nested-complex-models
Issue - Filtering / Sorting on a column that is bound to a complex object fails to generate the proper OData string.
Example Grid Code, three columns, column 1 and 3 are bound to a complex class, column 2 just a string:
<TelerikGrid Data=@sysVars.Dtos Pageable="true" Sortable="true" FilterMode="Telerik.Blazor.GridFilterMode.FilterRow" PageSize="20" TotalCount=@sysVars.Count OnRead=@ReadItems>
<GridColumns>
<GridColumn Field=@nameof(SysVar.SysVarType.Name) Title="Type" Editable="false">
<Template>
@{
var data = context as SysVar;
@data.SysVarType.Name
}
</Template>
</GridColumn>
<GridColumn Field=@nameof(SysVar.Value) Title="Value">
<Template>
@{
var data = context as SysVar;
var link = SysVarDto.FrontEndEditUrl(data.Id.Value);
<NavLink href=@link>@data.Value</NavLink>
}
</Template>
</GridColumn>
<GridColumn Field=@nameof(SysVar.Hierarchy.Description) Title="Hierarchy">
<Template>
@{
var data = context as SysVar;
@data.Hierarchy.Description
}
</Template>
</GridColumn>
</GridColumns>
</TelerikGrid>
The values bound to the grid are made up of a complex object. For the sake of the example
public class SysVar
{
public string Value { get; set; }
public Hierarchy Hierarchy { get; set; }
public SysVarType SysVarType { get; set; }
}
public class Hierarchy
{
public string Description { get; set; }
}
public class SysVarType
{
public string Name { get; set; }
}
Right now I know I can't have the Grid render SysVarType.Name, so I use a custom cell and everything works. However, if I try to sort/filter on my complex columns, SysVarType or Hierarchy the resulting OData string that is generated is incorrect.
Example of what is should look like, from a Telerik Grid in my React application if I sort on the sysVarType column:
https://localhost:44335/odata/v1/SysVarOData?$count=true&$expand=sysVarType($select=name),hierarchy($select=description)&$skip=0&$top=20&$orderby=value,sysVarType/name
Same string generated by the Telerik Grid in Blazor
Note: I can't sort two columns at the same time, not a huge issue at this time.
What is failing is the $orderby= doesn't return sysVarType/name and only returns name, causing a 400 on my backend as the class SysVar doesn't have a name field.