There seems to be no System.Type that will allow a GridColumn to be specified with the 'FieldType' attribute to receive a TelerikTimePicker
typeof(DateTime) --> TelerikDateTimePicker
typeof(?) --> TelerikTimePicker
<TelerikGrid Data="@gridDataExpando" Width="100%" Sortable="false" Pageable="false" Resizable="true" ShowColumnMenu="false"
ScrollMode="@GridScrollMode.Scrollable"
Height="100%"
EditMode="@GridEditMode.Incell"
OnUpdate="@UpdateHandlerExpando"
OnEdit="@EditHandler">
<GridColumns>
@{
var firstItem = gridDataExpando.FirstOrDefault();
if (firstItem != null)
{
var dictionaryItem = firstItem as IDictionary<string, object>;
foreach (var item in dictionaryItem)
{
if (!item.Key.Contains("Id"))
{
<GridColumn Field="@(item.Key)" FieldType="@(this.GetDataType(item.Key))" Width="140px" DisplayFormat="{0:hh:mm:ss tt}">
<HeaderTemplate>
<span>@item.Key</span>
</HeaderTemplate>
</GridColumn>
}
}
}
}
</GridColumns>
</TelerikGrid>
I am using a CheckBoxList filter menu and I am setting an initial filter through the OnStateInit. I noticed that when the Grid initializes and I check all the boxes, the Grid does not show any records. For reference, if no initial filter is applied and all CheckBoxes are selected, the Grid shows all the records.
Reproduction: https://blazorrepl.telerik.com/GSbbbJut14K03I2x14.
===
ADMIN EDIT
===
As a workaround for the time being, you may create a custom Filter Menu.
Problem Statement:
We have the following blazor grid:
We have enabled the GridColumnMenuSettings
Now when we open the column chooser it does not disable for the last option.
When we don't have the GridCheckboxColumn then it works as intended
The last column option is disabled
Expected Result : We don't want the check box column to be shown in the column chooser and the last option to be unchecked in the column chooser needs to be disabled.
@* Use the Template to render the list of columns and add some custom styles *@
<TelerikGrid Data="@MyData"
Pageable="true"
PageSize="5"
Width="700px"
FilterMode="@GridFilterMode.FilterMenu"
Sortable="true"
ShowColumnMenu="true">
<GridSettings>
<GridColumnMenuSettings Sortable="true"
Lockable="false"
FilterMode="@ColumnMenuFilterMode.None" />
</GridSettings>
<GridColumns>
<GridCheckboxColumn Width="80px" HeaderClass="header-select-all" />
<GridColumn Field="@(nameof(SampleData.Id))" Width="80px" Title="Id" Id="id-column-id" />
<GridColumn Field="@(nameof(SampleData.FirstName))" Title="First Name" Id="firstname-column-id" />
<GridColumn Field="@(nameof(SampleData.LastName))" Title="Last Name" Id="lastname-column-id" />
<GridColumn Field="@(nameof(SampleData.CompanyName))" Title="Company" Id="companyname-column-id" />
<GridColumn Field="@(nameof(SampleData.Team))" Title="Team" Id="team-column-id" />
<GridColumn Field="@(nameof(SampleData.HireDate))" Title="Hire Date" Id="hiredate-column-id" />
</GridColumns>
</TelerikGrid>
@code {
public string TextboxValue { get; set; } = string.Empty;
public IEnumerable<SampleData> MyData = Enumerable.Range(1, 30).Select(x => new SampleData
{
Id = x,
FirstName = $"FirstName {x}",
LastName = $"LastName {x}",
CompanyName = $"Company {x}",
Team = "team " + x % 5,
HireDate = DateTime.Now.AddDays(-x).Date
});
public class SampleData
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string CompanyName { get; set; }
public string Team { get; set; }
public DateTime HireDate { get; set; }
}
}
Grid with columns price1 and price2. Enter value in price1, switch to price2, enter value there, and editor is set to old value after async events finish.
The value entered in price2 is correctly set to the property, but the editor reverts to the previous value. If you escape edit mode of the cell, the value entered before the events finish will be shown.
On (fast) tabbing and entering values, this removes the first values entered before the async background events finish.
I tried reproducing the problem in REPL, but could not get the exact same behaviour. In our case no specific value is being set to price2, it just reverts.
https://blazorrepl.telerik.com/cxEzvQvE52q8aaAi27
How would you approach preventing the editor from being overridden by other cells' delayed events?
Hi,
it seems that grid.GetState() and FilterDescriptors, contains +1 "dummy" object.
- If it is by design, ok, BUT then, how to bind this filter descriptor to the ie TelerikFilter? = It displays that dummy object as it is, and confusing end users. Or how to "identify 100%" that is some kind of dummy value to be trashed?
How to reproduce:
1 run the repl demo
2 put "a" into the first colum(Name) filter
3 click button and observe the content of filter descriptors(serialized below the grid - RED is wrong, Green is expected as ok)
similar, but not the same(iam came from here):
Thanks for the tip, clarification, or removing that redundant values.
Greetings,
When using single selection mode, a row can be selected either by clicking the checkbox or by clicking on the rest of the row. There is no difference at all. Now, let's say I have a grid with multiple selection mode enabled, e.g.:
<TelerikGrid Data="listOfFoos" SelectionMode="GridSelectionMode.Multiple">
<GridColumns>
<GridCheckboxColumn SelectAll="true" SelectAllMode="GridSelectAllMode.All" />
<GridColumn Field="@nameof(Foo.Name)" Title="Name" />
</GridColumns>
</TelerikGrid>
public class Foo {
public string Name { get; set; }
}
public List<Foo> listOfFoos = [ new Foo{Name="First"}, new Foo{Name="Second"}, new Foo{Name="Third"} ];
When we click an unselected row, the behavior varies depending on where we click exactly:
This notably makes multiple selection impossible if we click on the row but not on the checkbox and gives the impression we are using single selection mode. It is especially strange if we consider the existence of the CheckBoxOnlySelection parameter of <GridCheckboxColumn> whose name suggests we can select using the rest of the row by default.
Hello,
after updating to the versin 4.6.0 from 4.5.0, almost all svg icons dissapeared(inside the grid). No erros, no console warnings.
Is there some breaking changes or aditional steps how to bring them back?
Original markup without changes(first blue button in example should have "play" icon at the beginning):
<TelerikButton OnClick="@(_ => OZRowCmd(null,20))" Icon="@FontIcon.Play" Title="Zahájit novou" Class="bg-primary" Size="@Telerik.Blazor.ThemeConstants.Button.Size.Large">Zahájit novou</TelerikButton>
It seems the Grid and GridSearchBox assume the search string by taking the value of GridState.SearchFilter.FilterDescriptors[0].Value and this is causing a few issues:
I am expanding grid search to include non-string columns, and I want this to apply by default across our entire application without having to update every grid individually or developers having to remember to opt in.
To search other type columns, I’ve largely taken the logic from Search Grid in numeric and date fields - Telerik UI for Blazor and it works well. However, that solution utilizes a custom search box component that I would have to add to each grid.
Instead, I have placed this filter creation logic in the OnStateChanged handler as exemplified in How to Search Grid Items with a StartsWith Filter Operator - Telerik UI for Blazor, as we already have a handler for this event that all grids utilize.
This has worked wonderfully except for the issues I’ve mentioned.
If the first filter is a CompositeFilterDescriptor, it causes an exception. Specifically:
Unable to cast object of type 'Telerik.DataSource.CompositeFilterDescriptor' to type 'Telerik.DataSource.FilterDescriptor'.
at Telerik.Blazor.Components.Common.TableGridBase`2.LoadSearchFilter(IFilterDescriptor descriptor)
at Telerik.Blazor.Components.TelerikGrid`1.SetStateInternal(GridState`1 state)
at Telerik.Blazor.Components.TelerikGrid`1.<SetStateAsync>d__311.MoveNext()
at Web.Pages.Grid.<OnStateChangedHandler>d__18.MoveNext() in C:\src\Web\Pages\Grid.razor:line 196
If there is another filter in the collection that is not a CompositeFilterDescriptor, I can work around this problem by moving it to the front of the list.
// Make sure first filter is not composite.
var nonCompositeFilter = newSearchFilter.FilterDescriptors.OfType<FilterDescriptor>().FirstOrDefault();
if (nonCompositeFilter is not null && newSearchFilter.FilterDescriptors[0] is CompositeFilterDescriptor)
{
newSearchFilter.FilterDescriptors.Remove(nonCompositeFilter);
newSearchFilter.FilterDescriptors.Insert(0, nonCompositeFilter);
}
However, if all filters are composite, the exception is unavoidable.
If the GridState.SearchFilter.FilterDescriptors collection is empty, the search box gets cleared. This is a problem when a user needs to type more characters for a filter to be created.
For example, let’s say you are only searching DateTime columns and using the logic from Search Grid in numeric and date fields - Telerik UI for Blazor. As you type, it checks to see if the input is an integer between 1000 and 2100. Until you type the fourth digit, it will not meet that condition thus will not add a filter. So if you begin by typing “2”, it searches and a filter will not be added yet. However, because there are no filters, it will clear the search box. You won’t be able to type out a full year value of “2023” unless you type fast enough to outpace the debounce delay.
Using the same example as above but with an Enum column instead of a DateTime, begin typing text. If the text matches an enum name, a filter is added for the enum item’s underlying value. For example:
Sample project attached.
Hello,
as you can see in the provided example : https://blazorrepl.telerik.com/GwEsxPFc05zxpF2u01
i have set a filter for column Country on OnStateInitHandler event. However when i try to clear the filter from the filtermenutemplate button , Check box has the previous value. But data are bound correctly.
Could you give me some advice?
Hi,
We ran into an issue with manual binding and selected items with Grid component. I used the 'WebApiFromServerApp' sample in 'grid\datasourcerequest-on-server' folder from Telerik's samples on GitHub.
To recreate the issue, modify 'GridWithService.razor' file in 'WebApiFromServerApp' project. I attached modified project.
To test the behavior:
Thank you.
Hi,
When we use custom filters with FilterMenuTemplate in combination with setting filters programmatically, the filter value remains visible after using the 'delete' button.
Simplified example:
Note: We have the same issue with a custom filter with a checkbox list and that code is based on the example of the filter menu template in the documentation.
Note 2: When we use the custom filters and the 'Delete' button without setting the filters programmatically, everything works fine.
It's like the 'Delete' button clears the FilterDescriptors in de Grid State (and we get the data we expect), but the FilterDescriptors in the FilterMenuTemplateContext aren't cleared.. But only when those are set programmatically.. (by setting the grid state).
I already tried to think of a workaround by hooking the OnStateChanged, but there the FilterDescriptors on the grid state are empty when the 'Delete' button is used. As expected, because we get the data we want.. But don't think I can access the FilterMenuTemplateContext there, to clear it as well..
----
ADMIN EDIT
The Excel export seems to honor it, so it can be used as a workaround.
Reproducible with the workaround commented out:
<TelerikButton OnClick="@CurrentPage">Current Page</TelerikButton>
<TelerikButton OnClick="@AllPages">All Pages</TelerikButton>
<TelerikGrid Data="@GridData"
@ref="@GridRef"
Pageable="true"
Sortable="true"
Resizable="true"
Reorderable="true"
FilterMode="@GridFilterMode.FilterRow"
Groupable="true">
<GridExport>
<GridExcelExport FileName="telerik-grid-export" AllPages="@ExportAllPages" />
</GridExport>
<GridColumns>
<GridColumn Field="@nameof(SampleData.ProductId)" Title="ID" Width="100px" />
<GridColumn Field="@nameof(SampleData.ProductName)" Title="Product Name" Width="300px" />
<GridColumn Field="@nameof(SampleData.UnitsInStock)" Title="In stock" Width="100px" />
<GridColumn Field="@nameof(SampleData.Price)" Title="Unit Price" Width="200px" />
<GridColumn Field="@nameof(SampleData.Discontinued)" Title="Discontinued" Width="100px" />
<GridColumn Field="@nameof(SampleData.FirstReleaseDate)" Title="Release Date" Width="300px" />
</GridColumns>
</TelerikGrid>
@code {
async Task AllPages()
{
ExportAllPages = true;
await Task.Delay(20); // allow the component to rerender with the new parameter
await GridRef.SaveAsCsvFileAsync();
//await GridRef.SaveAsExcelFileAsync(); // this works
}
async Task CurrentPage()
{
ExportAllPages = false;
await Task.Delay(20); // allow the component to rerender with the new parameter
await GridRef.SaveAsCsvFileAsync();
//await GridRef.SaveAsExcelFileAsync(); // this works
}
private TelerikGrid<SampleData> GridRef { get; set; }
List<SampleData> GridData { get; set; }
bool ExportAllPages { get; set; }
protected override void OnInitialized()
{
GridData = Enumerable.Range(1, 100).Select(x => new SampleData
{
ProductId = x,
ProductName = $"Product {x}",
UnitsInStock = x * 2,
Price = 3.14159m * x,
Discontinued = x % 4 == 0,
FirstReleaseDate = DateTime.Now.AddDays(-x)
}).ToList();
}
public class SampleData
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public int UnitsInStock { get; set; }
public decimal Price { get; set; }
public bool Discontinued { get; set; }
public DateTime FirstReleaseDate { get; set; }
}
}
When a user clicks outside of the edited input in the same cell, the cell remains in edit mode. The problem occurs in the 2.30.0 version.
You can see this behavior in the Incell Editing demo.
Documentation states that Grid supports Virtualization with Grouping if it is done by loading the Groups on-demand.
See:
On page: Blazor Grid - Load Group Data On Demand | Telerik UI for Blazor
From this, it appears that Virtual Scrolling, Group Load on Demand, and pagination of the results should function as expected. I'm specifically focusing on the section where it says "load on demand for the data when the user expands a group or when they scroll to need a new set of available groups".
The behavior I am seeing in my Telerik Repl is not matching up with that.
See: https://blazorrepl.telerik.com/QFbmurvT41eZq6Ld34
In the repl, I have added some Console.WriteLines to see when OnRead is actually called, as well as to log out some other information about the OnRead Request. It can be seen that no pagination information is included in the request (PageSize = 0, Skip = 0) while the PageSize is set on the actual Grid component (PageSize = 20).
As a result, all groups are loaded initially, which will be problematic if my server-side data set is being grouped on a value that will result in thousands/millions of groups.
It is possible that I missed something in the documentation that would enable the expected behavior (the Grid actually giving me PageSize and Skip so pagination will actually work), but it is also equally possible that this was never intended behavior, and I have been misled by the documentation page.
I have a blazor grid with a large number of columns which I would like to have the width of the page and a horizontal scrollbar to be able to scroll through all of the columns.
According the the documentation I have found (https://demos.telerik.com/blazor-ui/grid/scrolling), setting the width of the grid to 100% and providing widths for the columns which exceed that of the width of the grid/page should cause the horizontal scrollbar to appear. Instead of doing this, however, the grid just expands horizontally to fit all of the columns, no matter what I try. In addition, it appears to be expanding the entire page horizontally to fit itself, as it is increasing the size of all of my bootstrap columns so that it fits within the bootstrap container.
Here is an example of a page containing a grid where I am experiencing this:
@page "/admin/users/manageusers"
@inherits ManageUsersBase
<h3>Manage Users</h3>
<WS7.Components.PDAuthorizeBase AllowedRoleIds="ManageAllUsers,ManageAssignedUsers" />
@if (this.Users == null)
{
<p><em>Loading...</em></p>
}
else
{
<div class="form-group">
<label for="UserSearch" class="col-form-label">Search</label>
<input id="UserSearch" class="form-control" type="search" aria-label="User Search" placeholder="Search" @bind-value="Filter" @bind-value:event="oninput" />
</div>
<TelerikGrid Data="@FilteredUsers" TItem="WS7.Engine.Models.ViewModels.ManageUsersViewModel" Height="600px" Width="100%" Pageable="true" PageSize="40" Sortable="true" Groupable="false"
FilterMode="GridFilterMode.FilterMenu" Resizable="true" Reorderable="true" OnEdit="EditUser" ScrollMode="@GridScrollMode.Scrollable">
<GridToolBar>
<GridCommandButton OnClick="(()=>AddUser())">
<span class="oi oi-plus"></span> Add
</GridCommandButton>
</GridToolBar>
<GridColumns>
<GridCommandColumn Width="100px">
<GridCommandButton Command="Edit" Icon="edit">Edit</GridCommandButton>
</GridCommandColumn>
<GridColumn Field="UserName" Title="User Name" Width="500px" />
<GridColumn Field="Email" Title="Email" Width="500px" />
<GridColumn Field="FirstName" Title="First Name" Width="500px" />
<GridColumn Field="LastName" Title="Last Name" Width="500px" />
<GridColumn Field="AccountStatus" Title="Account Status" Width="500px">
<Template>
@{
string toolTip;
WS7.Engine.Models.ViewModels.ManageUsersViewModel user = context as WS7.Engine.Models.ViewModels.ManageUsersViewModel;
toolTip = "Account Status: " + user.AccountStatus;
toolTip += Environment.NewLine + "Active: " + user.Active.ToString();
toolTip += Environment.NewLine + "Email Confirmed: " + user.EmailConfirmed.ToString();
}
<div class="badge badge-pill badge-info">
<span class="oi oi-info" data-toggle="tooltip" data-placement="top" title="@toolTip"></span>
</div>
</Template>
</GridColumn>
@*<GridCommandColumn Width="90px">
<GridCommandButton Command="Delete" Icon="delete">Delete</GridCommandButton>
</GridCommandColumn>*@
</GridColumns>
</TelerikGrid>
}
---
ADMIN EDIT
You can find some more details on the origin of the issue in the thread below and in the following Knowledge Base article, which also offers a few ideas for solutions to this browser behavior: https://docs.telerik.com/blazor-ui/knowledge-base/grid-bootstrap-flex-width-issue
---
Hi,
I am using a grid on a data structure that has nested properties inside. Previously, I was able to do this which worked fine: (notice the first 2 colums)
<TelerikGrid Data="@PackedInfo.PackedParts" Height="100%">
<GridColumns>
<GridColumn Field=@nameof(PackedPart.Part.PartNo) Title="Part no" />
<GridColumn Field=@nameof(PackedPart.Part.PartDescription) Title="Description" />
<GridColumn Field=@nameof(PackedPart.UnitWeightG) Title="Substance Weight" />
<GridColumn Field=@nameof(PackedPart.FlashPointCentigrade) Title="Flash point" />
<GridColumn Field=@nameof(PackedPart.Pg) Title="PG" />
<GridColumn Field=@nameof(PackedPart.Qty) Title="PG" />
</GridColumns>
</TelerikGrid>
I recently upgraded to the latest version (Telerik.UI.for.Blazor (2.29.0) and noticed that the first 2 fields are no longer displaying. I fixed this, by specifying the field names as string values:
<TelerikGrid Data="@PackedInfo.PackedParts" Height="100%">
<GridColumns>
<GridColumn Field="Part.PartNo" Title="Part no" />
<GridColumn Field="Part.PartDescription" Title="Description" />
<GridColumn Field=@nameof(PackedPart.UnitWeightG) Title="Substance Weight" />
<GridColumn Field=@nameof(PackedPart.FlashPointCentigrade) Title="Flash point" />
<GridColumn Field=@nameof(PackedPart.Pg) Title="PG" />
<GridColumn Field=@nameof(PackedPart.Qty) Title="PG" />
</GridColumns>
</TelerikGrid>
I have also tried using @nameof(Part.PartNo) but that didn't work either. Only providing nested properties as string values works. This should not be the intended behaviour i'm sure?
regards,
Chris Nateghi
Hello,
After just a sort operation, in the event handler of OnStateChanged event, the FilterDescriptors of GridStateEventArgs.GridState is not empty.
Steps to reproduce :
1) Implement Grid with OnStateChanged and OnRead :
<TelerikGrid
OnStateChanged="@((GridStateEventArgs<IGetAgences_Agences_Items> args) => OnStateChangedHandler(args))"
OnRead=@ReadItems
async Task OnStateChangedHandler(GridStateEventArgs<IGetAgences_Agences_Items> args)
{
var filters = args.GridState.FilterDescriptors; // filters are not empty after just a sort opration
}
async Task ReadItems(GridReadEventArgs args)
{
this.LoadData()
await InvokeAsync(StateHasChanged);
}
2) Sort a column
3) The OnStateChanged event is fire
4) In the OnStateChangedHandler, the filters are not empty :
Expected behaviors :
If no filters added, the filters of the GridState must be empty
Thank's
Thomas
The new functionality to have the in-cell editing validate based on the model doesn't work with fluid validation. We use a custom component that integrates fluid validation with blazor which works fine for all controls including telerik input controls, but the built in validation for the grid editing doesn't seem to work with it.
Also there seems to be a bug with the validation using standard attribute validation. If the row you are working on has an existing record that does not validation properly, the in-cell editing will stop working once you go in to any cell and make a change. The edit mode on that cell will close as if everything updated ok, but after that, you will not be able to click into any cell to edit. While normally the data should already be valid, there can be scenarios where new validation rules are applied and existing records would become retroactively invalid.
Thanks,
Alan
I am having problems with grouping in TelerikGrid.
When I drag the column into the header for grouping, I get an error ArgumentNullException: Value cannot be null, apparently, somewhere in TelerikGrid.SetProcessedGroups.
Test code:@page "/test"
<div>
<TelerikGrid @ref="grid" Data="@GridData" @bind-Page="Page" PageSize="PageSize"
Pageable="true" Sortable="true" Groupable="true"
FilterMode="Telerik.Blazor.GridFilterMode.FilterMenu"
ShowColumnMenu="true"
TotalCount="@TotalRowCount"
SelectionMode="GridSelectionMode.Single"
OnRead=@ReadData>
<GridAggregates>
<GridAggregate Field=@nameof(TestData.Name) Aggregate="@GridAggregateType.Count" />
<GridAggregate Field=@nameof(TestData.Surname) Aggregate="@GridAggregateType.Count" />
<GridAggregate Field=@nameof(TestData.Department) Aggregate="@GridAggregateType.Count" />
</GridAggregates>
<GridColumns>
<GridColumn Field="@(nameof(TestData.Name))" FieldType="typeof(string)" Editable="false" Groupable="true" ShowColumnMenu="false" />
<GridColumn Field="@(nameof(TestData.Surname))" FieldType="typeof(string)" Editable="false" Groupable="true" ShowColumnMenu="false" />
<GridColumn Field="@(nameof(TestData.Department))" FieldType="typeof(string)" Editable="false" Groupable="true" ShowColumnMenu="false" />
<GridCommandColumn Width="60px" Lockable="false" ShowColumnMenu="true">
<GridCommandButton Command="View" Icon="information" ShowInEdit="false" OnClick="@ViewItem"></GridCommandButton>
</GridCommandColumn>
</GridColumns>
</TelerikGrid>
</div>
@code {
protected TelerikGrid<TestData> grid;
protected List<TestData> GridData { get; set; }
public int TotalRowCount { get; set; } = 0;
public int Page { get; set; } = 1;
public int PageSize { get; set; } = 10;
protected async Task ReadData(GridReadEventArgs args)
{
await LoadData();
}
protected async Task LoadData()
{
GridData = await GetSampleData();
TotalRowCount = 100;
}
protected async Task<List<TestData>> GetSampleData()
{
List<TestData> results = new List<TestData>();
results.Add(new TestData { Name = "Name1", Surname = "Surname1", Department = "Department1" });
results.Add(new TestData { Name = "Name2", Surname = "Surname2", Department = "Department1" });
results.Add(new TestData { Name = "Name3", Surname = "Surname3", Department = "Department1" });
results.Add(new TestData { Name = "Name4", Surname = "Surname4", Department = "Department1" });
results.Add(new TestData { Name = "Name5", Surname = "Surname5", Department = "Department2" });
results.Add(new TestData { Name = "Name6", Surname = "Surname6", Department = "Department2" });
results.Add(new TestData { Name = "Name7", Surname = "Surname7", Department = "Department2" });
results.Add(new TestData { Name = "Name8", Surname = "Surname8", Department = "Department3" });
results.Add(new TestData { Name = "Name9", Surname = "Surname9", Department = "Department3" });
results.Add(new TestData { Name = "Name10", Surname = "Surname10", Department = "Department4" });
await Task.Delay(1000); //simulate loading delay ...
return results;
}
protected void ViewItem(GridCommandEventArgs args)
{
//navigate to edit view ...
}
public class TestData
{
public string Name { get; set; }
public string Surname { get; set; }
public string Department { get; set; }
}
}
I am getting the following error:
This happens in Chrome and Edge, in Webassembly and Server-side blazor.
Am I doing something wrong?
Thanks for the help!