Completed
Last Updated: 16 May 2024 20:05 by ADMIN
Austin
Created on: 13 May 2024 13:34
Category: TreeList
Type: Feature Request
1
Add the ability to determine the initial shift-click range selection starting row index

https://docs.telerik.com/blazor-ui/components/grid/selection/multiple#two-way-binding-of-selecteditems

Click the Preview button to load the example. Notice that the 3rd, 4th, and 5th rows are programmatically selected in the OnInitialized() method. Now, if you hold down the Shift key and click on the 6th row, instead of having the 3rd through 6th rows selected, we get the 1st through 6th row selected.

By design, the Shift + Click shortcut starts the selection from the last clicked row. If no click has taken place, the selection always starts from the first row. How to customize this?

For reference in Angular: https://www.telerik.com/kendo-angular-ui-develop/components/grid/api/SelectionDirective/

1 comment
ADMIN
Hristian Stefanov
Posted on: 16 May 2024 20:05

Hello,

Update on the item: Achieving the desired customization of the default selection behavior and determining the starting point for selection is achievable through the SelectedItemsChanged event alongside the OnRowClick event.

Here's a foundational example for guidance:

<TelerikGrid Data=@GridData
             SelectionMode="@GridSelectionMode.Multiple"
             SelectedItemsChanged="@((IEnumerable<Employee> employeeList) => OnSelect(employeeList))"
             SelectedItems="@SelectedEmployees"
             OnRowClick="@OnRowClickHandler"
             Pageable="true"
             Height="400px">
    <GridColumns>
        <GridCheckboxColumn />
        <GridColumn Field=@nameof(Employee.Name) />
        <GridColumn Field=@nameof(Employee.Team) Title="Team" />
    </GridColumns>
</TelerikGrid>

@code {
    private List<Employee> GridData { get; set; }
    private Employee firstPreselected { get; set; }
    private Employee lastPreselected { get; set; }
    private IEnumerable<Employee> SelectedEmployees { get; set; } = Enumerable.Empty<Employee>();
    private int clickedRowIndex { get; set; }
    private bool ShiftHold { get; set; }

    private void OnRowClickHandler(GridRowClickEventArgs args)
    {
        var model = args.Item as Employee;
        clickedRowIndex = model.EmployeeId;

        if (args.EventArgs is MouseEventArgs keyboardEventArgs)
        {
            if (keyboardEventArgs.ShiftKey)
            {
                ShiftHold = true;
            }
            else
            {
                ShiftHold = false;
            }
        }
    }

    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
            });
        }

        SelectedEmployees = GridData.Skip(3).Take(3).ToList();
        firstPreselected = GridData.ElementAt(3);
        lastPreselected = GridData.ElementAt(5);
    }

    protected void OnSelect(IEnumerable<Employee> employees)
    {
        if (ShiftHold && firstPreselected != null)
        {
            // Determine the new first and last preselected rows
            if (lastPreselected.EmployeeId < clickedRowIndex)
            {
                lastPreselected = GridData.ElementAt(clickedRowIndex);
            }
            else if (clickedRowIndex <= firstPreselected.EmployeeId)
            {
                firstPreselected = GridData.ElementAt(clickedRowIndex);
            }

            // Update selected rows based on the new preselected range
            SelectedEmployees = GridData.Where(emp => emp.EmployeeId >= firstPreselected.EmployeeId && emp.EmployeeId <= lastPreselected.EmployeeId);
        }
        else
        {
            // If Shift key is not held or there's no previous selection, update selected employees based on your business logic
            SelectedEmployees = employees;
            firstPreselected = null;
            lastPreselected = null;
        }
    }

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

Feel free to tailor it to your specific business requirements.

Having said this, I'm marking this item as "Completed".

Should there be any scenarios not fully addressed by the above approach, any feedback in the comments section would be greatly appreciated, allowing us to revise the item status.

Regards,
Hristian Stefanov
Progress Telerik

Stay tuned by visiting our public roadmap and feedback portal pages! Or perhaps, if you are new to our Telerik family, check out our getting started resources!