Unplanned
Last Updated: 05 Apr 2023 09:13 by ADMIN
Kenny
Created on: 12 May 2019 16:44
Category: Grid
Type: Feature Request
21
Specifying which field should have focus in grid editor.

It would be nice if I could specify an item in the inline editor (or any other for that matter) to get focus when the editor is activated.

Thanks,
Kenny

===

Telerik edit:

A possible workaround is:

  1. Define an <EditorTemplate> for the column(s) that can receive automatic focus in edit mode. The editor component inside it must have a @ref.
  2. (optional) Set a flag that points to the edit field to focus, if it will be dynamic.
  3. Check the flag value in OnAfterRenderAsync and focus the respective editor programmatically after a delay.

The example below also shows how to enter Grid edit mode programmatically and how to focus a specific field when editing with OnRowClick.

<TelerikGrid @ref="@GridInlineRef"
             Data="@GridInlineData"
             EditMode="@GridEditMode.Inline"
             OnAdd="@OnGridAddEdit"
             OnEdit="@OnGridAddEdit"
             OnCreate="@OnGridInlineCreate"
             OnUpdate="@OnGridInlineUpdate"
             OnRowClick="@OnGridRowClick">
    <GridToolBarTemplate>
        <GridCommandButton Command="Add">Add</GridCommandButton>
    </GridToolBarTemplate>
    <GridColumns>
        <GridColumn Field="@nameof(Product.Name)">
            <EditorTemplate>
                @{ var editItem = (Product)context; }
                <TelerikTextBox @ref="@NameTextBoxRef" @bind-Value="@editItem.Name" DebounceDelay="0" />
            </EditorTemplate>
        </GridColumn>
        <GridColumn Field="@nameof(Product.Price)">
            <EditorTemplate>
                @{ var editItem = (Product)context; }
                <TelerikNumericTextBox @ref="@PriceNumericTextBoxRef" @bind-Value="@editItem.Price" DebounceDelay="0" />
            </EditorTemplate>
        </GridColumn>
        <GridColumn Field="@nameof(Product.Stock)">
            <EditorTemplate>
                @{ var editItem = (Product)context; }
                <TelerikNumericTextBox @ref="@StockNumericTextBoxRef" @bind-Value="@editItem.Stock" DebounceDelay="0" />
            </EditorTemplate>
        </GridColumn>
        <GridCommandColumn>
            <GridCommandButton Command="Edit">Edit</GridCommandButton>
            <GridCommandButton Command="Save" ShowInEdit="true">Update</GridCommandButton>
            <GridCommandButton Command="Cancel" ShowInEdit="true">Cancel</GridCommandButton>
        </GridCommandColumn>
    </GridColumns>
</TelerikGrid>

@code {
    private TelerikGrid<Product>? GridInlineRef { get; set; }
    private TelerikTextBox? NameTextBoxRef { get; set; }
    private TelerikNumericTextBox<decimal?>? PriceNumericTextBoxRef { get; set; }
    private TelerikNumericTextBox<int>? StockNumericTextBoxRef { get; set; }
    private string EditFieldToFocus { get; set; } = string.Empty;

    private List<Product> GridInlineData { get; set; } = new List<Product>();

    private void OnGridAddEdit(GridCommandEventArgs args)
    {
        EditFieldToFocus = nameof(Product.Stock);
    }

    private async Task OnGridRowClick(GridRowClickEventArgs args)
    {
        EditFieldToFocus = args.Field;
        var itemToEdit = (Product)args.Item;

        args.ShouldRender = true;

        if (GridInlineRef != null)
        {
            var gridState = GridInlineRef.GetState();

            gridState.InsertedItem = null!;
            gridState.OriginalEditItem = itemToEdit;
            gridState.EditItem = itemToEdit.Clone();

            await GridInlineRef.SetStateAsync(gridState);
        }
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (!string.IsNullOrEmpty(EditFieldToFocus))
        {
            await Task.Delay(200);

            switch (EditFieldToFocus)
            {
                case nameof(Product.Name):
                    if (NameTextBoxRef != null)
                    {
                        await NameTextBoxRef.FocusAsync();
                    }
                    break;
                case nameof(Product.Price):
                    if (PriceNumericTextBoxRef != null)
                    {
                        await PriceNumericTextBoxRef.FocusAsync();
                    }
                    break;
                case nameof(Product.Stock):
                    if (StockNumericTextBoxRef != null)
                    {
                        await StockNumericTextBoxRef.FocusAsync();
                    }
                    break;
                default:
                    break;
            }

            EditFieldToFocus = string.Empty;
        }
    }

    #region Programmatic Inline Editing

    private async Task InlineAdd()
    {
        var gridState = GridInlineRef!.GetState();

        gridState.InsertedItem = new Product();
        gridState.InsertedItem.Name = "New value";
        gridState.OriginalEditItem = null!;
        gridState.EditItem = null!;

        await GridInlineRef.SetStateAsync(gridState);
    }

    private async Task InlineEdit()
    {
        if (GridInlineData.Any())
        {
            var gridState = GridInlineRef!.GetState();

            gridState.InsertedItem = null!;
            gridState.OriginalEditItem = GridInlineData.First();
            gridState.EditItem = GridInlineData.First().Clone();
            gridState.EditItem.Name = "Updated inline value";

            EditFieldToFocus = nameof(Product.Price);

            await GridInlineRef.SetStateAsync(gridState);
        }
    }

    private async Task InlineCancel()
    {
        var gridState = GridInlineRef!.GetState();

        gridState.InsertedItem = null!;
        gridState.OriginalEditItem = null!;
        gridState.EditItem = null!;

        await GridInlineRef.SetStateAsync(gridState);
    }

    private async Task InlineUpdate()
    {
        var gridState = GridInlineRef!.GetState();

        if (gridState.EditItem != null)
        {
            OnGridInlineUpdate(new GridCommandEventArgs()
            {
                Item = gridState.EditItem
            });
        }
        else if (gridState.InsertedItem != null)
        {
            OnGridInlineCreate(new GridCommandEventArgs()
            {
                Item = gridState.InsertedItem
            });
        }

        gridState.InsertedItem = null!;
        gridState.OriginalEditItem = null!;
        gridState.EditItem = null!;

        await GridInlineRef.SetStateAsync(gridState);
    }

    #endregion Programmatic Inline Editing

    #region Grid Inline Editing Handlers

    private void OnGridInlineUpdate(GridCommandEventArgs args)
    {
        var updatedItem = (Product)args.Item;
        var index = GridInlineData.FindIndex(i => i.Id == updatedItem.Id);
        if (index != -1)
        {
            GridInlineData[index] = updatedItem;
        }
    }

    private void OnGridInlineCreate(GridCommandEventArgs args)
    {
        var createdItem = (Product)args.Item;
        createdItem.Id = Guid.NewGuid();
        GridInlineData.Insert(0, createdItem);
    }

    #endregion Grid Inline Editing Handlers

    #region Data Generation and Model

    protected override void OnInitialized()
    {
        for (int i = 1; i <= 3; i++)
        {
            GridInlineData.Add(new Product()
            {
                Id = Guid.NewGuid(),
                Name = $"Product {i}",
                Price = Random.Shared.Next(1, 100) * 1.23m,
                Stock = (short)Random.Shared.Next(0, 1000)
            });
        }
    }

    public class Product
    {
        public Guid Id { get; set; }
        public string Name { get; set; } = string.Empty;
        public decimal? Price { get; set; }
        public int Stock { get; set; }
        public DateTime ReleaseDate { get; set; }
        public bool InProduction { get; set; }

        public Product Clone()
        {
            return new Product()
            {
                Id = Id,
                Name = Name,
                Price = Price,
                Stock = Stock,
                ReleaseDate = ReleaseDate,
                InProduction = InProduction
            };
        }
    }

    #endregion Data Generation and Model
}

 

9 comments
ADMIN
Dimo
Posted on: 05 Apr 2023 09:13

Hello Meindert,

Focusing the clicked cell in edit mode after OnRowClick is possible in version 5.1.0+ where we exposed the clicked cell in the OnRowClick event.

Otherwise, the only option is to use GridColumn Templates with @onclick for all editable columns.

Regards,
Dimo
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Meindert
Posted on: 29 Mar 2023 17:03

Hi,

We have to use InLine editing, because of bad performance InCell editing.

when make use of OnRowClick i like to have the focus on the specific editor where the mouse is pointing to. 

Is it possible to set the focus to a specific column editor programmatically without making use of EditorTemplate  ?

regards, Meindert

ADMIN
Marin Bratanov
Posted on: 02 Feb 2021 14:56

Hello Jason,

This happens in the InCell edit mode already, check it out in the demos: https://demos.telerik.com/blazor-ui/grid/editing-incell

That's what I meant with the grid having default focus for the first input now. With InCell editing there is only one inputin the current cell, with the other modes we focus the first input in the current row.

Regards,
Marin Bratanov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Jason
Posted on: 02 Feb 2021 14:03
In my opinion, the best implementation would be

"The focus should be placed in the cell where the user clicks".  So for example if the user clicks on the 3rd row and 4th column, the focus would immediately go into the cell at the 3rd row and 4th column.  This is intuitively where an end user would expect the focus to go.

Ideally this would be the default behavior and not require any coding to make it happen

ADMIN
Marin Bratanov
Posted on: 02 Feb 2021 13:03

Hi everyone,

The grid has been focusing the first available input by default for a while now.

That said, we still haven't seen examples of how one would expect that to be exposed for configuration. If you have any suggestions (or if you still need it, considering there is default focus and you can use the EditorTemplate to steal it), let us know.

 

Regards,
Marin Bratanov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

ADMIN
Marin Bratanov
Posted on: 21 Jul 2020 07:51

Hello Jason,

Here's the request for that behavior of the InCell editing: https://feedback.telerik.com/blazor/1454451-incell-editing-should-focus-the-first-input-in-an-opened-cell. Please Follow that (I've added your Vote on your behalf). It even has a workaround solution for now. You may also want to Vote for and Follow an actual spreadsheet component: https://feedback.telerik.com/blazor/1442151-spreadsheet-component

This item is about default focus in the other modes where you have more than one editor at a time - Inline and Popup editing. Could you share your thoughts on how you would expect control over that to be exposed for you?

Regards,
Marin Bratanov
Progress Telerik

Jason
Posted on: 20 Jul 2020 19:59

Related to this thread, it would be useful if a user could click on any cell in a row and immediately start typing (just like a normal spreadsheet).

For example in the current Grid implementation, if we use EditMode="@GridEditMode.InCell", the end user has to click twice to enter data.  Once to make the cell editable, and a second time to put the cursor inside of the cell, so that they can start typing.  It is wasteful energy for the user.

 

Kenny
Posted on: 19 Jun 2019 22:11
You could specify it as an attribute maybe.  Thinking about this further, if the first field in the grid would get focus, that would be much better than no field getting focus and would probably be sufficient for most situations.
ADMIN
Marin Bratanov
Posted on: 13 May 2019 04:34
Hi Kenny,

I moved this to the feedback portal: https://feedback.telerik.com/blazor/1408647-specifying-which-field-should-have-focus-in-grid-editor. That would be a nice addition to the grid capabilities, although I am not sure how that should be exposed through the grid API. Do you have any suggestions? Where would you look for such a feature and how would you expect it to be exposed?


Regards,
Marin Bratanov
Progress Telerik UI for Blazor