Customers report inconsistent in-cell editing behavior with DatePicker columns in the Grid.
Here is a REPL test page that reproduces the issue (first date column) and provides a workaround (second date column):
https://blazorrepl.telerik.com/QAErkrEh090ykIxR16
The workaround relies on Grid EditorTemplate, the DatePicker OnClose event, and programmatic Grid edit mode management. The relevant code is:
@using System.ComponentModel.DataAnnotations
<TelerikGrid @ref="@GridRef"
Data="@GridData"
EditMode="@GridEditMode.Incell"
OnUpdate="@OnGridUpdate"
OnCreate="@OnGridCreate">
<GridToolBarTemplate>
<GridCommandButton Command="Add">Add Item</GridCommandButton>
</GridToolBarTemplate>
<GridColumns>
<GridColumn Field="@nameof(Product.Name)" />
<GridColumn Field="@nameof(Product.StartDate)" Title="BUG" DisplayFormat="{0:d}" />
<GridColumn Field="@nameof(Product.EndDate)" Title="WORKAROUND" DisplayFormat="{0:d}">
<EditorTemplate>
@{ var editItem = (Product)context; }
<TelerikDatePicker Value="editItem.EndDate"
ValueChanged="@((DateTime? newValue) => OnGridDatePickerValueChanged(newValue, editItem))"
ValueExpression="@( () => editItem.EndDate )"
OnClose="@(async () => await OnGridDatePickerClose(editItem))" />
</EditorTemplate>
</GridColumn>
</GridColumns>
</TelerikGrid>
@code {
#nullable enable
private TelerikGrid<Product>? GridRef;
private List<Product> GridData { get; set; } = new();
private int LastId { get; set; }
private DateTime LastDatePickerValueChanged { get; set; } = DateTime.Now;
private void OnGridDatePickerValueChanged(DateTime? newValue, Product editItem)
{
editItem.EndDate = newValue;
LastDatePickerValueChanged = DateTime.Now;
}
private async Task OnGridDatePickerClose(Product editItem)
{
if (DateTime.Now - LastDatePickerValueChanged > TimeSpan.FromMilliseconds(500))
{
GridState<Product> gridState = GridRef!.GetState();
if (gridState.EditItem is not null && gridState.EditItem.Id == editItem.Id)
{
// Uncomment to perform an item update instead of cancel
// OnGridUpdate(new GridCommandEventArgs { Item = editItem });
gridState.OriginalEditItem = null!;
gridState.EditItem = null!;
await GridRef.SetStateAsync(gridState);
}
}
}
private void OnGridCreate(GridCommandEventArgs args)
{
var createdItem = (Product)args.Item;
createdItem.Id = ++LastId;
GridData.Insert(0, createdItem);
}
private void OnGridUpdate(GridCommandEventArgs args)
{
var updatedItem = (Product)args.Item;
var originalItemIndex = GridData.FindIndex(i => i.Id == updatedItem.Id);
if (originalItemIndex != -1)
{
GridData[originalItemIndex] = updatedItem;
}
}
protected override void OnInitialized()
{
for (int i = 1; i <= 5; i++)
{
GridData.Add(new Product()
{
Id = ++LastId,
Name = $"Product {LastId}",
Price = Random.Shared.Next(0, 100) * 1.23m,
Quantity = Random.Shared.Next(0, 1000),
StartDate = DateTime.Today.AddDays(-Random.Shared.Next(60, 1000)),
EndDate = DateTime.Today.AddDays(Random.Shared.Next(1, 60)),
IsActive = LastId % 4 > 0
});
}
}
public class Product
{
public int Id { get; set; }
[Required]
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
public int Quantity { get; set; }
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; }
public bool IsActive { get; set; }
}
}
The Telerik UI for Blazor TimePicker currently does not appear to expose an equivalent to the Kendo UI for jQuery TimePicker "focusTime" option.
https://github.com/telerik/kendo-ui-core/blob/master/docs/api/javascript/ui/timepicker.md#focustime-datedefault-null
In Kendo UI for jQuery, focusTime allows the popup to open with a specific time focused without actually setting the selected value. This is useful when the picker has no value yet.
For example, let's say we want the time-picker to open up with the placeholder value of 08:00, how would we achieve this in Telerik UI for Blazor? Currently it defaults the placeholder to the current time.
Thanks
(bug report only)
Regression introduced in 9.0.0.
1. Run the code posted below and export the Grid.
2. Open the exported Excel file.
<TelerikGrid Data=@GridData
Pageable="true" Sortable="true" Resizable="true" Reorderable="true"
ShowColumnMenu="true" FilterMode="@GridFilterMode.FilterMenu"
Width="800px" Height="400px">
<GridToolBar>
<GridToolBarExcelExportTool>
Export to Excel
</GridToolBarExcelExportTool>
</GridToolBar>
<GridExport>
<GridExcelExport FileName="telerik-grid-export" AllPages="false" />
</GridExport>
<GridColumns>
<GridColumn Title="Personal Information">
<Columns>
<GridColumn Field=@nameof(Customer.FirstName) Title="First Name" Width="100px" />
<GridColumn Field=@nameof(Customer.LastName) Title="Last Name" Width="100px" />
</Columns>
</GridColumn>
<GridColumn Title="Company">
<Columns>
<GridColumn Field=@nameof(Customer.CompanyName) Title="Name" />
<GridColumn Field=@nameof(Customer.HasCompanyContract) Title="Has Contract" Width="120px" />
</Columns>
</GridColumn>
<GridColumn Title="Contact Details">
<Columns>
<GridColumn Field="@nameof(Customer.Email)" Title="Email"></GridColumn>
<GridColumn Field="@nameof(Customer.Phone)" Title="Phone"></GridColumn>
<GridColumn Field="@nameof(Customer.City)" Title="City"></GridColumn>
</Columns>
</GridColumn>
</GridColumns>
</TelerikGrid>
@code {
public List<Customer> GridData { get; set; }
public class Customer
{
public int Id { get; set; }
public string PasswordHash { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string CompanyName { get; set; }
public bool HasCompanyContract { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string City { get; set; }
}
// generation of dummy data
protected override void OnInitialized()
{
GridData = GenerateData();
}
List<Customer> GenerateData()
{
var data = new List<Customer>();
string[] fNames = new string[] { "Nancy", "John", "Orlando", "Jane", "Bob", "Juan" };
string[] lNames = new string[] { "Harris", "Gates", "Smith", "Caprio", "Gash", "Gee" };
string[] cNames = new string[] { "Acme", "Northwind", "Contoso" };
string[] cities = new string[] { "Denver", "New York", "LA", "London", "Paris", "Helsinki", "Moscow", "Sofia" };
Random rnd = new Random();
for (int i = 0; i < 150; i++)
{
string fName = fNames[rnd.Next(0, fNames.Length)];
string lName = lNames[rnd.Next(0, lNames.Length)];
string cName = cNames[rnd.Next(0, cNames.Length)];
data.Add(new Customer
{
Id = i,
PasswordHash = "not shown",
FirstName = fName,
LastName = lName,
CompanyName = cName,
HasCompanyContract = i % 3 == 0,
Email = $"{fName}.{lName}@{cName}.com",
Phone = $"{rnd.Next(100, 999)}-555-{rnd.Next(100, 999)}",
City = cities[rnd.Next(0, cities.Length)]
});
}
return data;
}
}
(optional)
The “Personal Information”, “Company”, “Contact Details” headers are not exported.
The multi-column headers are exported.
The TabStrip ActiveTabIdChanged event fires when the user navigates to another page.
The workaround is to detect app navigation and prevent the business logic execution. The example below is for the general case. If the app navigates programmatically with NavigationManager.NavigateTo(), you can set the IsNavigating flag immediately before that.
@implements IDisposable
@inject NavigationManager NavManager
<TelerikTabStrip ActiveTabId="@ActiveTabId"
ActiveTabIdChanged="@TabStripActiveTabIdChanged">
@for (int i = 1; i <= TabCount; i++)
{
int tabIndex = i;
<TabStripTab @key="@tabIndex" Title="@($"Tab {tabIndex}")" Id="@($"tab{tabIndex}")">
<h2>Tab @tabIndex</h2>
</TabStripTab>
}
</TelerikTabStrip>
@code {
private string ActiveTabId { get; set; } = "tab1";
private bool IsNavigating { get; set; }
private const int TabCount = 3;
private async Task TabStripActiveTabIdChanged(string newActiveTabId)
{
if (IsNavigating)
{
return;
}
ActiveTabId = newActiveTabId;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
locationChangingRegistration = NavManager.RegisterLocationChangingHandler(OnLocationChanging);
}
}
private IDisposable? locationChangingRegistration;
private ValueTask OnLocationChanging(LocationChangingContext context)
{
IsNavigating = true;
return ValueTask.CompletedTask;
}
public void Dispose() => locationChangingRegistration?.Dispose();
}
If the element of the tooltip is on top of the screen (almost outside of the viewport), hovering the remaining part of the element makes the tooltip create a flashing effect.
Please watch the attached video.
When I place a tooltip on drawer item, it just flickers randomly
![[video-to-gif output image]](https://im3.ezgif.com/tmp/ezgif-3-4372cd0f87.gif)
https://blazorrepl.telerik.com/wQbbmbGb05hzznPh45
When you select a date in DropDownList with dates in it (List<DateTime>), the @bind-Value is shaving off the milliseconds.
===ADMIN EDIT===
In the meantime, as a workaround for displaying milliseconds correctly, you can bind the DropDownList to a model. This way, you can use the "Id" to retrieve the selected item and display its precise milliseconds. Below is an example I've prepared to demonstrate this approach:
Selected value: @myDdlData.ToList().Where(x => x.Id == selectedValueId).FirstOrDefault()?.MyValueField.ToString("MM/dd/yyyy HH:mm:ss.fff")
<br />
<TelerikDropDownList Data="@myDdlData"
TextField="MyTextField"
ValueField="Id"
@bind-Value="selectedValueId">
</TelerikDropDownList>
@code {
public class MyDdlModel
{
public int Id { get; set; }
public DateTime MyValueField { get; set; }
public string MyTextField => MyValueField.ToString("MM/dd/yyyy HH:mm:ss.fff"); // Display formatted DateTime
}
private int selectedValueId { get; set; } = 1;
private IEnumerable<MyDdlModel> myDdlData = GenerateRandomDateTimes(20);
private static IEnumerable<MyDdlModel> GenerateRandomDateTimes(int count)
{
Random random = new Random();
DateTime startDate = DateTime.Now;
return Enumerable.Range(1, count)
.Select(x => new MyDdlModel
{
Id = x, // Unique integer Id
MyValueField = startDate.AddDays(x)
.AddMinutes(random.Next(0, 60))
.AddSeconds(random.Next(0, 60))
.AddMilliseconds(random.Next(0, 1000))
}).ToList();
}
}
I have been having issues adding the month view to a Telerik Blazor scheduler component, when there is grouping. It gives a null reference error any time I try to switch to the month view. I also tried it using the available demo for grouping in Telerik REPL, the only difference I found between my code and the demo was that I had used the ItemsPerSlot parameter. I added this to the demo, and was able to reproduce the error I was seeing, and I have attached the console output from the REPL demo. I believe there is either a bug with the ItemsPerSlot being used in conjunction with grouping on a scheduler component, or some instruction missing from how to set it up properly to prevent this null reference issue.
Changed code:
<SchedulerMonthView ItemsPerSlot="5"></SchedulerMonthView>
Demo used:
Blazor Scheduler (Event Calendar) Demos - Grouping | Telerik UI for Blazor
The PDF standard allows two ways to configure Acro fields and relate them to inputs (widget annotations):
Adobe Acrobat supports both options. Telerik PdfProcessing supports only the first option, which is more commonly used. The PDF Viewer supports only the second option. If the PDF Viewer loads a file with the first configuration, the component saves new field values in such a way that they can't be retrieved by PdfProcessing. Moreover, if the PDF file is opened locally, it looks like the new values are there, but when you click on a field, the original value shows. The new value behaves like a placeholder rather than a real value.
Would it be possible to have the ability to create compact TreeList's similar to how we can now in a Grid? Since Size=ThemeConstants.Grid.Size.Small is available a Grid now it seems natural this would be a next step. If we can be provided with a work around for the time being that would be great.
The FileManager crashes with a null reference exception when the selected file is deleted while the preview pane is open.
https://demos.telerik.com/blazor-ui/filemanager/overview
Error: System.NullReferenceException: Object reference not set to an instance of an object.
at System.Object.GetType()
at Telerik.Blazor.Components.TelerikFileManager`1.ConvertToFileEntry(Object dataItem)
at Telerik.Blazor.Components.TelerikFileManager`1.GetSelectedEntryForDetails()
at Telerik.Blazor.Components.TelerikFileManager`1.<BuildRenderTree>b__397_15(RenderTreeBuilder __builder3)
at Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder.AddContent(Int32 sequence, RenderFragment fragment)
at Telerik.Blazor.Components.TelerikSplitter.BuildRenderTree(RenderTreeBuilder __builder)
at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, Exception& renderFragmentException)
Reproduction with Data parameter
https://blazorrepl.telerik.com/GJYPlrEW485dZtjX55
Reproduction with OnRead
I made a Blazor REPL reproduction: https://blazorrepl.telerik.com/mcuCGpYr4223mhWY49. Run and observe the person label is overlapping the dropdown.
How to reproduce:
<TelerikFloatingLabel Text="Person">
<TelerikComboBox
TItem="@Person" TValue="@int"
ScrollMode="@DropDownScrollMode.Virtual"
OnRead="@GetRemoteData"
ValueMapper="@GetModelFromValue"
ItemHeight="30"
PageSize="20"
TextField="@nameof(Person.Name)"
ValueField="@nameof(Person.Id)"
@bind-Value="@SelectedValue"
Filterable="true" FilterOperator="@StringFilterOperator.Contains">
<ComboBoxSettings>
<ComboBoxPopupSettings Height="200px" />
</ComboBoxSettings>
</TelerikComboBox>
</TelerikFloatingLabel>