Completed
Last Updated: 05 Aug 2024 13:31 by ADMIN
Release 6.1.0
Roy
Created on: 29 Dec 2020 16:52
Category: Grid
Type: Bug Report
10
When you use the checkbox to select a row, you cannot clear it if you cancel the SelectedItemsChanged event

---

ADMIN EDIT

Here is a workaround - using a bit of JS to clear the checked state of the checkbox element when you clear the SelectedItems collection:

At the end of this post you can find attached a sample project that showcases a more complex scenario where you may want to keep some rows selected but cancel the selection of others (in that sample, only one row with a given ItemType can be selected). It shows how you can get the index in the rendering of a particular row to use for a slightly modified version of the JS function.

@inject IJSRuntime _js

@* Move JavaScript code to a separate JS file in production *@
<script suppress-error="BL9992">
    function uncheckGrid() {
        var checkboxes = document.querySelectorAll(".no-select .k-grid-checkbox");
        for (var i = 0; i < checkboxes.length; i++) {
            checkboxes[i].checked = false;
        }
    }
</script>

<style>
    .no-select {
        cursor: not-allowed;
    }

    .no-select .k-checkbox {
        pointer-events: none;
    }
</style>

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

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

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

    private IEnumerable<Employee> SelectedEmployees { get; set; } = new List<Employee>();

    private void OnGridCellRender(GridCellRenderEventArgs args)
    {
        var product = (Employee)args.Item;
        if (!product.Active)
        {
            args.Class = "no-select";
        }
    }

    protected void OnSelect(IEnumerable<Employee> newSelected)
    {
        var validItemsToSelect = newSelected.Where(x => x.Active);
        SelectedEmployees = validItemsToSelect;
        if (validItemsToSelect.Count() < newSelected.Count())
        {
            _js.InvokeVoidAsync("uncheckGrid");
        }
    }

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

    public class Employee
    {
        public int EmployeeId { get; set; }
        public string Name { get; set; } = string.Empty;
        public string Team { get; set; } = string.Empty;
        public bool Active { get; set; }
    }
}

2 comments
ADMIN
Dimo
Posted on: 12 Aug 2022 06:42

Hi all,

This task is yet to be implemented. When we plan it, the status will change and you will get a notification. In the meantime, here are a couple of additional workarounds that do not require JavaScript and are likely more convenient to use:

Runnable REPL test page

Same code follows:

<p>Option 1 (recommended): Hide checkboxes of unselectable rows (non-active products):</p>

<TelerikGrid Data="@GridData"
             TItem="@Product"
             SelectionMode="@GridSelectionMode.Multiple"
             SelectedItems="@GridSelectedItems"
             SelectedItemsChanged="@OnGridSelectedItemsChanged1">
    <GridColumns>
        <GridCheckboxColumn OnCellRender="@OnCheckBoxCellRender1" />
        <GridColumn Field="@nameof(Product.Name)" Title="Product Name" />
        <GridColumn Field="@nameof(Product.Active)" />
    </GridColumns>
</TelerikGrid>

<style>
    .no-selection .k-grid-checkbox {
        visibility: hidden;
    }
</style>

<p>Option 2: Revert selection of unselectable rows (non-active products):</p>

<TelerikGrid Data="@GridData"
             TItem="@Product"
             SelectionMode="@GridSelectionMode.Multiple"
             SelectedItems="@GridSelectedItems"
             SelectedItemsChanged="@OnGridSelectedItemsChanged2">
    <GridColumns>
        <GridCheckboxColumn />
        <GridColumn Field="@nameof(Product.Name)" Title="Product Name" />
        <GridColumn Field="@nameof(Product.Active)" />
    </GridColumns>
</TelerikGrid>

<p> GridSelectedItems Count: @GridSelectedItems.Count().ToString() </p>

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

    void OnCheckBoxCellRender1(GridCellRenderEventArgs args)
    {
        var item = args.Item as Product;
        if (!item.Active)
        {
            args.Class = "no-selection";
        }
    }

    void OnGridSelectedItemsChanged1(IEnumerable<Product> newSelectedItems)
    {
        GridSelectedItems = newSelectedItems.Except(newSelectedItems.Where(x => !x.Active)).ToList();
    }

    void OnGridSelectedItemsChanged2(IEnumerable<Product> newSelectedItems)
    {
        GridSelectedItems = newSelectedItems;

        var exceptDisabled = newSelectedItems.Except(newSelectedItems.Where(x => !x.Active)).ToList();
        if (exceptDisabled.Count != GridSelectedItems.Count())
        {
            GridSelectedItemsTemp = newSelectedItems.Except(newSelectedItems.Where(x => !x.Active)).ToList();
        }
    }

    protected override void OnAfterRender(bool firstRender)
    {
        // for Grid 2 only
        if (GridSelectedItemsTemp != null)
        {
            GridSelectedItems = GridSelectedItemsTemp.ToList();
            GridSelectedItemsTemp = null;
            StateHasChanged();
        }

        base.OnAfterRender(firstRender);
    }

    protected override void OnInitialized()
    {
        GridData = new List<Product>();
        var rnd = new Random();

        for (int i = 1; i <= 5; i++)
        {
            GridData.Add(new Product()
            {
                Id = i,
                Name = "Product " + i,
                Active = i % 2 == 0
            });
        }
    }

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

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/.

Gert
Posted on: 11 Aug 2022 06:58
Any news on this? I would highly appreciate.