New to Telerik UI for BlazorStart a free 30-day trial

Cannot Open a DropDownList inside a Navigable Grid

Environment

Product Grid for Blazor,
TreeList for Blazor

Description

Dropdown components do not open inside a Grid column <Template> when the Grid has Navigable="true".

Cause

When the Grid keyboard navigation is enabled, the table cells automatically gain focus when a cell is clicked. If the cell contains a focusable element, this element may lose focus unexpectedly on click.

Solution

Normally, editor components belong to <EditorTemplate>s, but this article assumes that editor templates are not an option. Thus, other possible options include:

  • If data operations like sorting and filtering are not necessary for the affected columns, place buttons or dropdown components like ComboBox or DropDownList inside a Grid Command Column instead. Grid command columns do not gain focus automatically when a nested focusable element is clicked.
  • If data operations for the affected columns are required, then use a container with @onclick:stopPropagation inside the <GridColumn> template. This will prevent the Grid from knowing about the clicks, so the data cell will not gain focus automatically.

Using dropdowns, buttons and other focusable elements inside a navigable Grid

<TelerikGrid Data="@GridData" Navigable="true">
    <GridColumns>
        <GridColumn Field="@nameof(Product.Name)" Title="Cells will steal focus on click" HeaderClass="warning">
            <Template>
                @{ var dataItem = (Product)context; }
                <span class="template-span">
                    <TelerikButton OnClick="@( () => OnButtonClick(dataItem.Id) )">@dataItem.Name</TelerikButton>
                    <TelerikDropDownList Data="@DropDownListData" @bind-Value="@dataItem.Active" />
                </span>
            </Template>
        </GridColumn>
        <GridColumn Field="@nameof(Product.Name)" Title="Template with stopPropagation" HeaderClass="success">
            <Template>
                @{ var dataItem = (Product)context; }
                <span @onclick:stopPropagation class="template-span">
                    <TelerikButton OnClick="@( () => OnButtonClick(dataItem.Id) )">@dataItem.Name</TelerikButton>
                    <TelerikDropDownList Data="@DropDownListData" @bind-Value="@dataItem.Active" />
                </span>
            </Template>
        </GridColumn>
        <GridCommandColumn Title="Command Column" HeaderClass="success">
            @{ var dataItem = (Product)context; }
            <span class="template-span">
                <TelerikButton OnClick="@( () => OnButtonClick(dataItem.Id) )">@dataItem.Name</TelerikButton>
                <TelerikDropDownList Data="@DropDownListData" @bind-Value="@dataItem.Active" />
            </span>
        </GridCommandColumn>
    </GridColumns>
</TelerikGrid>

<style>
    .template-span {
        display: flex;
        gap: 1em;
        padding: .3em;
    }

    .warning {
        background-color: var(--kendo-color-warning);
    }

    .success {
        background-color: var(--kendo-color-success);
        color: var(--kendo-color-on-success);
    }
</style>

@code {
    List<Product> GridData { get; set; } = new();

    List<bool> DropDownListData { get; set; } = new List<bool>() { true, false };

    private void OnButtonClick(int id)
    {
        Console.WriteLine($"Button click on data item {id}");
    }

    protected override void OnInitialized()
    {
        for (int i = 1; i <= 3; i++)
        {
            GridData.Add(new Product()
            {
                Id = i,
                Name = $"Name {i}",
                Active = i % 3 == 0
            });
        }
    }

    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; } = string.Empty;
        public bool Active { get; set; }
    }
}

See Also