The window actions OnClick handler does not execute when a predefined action (e.g. Close) is triggered. This prevents custom logic from running during standard close operations.
Reproducible on version 14.0.0
Repro: https://blazorrepl.telerik.com/wqaJcWbu45qZxbeX49
The disable option is still showing the step and it is not good for me. I have 35 types of transactions and all of them have generic and specific step.
---
ADMIN EDIT
Here is a potential workaround - basic conditional markup can add or remove steps. The key thing is that they will be added to the end of the wizard if they had not been rendered. To handle this, dispose and re-initialize the component, so the step will be rendered at the correct position.
If you have complex steps, you can work around this by creating a collection of descriptor models for the list of steps and create the steps based on that collection, where you can keep the VIsible flag, in a fashion similar to this example for the TabStrip.
<TelerikButton OnClick="@ToggleStep">Toggle attachments step visibility</TelerikButton>
@if (WizardVisible)
{
<TelerikWizard @bind-Value="@CurrStepIndex">
<WizardSteps>
<WizardStep Label="Personal Details" Icon="SvgIcon.User">
<Content>
content here
</Content>
</WizardStep>
@if (AttachmentsStepVisible)
{
<WizardStep Label="Attachments" Icon="SvgIcon.Paperclip">
<Content>
conditional content here
</Content>
</WizardStep>
}
<WizardStep Label="Confirmation" Icon="SvgIcon.Check">
<Content>
other content here
</Content>
</WizardStep>
</WizardSteps>
</TelerikWizard>
}
@code {
private bool AttachmentsStepVisible { get; set; }
private bool WizardVisible { get; set; } = true;
private int CurrStepIndex { get; set; }
private async void ToggleStep()
{
//dispose the Wizard
WizardVisible = false;
// defence against hiding the step when it is the last step, which would cause an exception
if (AttachmentsStepVisible && CurrStepIndex == 2)
{
CurrStepIndex = 1;
}
//the actual visibility toggle
AttachmentsStepVisible = !AttachmentsStepVisible;
//allow some time for the disposal and toggling the step visibility prior to re-initialization
await Task.Delay(10);
//re-initialize the Wizard
WizardVisible = true;
StateHasChanged();
}
}---
The CheckBoxList filter does not work as expected when the Grid is bound to ExpandoObject
===
ADMIN EDIT: A possible workaround is to bind the Grid with OnRead event and populate the MemberType property of the filter descriptors manually:
@using System.Dynamic
@using Telerik.DataSource
@using Telerik.DataSource.Extensions
<TelerikGrid OnRead="@OnGridRead"
TItem="@ExpandoObject"
Pageable="true"
Sortable="true"
FilterMode="@GridFilterMode.FilterMenu"
FilterMenuType="@FilterMenuType.CheckBoxList"
Height="400px">
<GridToolBarTemplate>
<GridSearchBox />
</GridToolBarTemplate>
<GridColumns>
@{
if (GridData != null && GridData.Any())
{
<GridColumn Field="PropertyInt" FieldType="@GridPropertyTypes["PropertyInt"]" />
<GridColumn Field="PropertyString" FieldType="@GridPropertyTypes["PropertyString"]" />
<GridColumn Field="PropertyGroup" FieldType="@GridPropertyTypes["PropertyString"]" />
<GridColumn Field="PropertyDate" FieldType="@GridPropertyTypes["PropertyDate"]" />
<GridColumn Field="PropertyBool" FieldType="@GridPropertyTypes["PropertyBool"]" />
}
}
</GridColumns>
</TelerikGrid>
@code {
private List<ExpandoObject> GridData { get; set; } = new List<ExpandoObject>();
private Dictionary<string, Type> GridPropertyTypes { get; set; } = new Dictionary<string, Type>() {
{ "Id", typeof(int) },
{ "PropertyInt", typeof(int) },
{ "PropertyString", typeof(string) },
{ "PropertyGroup", typeof(string) },
{ "PropertyDate", typeof(DateTime) },
{ "PropertyBool", typeof(bool) }
};
private async Task OnGridRead(GridReadEventArgs args)
{
args.Request.Filters.OfType<CompositeFilterDescriptor>()
.Each(x =>
{
x.FilterDescriptors.OfType<FilterDescriptor>()
.Each(y => y.MemberType = GridPropertyTypes[y.Member]);
});
var result = GridData.ToDataSourceResult(args.Request);
args.Data = result.Data;
args.Total = result.Total;
args.AggregateResults = result.AggregateResults;
}
protected override void OnInitialized()
{
for (int i = 1; i <= 18; i++)
{
dynamic expando = new ExpandoObject();
expando.Id = i;
expando.PropertyGroup = $"Group {(i % 3 + 1)}";
expando.PropertyInt = i;
expando.PropertyString = $"String {(char)(64 + i)}{(char)(64 + i)}";
expando.PropertyDate = DateTime.Now.AddMonths(-i);
expando.PropertyBool = i % 2 != 0;
GridData.Add(expando);
}
}
}
The issue is reproducible when the `AllowCustom` parameter is set to `true`.
Typing rapidly in the input field of the MultiColumnComboBox component causes the entered text to blink. Also, some of the inserted symbols are cleared.
Open this demo: https://demos.telerik.com/blazor-ui/multicolumncombobox/custom-values
Try to input text rapidly into the input field.
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.
I want a less-persistent popup, where a click outside of its boundaries would close it. To give a real world example, the Share Snippet feature in REPL works in such a way.
===
Telerik edit: A workaround for the time being is to attach a JavaScript click handler that closes the Popup instance: https://blazorrepl.telerik.com/GyumGrEs22yZgoCD16
We upgraded to the latest Telerik Blazor components (8.1.1).
I think there's a bug in the TabStrip when setting the index of the ActiveTabIndex or @bind-ActiveTabIndex.
The page will scroll to the active tab automatically.
Here's a link to the Repl - https://blazorrepl.telerik.com/GfaTEmbR45zQSzEq44
If you remove @bind-ActiveTabIndex="@ActiveTabIndex" from the TelerikTabStrip then the page load normally.
Thanks,
Cesar
The problem with the extra characters at the beginning of the PDF document has resurfaced.
The bytes returned by GetFileAsync() don't start with %PDF-, but with JS.ReceiveByteArray. Some PDF readers and my antivirus flag the file as corrupt or suspicious. I worked around it by stripping everything before the first %PDF- occurrence in the bytes before writing to disk.
The DropDownTree does not show its selected value if the data is set asynchronously.
Possible workarounds include:
Test page:
DropDownTreeValue1: @DropDownTreeValue1
<br />
DropDownTreeValue2: @DropDownTreeValue2
<br />
Bug:
<TelerikDropDownTree Data="@DropDownTreeData"
@bind-Value="@DropDownTreeValue1"
@bind-ExpandedItems="@DropDownTreeExpandedItems"
Width="300px">
</TelerikDropDownTree>
Workaround:
<TelerikDropDownTree Data="@DropDownTreeData"
@bind-Value="@DropDownTreeValue2"
@bind-ExpandedItems="@DropDownTreeExpandedItems"
Width="300px">
</TelerikDropDownTree>
@* Render DropDownTree after setting Data *@
@if (DropDownTreeData is not null)
{
<span>Workaround:</span>
<TelerikDropDownTree Data="@DropDownTreeData"
@bind-Value="@DropDownTreeValue1"
@bind-ExpandedItems="@DropDownTreeExpandedItems"
Width="300px">
</TelerikDropDownTree>
}
@code {
private List<TreeItem>? DropDownTreeData { get; set; }
private int DropDownTreeValue1 { get; set; }
private int DropDownTreeValue2 { get; set; }
private IEnumerable<object> DropDownTreeExpandedItems { get; set; } = new List<TreeItem>();
protected override async Task OnInitializedAsync()
{
DropDownTreeValue1 = 3;
await Task.Delay(1000);
DropDownTreeData = LoadFlatData();
// Set DropDownTree Value after setting Data
DropDownTreeValue2 = 3;
DropDownTreeExpandedItems = DropDownTreeData.Where(x => x.ParentId is null && x.HasChildren);
}
private int TreeLevels { get; set; } = 3;
private int RootItems { get; set; } = 2;
private int ItemsPerLevel { get; set; } = 2;
private int IdCounter { get; set; }
private List<TreeItem> LoadFlatData()
{
List<TreeItem> items = new List<TreeItem>();
PopulateChildren(items, null, 1);
return items;
}
private void PopulateChildren(List<TreeItem> items, int? parentId, int level)
{
var itemCount = level == 1 ? RootItems : ItemsPerLevel;
for (int i = 1; i <= itemCount; i++)
{
var itemId = ++IdCounter;
items.Add(new TreeItem()
{
Id = itemId,
ParentId = parentId,
HasChildren = level < TreeLevels,
Text = $"Level {level} Item {i} Id {itemId}",
Value = itemId
});
if (level < TreeLevels)
{
PopulateChildren(items, itemId, level + 1);
}
}
}
public class TreeItem
{
public int Id { get; set; }
public int? ParentId { get; set; }
public bool HasChildren { get; set; }
public string Text { get; set; } = string.Empty;
public int Value { get; set; }
}
}
An exception occurs if a Grid row is dropped in another empty Grid in RTL mode:
Error: System.FormatException: the input string '-1' was not in a correct format.
I tried to use the TelerikDropDownTree component in my blazor application. When I activate the option ShowClearButton and click on the clear button, there is no update of the bound value or the ValueChanged event will be raised.
I can reproduce my issue with repl https://blazorrepl.telerik.com/wKOcviug54ZSE06146
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();
}
}
How to reproduce:
The regression was introduced in version 12.2.0. The last version that works correctly is 12.0.0.
The possible workarounds are:
@using System.ComponentModel.DataAnnotations
@using Telerik.DataSource
@using Telerik.DataSource.Extensions
<TelerikGrid @ref="@GridRef"
OnRead="@OnGridRead"
TItem="@Product"
EditMode="@GridEditMode.Incell"
OnCreate="@OnGridCreate"
OnDelete="@OnGridDelete"
OnUpdate="@OnGridUpdate"
Height="600px">
<GridToolBarTemplate>
<GridCommandButton Command="Add">Add Item</GridCommandButton>
</GridToolBarTemplate>
<GridColumns>
<GridColumn Field="@nameof(Product.Name)">
<EditorTemplate>
@{ var dataItem = (Product)context; }
<span @onfocusout="@( async () => await OnGridCellFocusOut(nameof(Product.Name)) )">
<TelerikTextBox @bind-Value="@dataItem.Name" />
</span>
</EditorTemplate>
</GridColumn>
@* <GridColumn Field="@nameof(Product.Price)" DisplayFormat="{0:C2}" />
<GridColumn Field="@nameof(Product.Quantity)" DisplayFormat="{0:N0}" />
<GridColumn Field="@nameof(Product.ReleaseDate)" DisplayFormat="{0:d}" /> *@
<GridColumn Field="@nameof(Product.Discontinued)" Width="120px">
<EditorTemplate>
@{ var dataItem = (Product)context; }
<span @onfocusout="@( async () => await OnGridCellFocusOut(nameof(Product.Discontinued)) )">
<TelerikCheckBox @bind-Value="@dataItem.Discontinued" />
</span>
</EditorTemplate>
</GridColumn>
<GridCommandColumn Width="180px">
<GridCommandButton Command="Delete">Delete</GridCommandButton>
</GridCommandColumn>
</GridColumns>
</TelerikGrid>
@code {
private TelerikGrid<Product>? GridRef { get; set; }
private ProductService GridProductService { get; set; } = new();
private async Task OnGridCellFocusOut(string field)
{
await Task.Delay(100);
if (GridRef is null)
{
return;
}
GridState<Product> gridState = GridRef.GetState();
Product? editItem = gridState.EditItem as Product;
if (editItem is null)
{
return;
}
GridCommandEventArgs args = new GridCommandEventArgs()
{
Field = field,
Item = editItem
};
await OnGridUpdate(args);
gridState.EditField = default;
gridState.EditItem = default!;
gridState.OriginalEditItem = default!;
await GridRef.SetStateAsync(gridState);
}
private async Task OnGridCreate(GridCommandEventArgs args)
{
var createdItem = (Product)args.Item;
await GridProductService.Create(createdItem);
}
private async Task OnGridDelete(GridCommandEventArgs args)
{
var deletedItem = (Product)args.Item;
await GridProductService.Delete(deletedItem);
}
private async Task OnGridRead(GridReadEventArgs args)
{
DataSourceResult result = await GridProductService.Read(args.Request);
args.Data = result.Data;
args.Total = result.Total;
args.AggregateResults = result.AggregateResults;
}
private async Task OnGridUpdate(GridCommandEventArgs args)
{
var updatedItem = (Product)args.Item;
await GridProductService.Update(updatedItem);
}
public class Product
{
public int Id { get; set; }
[Required]
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public decimal? Price { get; set; }
public int Quantity { get; set; }
[Required]
public DateTime? ReleaseDate { get; set; }
public bool Discontinued { get; set; }
}
#region Data Service
public class ProductService
{
private List<Product> Items { get; set; } = new();
private int LastId { get; set; }
public async Task<int> Create(Product product)
{
await SimulateAsyncOperation();
product.Id = ++LastId;
Items.Insert(0, product);
return LastId;
}
public async Task<bool> Delete(Product product)
{
await SimulateAsyncOperation();
if (Items.Contains(product))
{
Items.Remove(product);
return true;
}
return false;
}
public async Task<List<Product>> Read()
{
await SimulateAsyncOperation();
return Items;
}
public async Task<DataSourceResult> Read(DataSourceRequest request)
{
return await Items.ToDataSourceResultAsync(request);
}
public async Task<bool> Update(Product product)
{
await SimulateAsyncOperation();
int originalItemIndex = Items.FindIndex(x => x.Id == product.Id);
if (originalItemIndex != -1)
{
Items[originalItemIndex] = product;
return true;
}
return false;
}
private async Task SimulateAsyncOperation()
{
await Task.Delay(100);
}
public ProductService(int itemCount = 5)
{
Random rnd = Random.Shared;
for (int i = 1; i <= itemCount; i++)
{
Items.Add(new Product()
{
Id = ++LastId,
Name = $"Product {LastId}",
Description = $"Multi-line\ndescription {LastId}",
Price = LastId % 2 == 0 ? null : rnd.Next(0, 100) * 1.23m,
Quantity = LastId % 2 == 0 ? 0 : rnd.Next(0, 3000),
ReleaseDate = DateTime.Today.AddDays(-rnd.Next(365, 3650)),
Discontinued = LastId % 2 == 0
});
}
}
}
#endregion Data Service
}
Currently, a TextField value of empty string will produce a blank item in the dropdown.
On the other hand, a null TextField value will produce the fully qualified class name.
Here are possible workarounds: https://blazorrepl.telerik.com/myOlFpFb1465jW8E07
Set the PdfViewer document (data) value to null. As a result, an endless loader will appear.
===
ADMIN EDIT
===
A possible workaround for the time being is to re-initialize the component after clearing the file: https://blazorrepl.telerik.com/cHYwQola24zzBOAd02.