Unplanned
Last Updated: 17 Sep 2020 13:03 by ADMIN
Miriam
Created on: 14 Jul 2020 17:29
Category: Grid
Type: Feature Request
2
Focusout-Event in Grid

 Similar to the focusout-event of html-input...I want to do something after leaving a row.

----

ADMIN EDIT

Exposing similar keyboard events and actions from the grid will have the following major downsides:

  • First and foremost - Performance. Handling so many events will have a dramatic impact on the performance of the grid as each EventCallback re-renders the component twice. If we stop that re-rendering to keep the performance up to standards, you won't be able to change grid settings (such as selected items, edited row, etc.) and that will make the event next to useless.
  • Complexity - there is an incredible amount of information that such an event needs to carry in order to be useful - keys, modifier keys, current element (and obtaining element refs in blazor is another problem that causes performance issues), current model, adjacent models, whether the event happened on a data cell, header cell, or any of the dozens of possible elements in the grid. This list is also by no means exhaustive, there will be many more cases that I can't even thing of right now. This will make such events extremely complex and uncomfortable to use. An alternative would be exposing many events for many different elements, which will make the performance issue even worse.
  • Cost-benefit analysis - the majority of things are possible through templates right now. You can put in the desired template (editor, row, cell, header, whatever you need to capture events from) and add the desired handler to your own DOM element. Then, you can alter the grid, if needed, through its state. If you need the row data item - it is available in the templates related to the data rows. If you need adjacent rows models - you can get them from the sorted list of grid data when you use its OnRead event - you have the current row and you can get a previous/next one as needed from that list.

That said, I am keeping this item open (status "Unplanned") so we can still gather any feedback and its popularity and what the community thinks, and whether it will be a meaningful addition to the component.

----

5 comments
Miriam
Posted on: 15 Jul 2020 11:53
Thank you for your help! 
ADMIN
Marin Bratanov
Posted on: 15 Jul 2020 10:47

Hi Miriam,

The following snippet fires onfocusout when those inputs lose focus, and row click fires for the clicks on the rows (outside of the inputs, of course, the event needs to propagate to the grid in order to fire that event). I'm attaching also a short video that demonstrates the expected behavior.

<TelerikGrid Data=@GridData
             SelectionMode="@GridSelectionMode.Single"
             @bind-SelectedItems="@SelectedItems"
             Pageable="true"
             Height="400px" Navigable="true"
             OnRowClick="@OnRowClickHandler">
    <GridColumns>
        <GridColumn Field=@nameof(Employee.Name)>
            <Template>
                @{
                    <div class="text-right">
                        <input type="number" @onfocusout="@MyFocusOutHandler" />
                    </div>
                }
            </Template>
        </GridColumn>
        <GridColumn Field=@nameof(Employee.Team) Title="Team" />
    </GridColumns>
</TelerikGrid>


@code {
    async Task MyFocusOutHandler(FocusEventArgs e)
    {
        Console.WriteLine($"focus lost in the grid");
    }

    async Task OnRowClickHandler(GridRowClickEventArgs args)
    {
        var item = args.Item as Employee;

        Console.WriteLine(item.EmployeeId);
    }



    public List<Employee> GridData { get; set; }
    public IEnumerable<Employee> SelectedItems { get; set; } = Enumerable.Empty<Employee>();

    protected override void OnInitialized()
    {
        GridData = new List<Employee>();
        for (int i = 0; i < 15; i++)
        {
            GridData.Add(new Employee()
            {
                EmployeeId = i,
                Name = "Employee " + i.ToString(),
                Team = "Team " + i % 3
            });
        }

        // select Employee with ID 4
        SelectedItems = GridData.Where(item => item.EmployeeId == 4).ToList();
    }

    public class Employee
    {
        public int EmployeeId { get; set; }
        public string Name { get; set; }
        public string Team { get; set; }
    }
}

 

Regards,
Marin Bratanov
Progress Telerik

Attached Files:
Miriam
Posted on: 15 Jul 2020 09:03
Ok, now it works, but my OnRowClick is not triggered anymore that was working before.
Miriam
Posted on: 15 Jul 2020 08:56

 

Hi, unfortunately onfocusout is not triggered when I use it in a div. Just input works...

 

<GridColumn Field="@Name" Title="Name" Editable="true">
                            <Template>
                                @{
                                        <div class="text-right">
                                            <input type="number" @onfocusout="OnLostFocus" />
                                        </div>
                                    }
                                }
                            </Template>

</GridColumn>

ADMIN
Marin Bratanov
Posted on: 14 Jul 2020 17:32

While the grid is not as simple as an input, I am leaving this open for review so it can be considered.

In the meantime, you can capture the bubbled event on an element above the grid (note that it will fire for any focusout event under the grid - cells, pager, buttons, etc.)

<div @onfocusout="@MyFocusOutHandler">
    <TelerikGrid Data=@GridData
                    SelectionMode="@GridSelectionMode.Single"
                    @bind-SelectedItems="@SelectedItems"
                    Pageable="true"
                    Height="400px" Navigable="true">
        <GridColumns>
            <GridColumn Field=@nameof(Employee.Name) />
            <GridColumn Field=@nameof(Employee.Team) Title="Team" />
        </GridColumns>
    </TelerikGrid>
</div>

@code {
    async Task MyFocusOutHandler(FocusEventArgs e)
    {
        Console.WriteLine($"focus lost in the grid");
    }


    public List<Employee> GridData { get; set; }
    public IEnumerable<Employee> SelectedItems { get; set; } = Enumerable.Empty<Employee>();

    protected override void OnInitialized()
    {
        GridData = new List<Employee>();
        for (int i = 0; i < 15; i++)
        {
            GridData.Add(new Employee()
            {
                EmployeeId = i,
                Name = "Employee " + i.ToString(),
                Team = "Team " + i % 3
            });
        }

        // select Employee with ID 4
        SelectedItems = GridData.Where(item => item.EmployeeId == 4).ToList();
    }

    public class Employee
    {
        public int EmployeeId { get; set; }
        public string Name { get; set; }
        public string Team { get; set; }
    }
}

 

Regards,
Marin Bratanov
Progress Telerik