Unplanned
Last Updated: 16 Jul 2024 11:18 by Lajos

In a navigable Grid with incell edit, if a column has Editable=false the tabbing behavior is as follows: while the user is editing the previous editable cell pressing tab results in skipping the non-editable cell and moving the focus to the next editable cell to open it for edit.

However, the behavior is different when cancelling the editing through the OnEdit event. In this case, while the user is editing the previous editable cell pressing tab results in exiting the edit and keeping the focus to the cell. Subsequent tab press moves to focus to the pager.

Reproduction: https://blazorrepl.telerik.com/mykLFEFJ14mlqei429.

===

ADMIN EDIT

===

A possible option for the time being is to cancel the edit as shown in the example above but also force the Grid to enter edit of the next editable cell. You can do that through the State: Enter and Exit Grid Edit Mode Programmatically.

Here is a basic example, you may adjust it as needed to fit your exact requirements: https://blazorrepl.telerik.com/mSuLPAFP05HRs7B555.

Unplanned
Last Updated: 15 Jul 2024 11:38 by Alexander

Cases:

  • I am using the Template to control the rendering of the Drawer. When I place an <a> tag and focus it, I cannot use the Enter key to navigate to the desired link. The component traps the onkeypress event, which it should not.
  • When I place a TreeView inside the Drawer Template and focus it, the keyboard navigation does not work because the Drawer traps the HTML events like onkeydown.

<Admin>

Workaround for the first case:

<script suppress-error="BL9992">
    window.navigateToHref = (ev) => {
        if (ev.key === "Enter") {
            location.href = ev.target.href
        }
    };
</script>

@* This example shows how to create header and footer for the Drawer and select an item manually. *@
<TelerikDrawer @bind-Expanded="@DrawerExpanded"
               Data="@Data"
               MiniMode="true"
               Mode="@DrawerMode.Push"
               @bind-SelectedItem="@SelectedItem"
               @ref="@DrawerRef">
    <Template>
        @* the header *@
        <div>
            <TelerikButton OnClick="@(() => DrawerRef.ToggleAsync())" Icon="@FontIcon.Menu" />
            @if (DrawerExpanded)
            {
                <div class="text-info" style="border-bottom:solid; font-weight: bold; margin-bottom: 3em; white-space:nowrap">
                    <a href="https://google.com" onkeydown="navigateToHref(event)">
                        My Custom Navigation to Google
                    </a>
                </div>
            }
            else
            {
                <div class="text-info" style="border-bottom:solid; font-weight: bold;">
                    Nav
                </div>
            }
        </div>

        @* custom items rendering and item selection *@

        <div class="k-drawer-items">
            <ul>
                @if (SelectedItem != null && DrawerExpanded)
                {
                    <li class="k-drawer-item" style="white-space:nowrap">
                        <div>
                            <p><strong>@SelectedItem.Text</strong></p>
                            <p>@SelectedItem.Description</p>
                        </div>
                    </li>
                }

                @foreach (var item in Data)
                {
                    @* Use onclick to handle manual item selection *@
                    <li @onclick="@(() => SelectedItem = item)"
                    class="k-drawer-item @GetSelectedItemClass(item)" style="white-space:nowrap">
                        <TelerikFontIcon Icon="@item.Icon"></TelerikFontIcon>
                        @if (DrawerExpanded)
                        {
                            <div>
                                <div>@item.Text</div>
                            </div>
                        }
                    </li>
                }
            </ul>
        </div>

        @* the footer *@
        @if (DrawerExpanded)
        {
            <div style="text-align: center; margin-top: 3em; padding-top: 2em; border-top: 2px solid black; white-space:nowrap">
                <img src="user-avatar.png" alt="my avatar" style="border-radius: 50%; width: 50px; height: 50px;" />
                <br /><br />
                <TelerikButton Icon="@FontIcon.Logout" ThemeColor="primary">Log Out</TelerikButton>
            </div>
        }
    </Template>
    <DrawerContent>
        <div class="m-5">Content for @SelectedItem?.Text - @SelectedItem?.Description</div>
    </DrawerContent>
</TelerikDrawer>


@code {
    public TelerikDrawer<DrawerItem> DrawerRef { get; set; }
    public DrawerItem SelectedItem { get; set; }
    public bool DrawerExpanded { get; set; } = true;
    public IEnumerable<DrawerItem> Data { get; set; } = new List<DrawerItem>
    {
        new DrawerItem {Text = "Shopping Cart", Icon = FontIcon.Cart, Description = "Items in shopping cart"},
        new DrawerItem {Text = "Settings", Icon = FontIcon.Gear, Description = "My profile settings"},
        new DrawerItem {Text = "Notifications", Icon = FontIcon.ExclamationCircle, Description = "My profile notifications"},
        new DrawerItem {Text = "Calendar", Icon = FontIcon.Calendar, Description = "My events"},
    };

    public string GetSelectedItemClass(DrawerItem item)
    {
        if (SelectedItem == null) return string.Empty;
        return SelectedItem.Text.ToLowerInvariant().Equals(item.Text.ToLowerInvariant()) ? "text-info" : "";
    }

    public class DrawerItem
    {
        public string Text { get; set; }
        public FontIcon? Icon { get; set; }
        public string Description { get; set; }
    }
}

</Admin>

Unplanned
Last Updated: 15 Jul 2024 07:40 by Hang
Created by: Hang
Comments: 0
Category: FileManager
Type: Bug Report
1

When the user renames a folder, the TreeView foes not refresh to display the new folder name.

The test page below is based on the FileManager Events example.

A possible workaround is to recreate the FileManager in the OnUpdate handler:

@using System.IO

@if (ShouldRenderFileManager)
{
    <TelerikFileManager @ref="@FileManagerRef"
                        Data="@Files"
                        @bind-Path="@DirectoryPath"
                        View="@CurrentView"
                        ViewChanged="@OnViewChanged"
                        Height="400px"
                        OnCreate="@OnCreateHandler"
                        OnUpdate="@OnUpdateHandler"
                        OnDelete="@OnDeleteHandler"
                        OnModelInit="@OnModelInitHandler"
                        OnDownload="@OnDownloadHandler"
                        SelectedItems="@SelectedItems"
                        SelectedItemsChanged="@((IEnumerable<FlatFileEntry> selectedFiles) => OnSelect(selectedFiles))">
    </TelerikFileManager>
}

@foreach (var item in Files)
{
    <div>@item.Name</div>
}

@code {
    private bool ShouldRenderFileManager { get; set; } = true;

    private TelerikFileManager<FlatFileEntry>? FileManagerRef { get; set; }
    private List<FlatFileEntry> Files { get; set; } = new();

    private string DirectoryPath { get; set; } = string.Empty;

    private IEnumerable<FlatFileEntry> SelectedItems { get; set; } = new List<FlatFileEntry>();

    private FileManagerViewType CurrentView { get; set; }

    private void OnViewChanged(FileManagerViewType newView)
    {
        CurrentView = newView;
    }

    private async Task OnCreateHandler(FileManagerCreateEventArgs args)
    {
        var newFolder = args.Item as FlatFileEntry;

        var parent = GetParent(newFolder, DirectoryPath);

        newFolder.Id = "20";
        newFolder.ParentId = parent.Id;
        newFolder.Name = "New folder";
        newFolder.IsDirectory = true;
        newFolder.HasDirectories = false;
        newFolder.DateCreated = DateTime.Now;
        newFolder.DateCreatedUtc = DateTime.Now;
        newFolder.DateModified = DateTime.Now;
        newFolder.DateModifiedUtc = DateTime.Now;
        newFolder.Path = Path.Combine(DirectoryPath, newFolder.Name);
        newFolder.Extension = null;

        var parentDirectory = GetDirectory(DirectoryPath) ?? GetParent(newFolder, DirectoryPath);

        if (parentDirectory != null)
        {
            // Simulate add to the file system.
            newFolder.ParentId = parentDirectory.Id;
            Files.Add(newFolder);
            parentDirectory.HasDirectories = Files.Count(x => x.ParentId == parentDirectory.Id) > 0;
        }
        else
        {
            // Create a folder in the root directory.
            Files.Add(newFolder);
        }

        RefreshData();
    }

    private FlatFileEntry GetDirectory(string path)
    {
        var directory = Files.FirstOrDefault(x => x.IsDirectory && x.Path == path);

        return directory;
    }

    private FlatFileEntry GetParent(FlatFileEntry currItem, string currDirectory)
    {
        var parentItem = Files
            .FirstOrDefault(x => x.IsDirectory && x.Path == currDirectory);

        return parentItem;
    }


    private async Task OnUpdateHandler(FileManagerUpdateEventArgs args)
    {
        var item = args.Item as FlatFileEntry;

        if (item.IsDirectory)
        {
            var name = item.Name ?? string.Empty;

            var updatedItem = Files.FirstOrDefault(x => x.Id == item.Id);
            updatedItem.Name = item.Name;
            updatedItem.Path = Path.Combine(DirectoryPath, name);

            ShouldRenderFileManager = false;
            await Task.Delay(1);
            ShouldRenderFileManager = true;
        }
        else
        {
            // The name property is updated, but also update the path to the file.
            var name = item.Name ?? string.Empty;
            var extension = item.Extension ?? string.Empty;
            var fullName = extension.Length > 0 && name.EndsWith(extension) ?
                name : $"{name}{extension}";

            var updatedItem = Files.FirstOrDefault(x => x.Id == item.Id);

            updatedItem.Name = item.Name;
            updatedItem.Path = Path.Combine(DirectoryPath, fullName);
            Console.WriteLine(updatedItem.Path);
        }
    }

    private async Task OnDownloadHandler(FileManagerDownloadEventArgs args)
    {
        var selectedItem = args.Item as FlatFileEntry;

        // The Filemanager does not have the actual file.
        // Obtain the file contents, based on args.Item, and set the event arguments:

        //args.Stream = the file stream of the actual selected file;
        //args.MimeType = the MIME type of the actual file;
        //args.FileName = the file name that the browser will receive (optional);

        FlatFileEntry actualFile = (FlatFileEntry)args.Item;

        string dummyFileContent = $"This file is a dummy version of {actualFile.Name}. It was downloaded with the Telerik Blazor FileManager.";
        byte[] dummyFileBuffer = System.Text.Encoding.UTF8.GetBytes(dummyFileContent);

        args.Stream = new MemoryStream(dummyFileBuffer);
        args.MimeType = "text/plain";
        args.FileName = $"filemanager-{actualFile.Name}-{DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss")}.txt";
    }

    private async Task OnDeleteHandler(FileManagerDeleteEventArgs args)
    {
        var currItem = args.Item as FlatFileEntry;

        var itemToDelete = Files.FirstOrDefault(x => x.Id == currItem.Id);

        Files.Remove(itemToDelete);

        RefreshData();
    }

    private FlatFileEntry OnModelInitHandler()
    {
        var item = new FlatFileEntry();
        item.Name = $"New folder";
        item.Size = 0;
        item.Path = Path.Combine(DirectoryPath, item.Name);
        item.IsDirectory = true;
        item.HasDirectories = false;
        item.DateCreated = DateTime.Now;
        item.DateCreatedUtc = DateTime.Now;
        item.DateModified = DateTime.Now;
        item.DateModifiedUtc = DateTime.Now;

        return item;
    }

    private void OnSelect(IEnumerable<FlatFileEntry> selectedFiles)
    {
        // Update the view model.
        SelectedItems = selectedFiles;
    }

    private void RefreshData()
    {
        Files = new List<FlatFileEntry>(Files);
    }

    protected override async Task OnInitializedAsync()
    {
        Files = await GetFlatFileEntries();
    }

    public class FlatFileEntry
    {
        public string Id { get; set; }
        public string ParentId { get; set; }
        public string Name { get; set; }
        public long Size { get; set; }
        public string Path { get; set; }
        public string Extension { get; set; }
        public bool IsDirectory { get; set; }
        public bool HasDirectories { get; set; }
        public DateTime DateCreated { get; set; }
        public DateTime DateCreatedUtc { get; set; }
        public DateTime DateModified { get; set; }
        public DateTime DateModifiedUtc { get; set; }
    }

    // the next lines are hardcoded data generation so you can explore the FileManager freely

    private async Task<List<FlatFileEntry>> GetFlatFileEntries()
    {
        var workFiles = new FlatFileEntry()
        {
            Id = "1",
            ParentId = null,
            Name = "Work Files",
            IsDirectory = true,
            HasDirectories = true,
            DateCreated = new DateTime(2022, 1, 2),
            DateCreatedUtc = new DateTime(2022, 1, 2),
            DateModified = new DateTime(2022, 2, 3),
            DateModifiedUtc = new DateTime(2022, 2, 3),
            Path = Path.Combine("files"),
            Size = 3 * 1024 * 1024
        };

        var Documents = new FlatFileEntry()
        {
            Id = "2",
            ParentId = workFiles.Id,
            Name = "Documents",
            IsDirectory = true,
            HasDirectories = false,
            DateCreated = new DateTime(2022, 1, 2),
            DateCreatedUtc = new DateTime(2022, 1, 2),
            DateModified = new DateTime(2022, 2, 3),
            DateModifiedUtc = new DateTime(2022, 2, 3),
            Path = Path.Combine(workFiles.Path, "documents"),
            Size = 1024 * 1024
        };

        var Images = new FlatFileEntry()
        {
            Id = "3",
            ParentId = workFiles.Id,
            Name = "Images",
            IsDirectory = true,
            HasDirectories = false,
            DateCreated = new DateTime(2022, 1, 2),
            DateCreatedUtc = new DateTime(2022, 1, 2),
            DateModified = new DateTime(2022, 2, 3),
            DateModifiedUtc = new DateTime(2022, 2, 3),
            Path = Path.Combine(workFiles.Path, "images"),
            Size = 2 * 1024 * 1024
        };

        var files = new List<FlatFileEntry>()
{
            workFiles,

            Documents,

            Images
        };

        return files;
    }
}

Unplanned
Last Updated: 12 Jul 2024 07:05 by ADMIN

If you are zooming a page containing a DateTimePicker with "AdaptiveMode" set to "AdaptiveMode.Auto", the application crashes occasionally with the error:

Microsoft.JSInterop.JSException: Cannot read properties of null (reading 'addEventListener')
TypeError: Cannot read properties of null (reading 'addEventListener')

The more adaptive DateTimePicker instances the page contains, the more likely the error is to occur.

 

 

Unplanned
Last Updated: 11 Jul 2024 14:46 by Hang
When you right-click an item to open the Context Menu and select the "Delete" option, the confirmation dialog appears hidden behind the menu.
Unplanned
Last Updated: 10 Jul 2024 15:52 by Bruno

The Grid shows row skeletons in virtual scrolling scenarios when:

  • The Grid is scrolled half a row, but the Skip value in the Grid state is still zero.
  • The user filters while the Grid PageSize is greater than the total item count.

Test page: https://blazorrepl.telerik.com/mSkBaXkC50cEXmMB42

A possible workaround is to:

  1. Scroll the Grid to the top with JavaScript. This will trigger a new data request automatically.
  2. Reset the Grid state if the Grid is not scrolled, which will again trigger a new data request.

Example: https://blazorrepl.telerik.com/cSYrvEYW19htMCD934

Another possible solution is to disable the virtual scrolling at runtime if the total item count is too small: https://blazorrepl.telerik.com/mSOhvYuW47DaMk6c00

Unplanned
Last Updated: 10 Jul 2024 14:22 by ADMIN

We have a grid with a GridCheckboxColumn that we have configured through a '.unselectable-row' style so that certain elements cannot be selected (those elements with a padlock in the second column cannot be selected).

The grid works correctly in isolation, but when we add a TelerikLoaderContainer that is displayed during data loading process, the grid doesn't working properly: it is possible to select all the enabled elements of the grid using the button in the header of the checkbox column. However it is not possible to deselect them from the button in the header of the checkbox column when there is any unselectable element.

Here it is a link to REPL with a reproducible example: https://blazorrepl.telerik.com/GyYhYXPI24gIYgIJ03

To reproduce the problem, you sholud select all grid elements from the checkbox column header button and try to deselect them. You will not be able to deselect all the elements. 
Now comment the LoaderContainer component and repeat the test. You will see that now it is possible to deselect correctly all the elements.

How can we deselect all the elements from the header while keeping the loadercontainer?

Unplanned
Last Updated: 05 Jul 2024 06:18 by Christian
Hi,

The issue is that the tooltip position doesn't change when the user move the cursor between two elements with small proximity. 

The best example is Telerik's own Tooltip demo Blazor Components Demos and Examples - Telerik UI for Blazor. More often than not when moving between Karachi and Mumbay/Bombay tha tooltip doesn't shift position even though the text changes.
Unplanned
Last Updated: 03 Jul 2024 10:54 by ADMIN
Created by: Robert
Comments: 3
Category: ContextMenu
Type: Bug Report
4
 
Unplanned
Last Updated: 02 Jul 2024 07:52 by ADMIN

Hello, 

 

I use the scheduler component with grouping ressources on a timeline view. 

When there is only one ressource for the second group, there is no text showing on the view.

It works with 2 ressources.

I try over your demo and i have the same result.

https://blazorrepl.telerik.com/GyYAmBGE22N2CcIQ27

 

 

When I use 2 ressources it works.

Thank you

 

Unplanned
Last Updated: 02 Jul 2024 05:50 by ADMIN

Reproduction: https://blazorrepl.telerik.com/cHbFYUFq53Ext4Yt24.

Steps to reproduce:

  1. Open popup.
  2. Use the keyboard to navigate to the first item.
  3. Type "1", so the input value is "item11" (a value that matches an item from the list) -> ValueChanged is not fired.
  4. Type "1" again, so the input value is "item111" (this is a custom value not present in the list) -> ValueChanged is fired.
  5. Delete the last "1", so the input value is again "item11"(a value that matches an item from the list) -> ValueChanged is not fired.
Unplanned
Last Updated: 28 Jun 2024 11:20 by De

I have the following configuration:

Editor component in Grid EditorTemplate and the Grid editing mode is popup

Here is a REPL example https://blazorrepl.telerik.com/QeuUwsvb15sxbLuB04

The popup that opens when editing the Grid resizes when I type in the Editor

Steps to reproduce the issue:

1. Run the REPL example

2. Click the Edit button in the Grid

3. Resize the popup

4. Start to type something in the Editor

5. The popup resizes

Unplanned
Last Updated: 17 Jun 2024 08:20 by Max
In the csproj of my application, I have enabled support for nullable reference types (<Nullable>enable</Nullable>). If the filter operator is IsEqualTo the filtering will not match any items. 
Unplanned
Last Updated: 13 Jun 2024 08:15 by Andreas
Created by: Andreas
Comments: 0
Category: ContextMenu
Type: Bug Report
1

If I add a target element after initialization, the ContextMenu cannot be opened for it. It seems like the ContextMenu cannot work with dynamic targets.

Reproduction: https://blazorrepl.telerik.com/wyaKvxaM02UinTjJ35.

===

ADMIN EDIT

===

A possible workaround is to dispose and recreate the ContextMenu after adding the new element during runtime: https://blazorrepl.telerik.com/coaUvdYs153SKyiQ29.

Unplanned
Last Updated: 12 Jun 2024 10:47 by Nicholas
Created by: Nicholas
Comments: 0
Category: RadioGroup
Type: Bug Report
1
The RadioGroup's FocusAsync() method does not work. To reproduce, run this example and press the button: https://docs.telerik.com/blazor-ui/components/radiogroup/overview#radiogroup-reference-and-methods
Unplanned
Last Updated: 12 Jun 2024 10:28 by Jennifer

The Grid will cancel the insertion of a new item when:

  • the new item is not saved yet
  • the new item is expanded and its DetailTemplate is visible
  • the user changes the value of a column that has an editor template

Blazor REPL test page

===

In the meantime, a possible workaround is to hide the expand button for items, which are not added to the "permanent" Grid data yet. Here is how to do it with CSS:

.k-grid-add-row .k-hierarchy-cell .k-icon {
    display: none;
}
Unplanned
Last Updated: 12 Jun 2024 06:20 by ADMIN
Created by: Jesper
Comments: 4
Category: UI for Blazor
Type: Bug Report
4
I am using MS Playwright to create End2End tests. It worked fine when we used MudBlazor, but after we migrated to telerik I have run into a problem with the TelerikDropDownList.

It stops working if you open it too fast. It goes into a state where no matter what you do (Rebind/changing data bound values etc.), it will not open and show items.

It can be reproduced easily by calling .Open() in OnInitializedAsync()

I have reproduced it without MS Playwright in REPL, so you can easily debug it.

https://blazorrepl.telerik.com/QIOUYoPc57iQKy6702

If you uncomment the await Task.Delay(3000); the code will work.

Expected behavior:
It is ok that Open() does nothing while the control is initializing. It is not ok that just because you called Open() once, then you are forever stuck without being able to open it later, no matter how long you wait or what you do with the items.

I do not want to insert random Delays in my code either as I expect the TelerikDropDownList to not malfunction just because I open it too early.

I hope you can prioritize this as right now the DropDownList is not usable for us.
Unplanned
Last Updated: 10 Jun 2024 21:22 by ADMIN
Created by: Justin
Comments: 4
Category: UI for Blazor
Type: Bug Report
3

When SelectOnFocus="true" is enabled on the NumericTextBox control, and a format (e.g., Format="N1") is set, the SelectOnFocus functionality does not select all text if the decimal value has no trailing digits. For instance, with the value 76, the text is not selected on focus, but with the value 76.1, the text is selected correctly.


<TelerikNumericTextBox @bind-Value="@DecimalValue" Format="N1" SelectOnFocus="true"/>

@code {
    private decimal DecimalValue = 76;
}

 

Steps to Reproduce:

  1. Add a NumericTextBox control to a Blazor Server application.
  2. Set SelectOnFocus="true".
  3. Set a format, e.g., Format="N1".
  4. Enter a value such as 76 (with no trailing digits after the decimal point).
  5. Focus on the NumericTextBox.

Expected Behavior: The entire text (in this case, 76.0) should be selected when the NumericTextBox gains focus.

Actual Behavior: The text is not selected when the NumericTextBox gains focus if the value has no trailing digits after the decimal point (e.g., 76). However, if the value includes trailing digits (e.g., 76.1), the text is selected as expected.

Unplanned
Last Updated: 07 Jun 2024 10:23 by Constantinos Petridis
There are instances where numeric values from parameters are translated to string. One good example is the RowHeight parameter in the Grid. Make sure to use invariant culture to make sure that the string conversion will work for all cultures with different decimal separators. 
Unplanned
Last Updated: 06 Jun 2024 08:28 by ADMIN

The Editor is not showing its Value in the following scenario:

  • Using JSInterop in OnAfterRenderAsync
  • Setting the Editor Value in OnAfterRenderAsync and after the JSInterop call
  • Blazor Server app (seems to work in WebAssembly)

Possible workarounds are:

  • Set the Editor Value and call StateHasChanged() before using JSInterop in OnAfterRenderAsync, or
  • Add some small delay (for example, await Task.Delay(100); ) before using JSInterop.
1 2 3 4 5 6