Completed
Last Updated: 17 May 2024 13:11 by ADMIN
Release 2024 Q2 (May)
Jeffrey
Created on: 08 Nov 2019 04:16
Category: Grid
Type: Feature Request
27
Ability to enable/disable checkbox in checkbox column to allow/prevent selection of the row
Subject says it all.  Would like the ability to selectively enable/disable a single checkbox in a checkbox column.
5 comments
ADMIN
Tsvetomir
Posted on: 17 May 2024 13:11

Hello everyone,

Due to a lack of shared examples and scenarios about the discussed built-in functionality, we decided to close the item as completed with the following knowledge base article that uses the approach of my colleague Yanislav: Allow or Prevent Selection of Certain Rows in the Grid

Regards,
Tsvetomir
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!
ADMIN
Yanislav
Posted on: 16 Apr 2024 07:16

Hello Everyone,

Thank you for your feedback on our product!

I'd like to understand more about your use cases for this feature and why it is needed. While we recognize its validity, the described requirement can typically be achieved without introducing additional built-in functionality.

Essentially, you can listen for the SelectedItemsChanged event of the Grid and prevent the selection of items conditionally.

<TelerikGrid Data="@MyData"
             SelectedItems="@SelectedItems"
             SelectedItemsChanged="@((IEnumerable<SampleData> items) => SelectedItemsChanged(items))"

...
    public void SelectedItemsChanged(IEnumerable<SampleData> items)
    {
        SelectedItems = items.Where(x => x.Selectable).ToList();
    }

As for the checkboxes, you can disable them by conditionally applying classes to the rows in which the checkboxes should be disabled.

<TelerikGrid Data="@MyData"
...
             OnRowRender="@OnRowRenderHandler">

    void OnRowRenderHandler(GridRowRenderEventArgs args)
    {
        var item = args.Item as SampleData;

        if (!item.Selectable)
        {
            args.Class = "unselectable-row";
        }
    }

This way, you can add a CSS rule that targets those checkboxes within the rows with the applied custom class and disable them.

<style>
    .unselectable-row > td .k-checkbox {
        opacity: 0.5;
        pointer-events: none;
    }
</style>

Here is a REPL example that demonstrates this approachhttps://blazorrepl.telerik.com/QoOIbJPG46vdHcQw12

Would you mind reviewing the example and sharing some scenarios (if there are any) where having such built-in functionality would be particularly useful, and in which the approach suggested above would not suffice?

This information will help us determine whether or not to include this feature in our API. If it turns out that this functionality can be achieved with CSS, we may decide not to include it to preserve the API clear. However, we'd still like to hear more about your specific needs before making a final decision.

Thank you for taking the time to share your thoughts with us.

Regards,


Yanislav
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!
ADMIN
Marin Bratanov
Posted on: 15 Apr 2020 05:38

You may also find interesting this idea: https://feedback.telerik.com/blazor/1454469-select-rows-only-with-checkboxes-clicking-the-rows-to-not-affect-selection

 

Regards,
Marin Bratanov
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
Jeffrey
Posted on: 08 Nov 2019 13:54

Marin,

Thanks for the quick and detailed response

ADMIN
Marin Bratanov
Posted on: 08 Nov 2019 09:02

Hi Jeffrey,

This post will list three ideas I can offer for this, and it is a bit long. I have ordered them from least to most amount of code you'd need to write (which has an inverse relationship to the flexibility you can achieve).

For the time being you can handle the selection change event and loop the selected items, and take only those you want (which is not ideal, of course): https://docs.telerik.com/blazor-ui/components/grid/selection/multiple#selecteditemschanged-event.

Another option (which, in my opinion has slightly worse UX) is to use two-way binding for the selected items and only store the ones you want. The issue is that the checkbox will stay toggled even if the item does not get selected:

 

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

@if (SelectedItems != null)
{
    <ul>
        @foreach (Employee employee in SelectedItems)
        {
            <li>
                @employee.Name
            </li>
        }
    </ul>
}

@code {
    public List<Employee> GridData { get; set; }
    IEnumerable<Employee> _selItems { get; set; }
    public IEnumerable<Employee> SelectedItems { 
        get 
        {
            return _selItems;
        } 
        set
        { 
            _selItems = value.Where(empl => empl.EmployeeId != 2);
        }
    }

    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 3 through 5
        SelectedItems = GridData.Skip(2).Take(3).ToList();
    }

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

A third option is to implement the selection with your own code and disabled checkboxes in the column template, something like this:

 

<TelerikGrid Data=@GridData
             SelectionMode="GridSelectionMode.None"
             Pageable="true"
             Height="400px">
    <GridColumns>
        <GridColumn Field="@(nameof(Employee.EmployeeId))">
            <Template>
                @{ 
                    Employee empl = context as Employee;
                    <input type="checkbox" id="@("selCb_" + empl.EmployeeId)" class="k-checkbox" checked="@empl.Selected"
                          @onchange="@(e => SelectEmployee(empl, e))" @key="@empl.EmployeeId" disabled="@( empl.EmployeeId == 3 )" />
                    <label class="k-checkbox-label" for="@("selCb_" + empl.EmployeeId)">Select @empl.EmployeeId</label>
                }
            </Template>
        </GridColumn>
        <GridColumn Field=@nameof(Employee.Name) />
        <GridColumn Field=@nameof(Employee.Team) Title="Team" />
    </GridColumns>
</TelerikGrid>

@if (SelectedItems.Count > 0)
{
    <ul>
        @foreach (Employee employee in SelectedItems)
        {
            <li>
                @employee.Name
            </li>
        }
    </ul>
}

@code {
    public List<Employee> GridData { get; set; }
    public List<Employee> SelectedItems { get; set; } = new List<Employee>();

    void SelectEmployee(Employee emplToSelect, ChangeEventArgs e)
    {
        bool isSelected = bool.Parse(e.Value.ToString());

        emplToSelect.Selected = isSelected;
        if(isSelected)
        {
            SelectedItems.Add(emplToSelect);
        }
        else
        {
            SelectedItems.Remove(emplToSelect);
        }
    }

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

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

 

 

Regards,
Marin Bratanov
Progress Telerik

 UI for Blazor