The null type of operator can cause errors on the backend
*** Thread created by admin on customer behalf ***
When using row virtualization, the visible rows are miscalculated when the browser zoom is used (hold control with mouse scroll).
The result of the miscalculation is that the first row at some point is not visible.
To reproduce the problem you should scroll to the top of the grid and see the first row.
Then start to zoom down and see how the first row is displaced.
Seems like only 50%, 100%, 150%, 200% (multiply of 50%) are calculated correctly in row virtualization
<AdminEdit>
You can reproduce the bug with the attached code.
It's browser-specific and is appearing only in chromium browsers.
It could be related to the way browsers calculate the size of the elements when zooming.
Currently, there is an open bug in the chromium: https://bugs.chromium.org/p/chromium/issues/detail?id=1048147&q=component%3AUI%3EBrowser%3EZoom%20height&can=2
</AdminEdit>
The orderby clause only has one column when multicolumn sorting is enabled, you can test it with this sample.
---
ADMIN EDIT
A workaround is to replace the orderby generated by the grid with your own clause that uses the DataSourceRequest to extract all sort descriptors, here's an example:
@using System.Net.Http.Json
@using System.Text.RegularExpressions
@using Telerik.Blazor.Extensions
@using WasmApp.Shared
@inject HttpClient Http
<TelerikGrid Data=@GridData
Height="460px"
RowHeight="60"
PageSize="10"
Pageable="true"
Sortable="true"
FilterMode="@GridFilterMode.FilterRow"
SortMode="@SortMode.Multiple"
OnRead=@ReadItems
TotalCount=@Total>
<GridColumns>
<GridColumn Field="ProductID" />
<GridColumn Field="ProductName" />
<GridColumn Field="Discontinued" />
</GridColumns>
</TelerikGrid>
@code{
public List<ODataProduct> GridData { get; set; } = new List<ODataProduct>();
public int Total { get; set; } = 0;
protected async Task ReadItems(GridReadEventArgs args)
{
var baseUrl = "https://demos.telerik.com/kendo-ui/service-v4/odata/Products?";
string OdataUrl = args.Request.ToODataString();
// replace the original orederby clause with one that contains all the order rules
Regex x = new Regex("(orderby=)(.*?)(&)", RegexOptions.IgnoreCase);
string actualOrderByClause = "orderby=";
for (int i = 0; i < args.Request.Sorts.Count; i++)
{
if (i > 0)
{
actualOrderByClause += ",";
}
string order = args.Request.Sorts[i].SortDirection == Telerik.DataSource.ListSortDirection.Ascending ? "" : "%20desc";
actualOrderByClause += $"{args.Request.Sorts[i].Member}{order}";
}
actualOrderByClause += "&";
string OdataQueryWithMultipleOrder = x.Replace(OdataUrl, actualOrderByClause);
//do the request as usual
var requestUrl = $"{baseUrl}{OdataQueryWithMultipleOrder}";
ODataResponseOrders response = await Http.GetFromJsonAsync<ODataResponseOrders>(requestUrl);
GridData = response.Products;
Total = response.Total;
}
}
---
If you set args.IsCancelled=true in any CUD event handler, the loading sign will never go away.
---
ADMIN EDIT
If you don't need to cancel the event (e.g., because remote validation or data operation failed), you should avoid cancelling it - its purpose is to keep the grid in the current mode (edit/insert) when the operation fails so the user does not lose data.
That said, the loading sing should disappear in thsoe cases too, and a workaround is to disable it by setting the EnableLoaderContainer="false" parameter of the grid.
---
I want to be able to use interfaces and models that are created from a service when working with the grid. A parameterless constructor is not enough for me, I need to be able to instantiate models in a more complex manner.
---
ADMIN EDIT
The tentative event name I have put in the title might vary when the implementation is researched. The goal would still be the same - the grid to provide an event when it needs an instance of the model so you can provide it with one. At the moment this happens when a row enters edit mode, when the filter list needs to be built, and when you are inserting an item (a caveat with the last one might be the OnClick event for the command button - the new event might have to fire before OnClick so it can give you the model).
---
I have a WASM application and I setup my Grid to use the editor as an editing field in the Grid. When the user types something the application is laggy and it might even hang.
---
ADMIN EDIT
Attached is a sample app that alleviates this a little by using a regular textarea and making editor updates less frequent.
---
I have a Grid and if the initial validation fails for a certain cell and the user edits a cell with a valid value on the same row the editing freezes.
<AdminEdit>
As a workaround, you can provide valid initial values for all cells in the Grid.
</AdminEdit>
Hi,
I am getting an unhandled exception when setting the GridState of a TelerikGrid with the SetState method that has multi-column headers.
Exception:
Unhandled exception rendering component: More than one sibling of element 'col' has the same key value, 'Telerik.Blazor.Components.GridColumn'. Key values must be unique.
Example grid:
<TelerikGrid @ref=@TestGrid Data=@TestData FilterMode=GridFilterMode.FilterMenu Sortable="true" SortMode=SortMode.Multiple TItem="TestDataItem">
<GridColumns>
<GridColumn Title="Test Column 1" Field=@nameof(TestDataItem.TestColumn1) />
<GridColumn Title="Test Column Group" />
<Columns>
<GridColumn Title="Test Column 2" Field=@nameof(TestDataItem.TestColumn2) />
<GridColumn Title="Test Column 3" Field=@nameof(TestDataItem.TestColumn3) />
</Columns>
</GridColumn>
</GridColumns>
<TelerikGrid>
I have tried to set the Id or @key of the columns but nothing has fixed this issue.
The TelerikGrid is kind of missing a "None" Value in the enum for the EditMode.
We need to disable the edit mode based on a value from the model (role access restricted), and I don't see any way this is possible without copy-pasting the entire grid under an if statement.
------ADMIN EDIT-------
A possible workaround at the moment is to set the "Editable" parameter of the columns to "false" or not use a command column with "edit".
Another workaround can be to attach a OnEdit handler and cancel the event based on the view model flag only. If the user cannot edit - always cancel.
After the update I get the following error message:
/...Views/ViewRoute.razor(13,13): Error CS0012: The type 'SortDescriptor'is defined in an assembly that isnot referenced. You must add a reference to assembly 'Telerik.DataSource, Version=2.0.10.0, Culture=neutral, PublicKeyToken=29ac1a93ec063d92'. (CS0012)
the package is installed...nevertheless I get the error
<PackageReference Include="Telerik.UI.for.Blazor" Version="2.26.0" />
<PackageReference Include="Telerik.DataSource" Version="2.0.10" />
at this position
GridState<Wegpunkte> desiredState = new GridState<Wegpunkte>()
{
SortDescriptors = new List<SortDescriptor>()
{
new SortDescriptor {Member = "TourPos", SortDirection = ListSortDirection.Ascending}
}
};
I have a filterable DropDownList in a Grid EditorTemplate. The edit mode is InCell.
When the user opens the dropdown, the edited cell closes immediately with an OnUpdate call. The DropDownList value can be changed only with the keyboard or if I disable DropDownList filtering.
===
The same problem occurs with any component that uses a popup and the popup can gain focus - ComboBox, ColorPicker, etc.
The exception is -
System.ArgumentNullException: Value cannot be null. (Parameter 'source')
Here is a test page, based on this one -
@using Telerik.DataSource
@using Telerik.DataSource.Extensions
@using System.IO
<TelerikGrid TItem="@object"
LoadGroupsOnDemand="true"
Groupable="true"
OnStateInit="@((GridStateEventArgs<object> args) => OnStateInitHandler(args))"
OnRead="@ReadItems"
ScrollMode="@GridScrollMode.Virtual" PageSize="20" RowHeight="60"
Navigable="true" Sortable="true" FilterMode="@GridFilterMode.FilterRow" Height="600px">
<GridColumns>
<GridColumn Field="@nameof(Employee.Name)" FieldType="@typeof(string)" Groupable="false" />
<GridColumn Field="@nameof(Employee.Team)" FieldType="@typeof(string)" Title="Team" />
<GridColumn Field="@nameof(Employee.Salary)" FieldType="@typeof(decimal)" Groupable="false" />
<GridColumn Field="@nameof(Employee.IsOnLeave)" FieldType="@typeof(bool)" Title="On Vacation" />
</GridColumns>
</TelerikGrid>
@code {
List<object> GridData { get; set; }
protected async Task ReadItems(GridReadEventArgs args)
{
DataEnvelope<Employee> result = await MyService.GetData(args.Request);
if (args.Request.Groups.Count > 0)
{
args.Data = result.GroupedData.Cast<AggregateFunctionsGroup>().ToList();
}
else
{
args.Data = result.CurrentPageData.Cast<Employee>().ToList();
}
args.Total = result.TotalItemCount;
if (args.Request.Groups.Count > 0)
{
try
{
List<AggregateFunctionsGroup> items = result.GroupedData.Cast<AggregateFunctionsGroup>().ToList();
await using var s = new MemoryStream();
await System.Text.Json.JsonSerializer.SerializeAsync(s, items);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
void OnStateInitHandler(GridStateEventArgs<object> args)
{
// set initial grouping
GridState<object> desiredState = new GridState<object>()
{
GroupDescriptors = new List<GroupDescriptor>()
{
new GroupDescriptor()
{
Member = "Team",
MemberType = typeof(string)
},
new GroupDescriptor()
{
Member = "IsOnLeave",
MemberType = typeof(bool)
}
}
};
args.GridState = desiredState;
}
public class Employee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
public string Team { get; set; }
public bool IsOnLeave { get; set; }
public decimal Salary { get; set; }
}
public class DataEnvelope<T>
{
public List<AggregateFunctionsGroup> GroupedData { get; set; }
public List<T> CurrentPageData { get; set; }
public int TotalItemCount { get; set; }
}
public static class MyService
{
private static List<Employee> SourceData { get; set; }
public static async Task<DataEnvelope<Employee>> GetData(DataSourceRequest request)
{
if (SourceData == null)
{
SourceData = new List<Employee>();
var rand = new Random();
for (int i = 1; i <= 2500; i++)
{
SourceData.Add(new Employee()
{
EmployeeId = i,
Name = "Employee " + i.ToString(),
Team = "Team " + i % 100,
IsOnLeave = i % 3 == 0,
Salary = rand.Next(1000, 5000)
});
}
}
await Task.Delay(500);// deliberate delay to showcase async operations, remove in a real app
// retrieve data as needed, you can find more examples and runnable projects here
// https://github.com/telerik/blazor-ui/tree/master/grid/datasourcerequest-on-server
var datasourceResult = SourceData.ToDataSourceResult(request);
DataEnvelope<Employee> dataToReturn;
if (request.Groups.Count > 0)
{
dataToReturn = new DataEnvelope<Employee>
{
GroupedData = datasourceResult.Data.Cast<AggregateFunctionsGroup>().ToList(),
TotalItemCount = datasourceResult.Total
};
}
else
{
dataToReturn = new DataEnvelope<Employee>
{
CurrentPageData = datasourceResult.Data.Cast<Employee>().ToList(),
TotalItemCount = datasourceResult.Total
};
}
return await Task.FromResult(dataToReturn);
}
}
}
The filter list item menu defined as follows do not have accessible name. Please provide work around or fix that I can implement.
<TelerikGrid Data="@ViewModel.RouterAndDataLossInformation" TItem="TrafficLossSummary"
Pageable="true"
Sortable="true"
Groupable="false"
FilterMode="Telerik.Blazor.GridFilterMode.FilterRow"
Resizable="true"
Reorderable="true"
Height = "100%">
As of UI for Blazor 4.0. ExcelExportableColumn is inaccessible due to its protection level and GridExcelExportColumn should be used instead.
I am trying to add the hidden columns to the exported file through the OnBeforeExport event. However, I am unable to create an exportable column instance using the GridExcelExportColumn. I get the following error:
CS1729: GridExcelExportColumn does not contain a constructor that takes 0 arguments.
Using the following configuration does not produce the expected result:
<GridSettings>
<GridPopupEditFormSettings ButtonsLayout="FormButtonsLayout.Center"/>
</GridSettings>
The button layout is always left no matter what you choose.
===
ADMIN EDIT
===
Possible workarounds for the time being are to position the buttons with CSS or use a Popup Buttons Template.