New to Telerik UI for Blazor? Download free 30-day trial

Edit Grid CheckBoxes with Single Click

Environment

Product Grid for Blazor,
TreeList for Blazor

Description

To edit a checkbox in a Grid cell, users need to click once to put the row (or cell) in edit mode. They they need another click to change the checkbox value. How to do this with only one click?

How to update boolean values in the Grid with no edit mode?

How to toggle checkboxes in the Grid directly without using the built-in editing feature?

The Grid is not editable, but it should allow users to check and uncheck check box values.

How to use a single click on Grid checkboxes to set the opposite value?

How to get a checkbox value in the Grid for update action on button click?

Solution

  1. Define a <GridColumn> with a Field that points to a bool property.
  2. Set Editable="false" for that column, if the Grid EditMode is Incell.
  3. Define a column cell template (<Template>) for the column. Place a TelerikCheckBox component inside.
  4. If the updated CheckBox values require real-time synchronization with a remote data source, then use the CheckBox OnChange or ValueChanged event. In this case, ValueChanged will also require a ValueExpression.
@using Telerik.DataSource.Extensions

<TelerikGrid OnRead="@OnGridRead"
             TItem="@User"
             EditMode="@GridEditMode.Incell"
             OnUpdate="@OnGridUpdate">
    <GridColumns>
        <GridColumn Field="@nameof(User.Name)" />
        <GridColumn Field="@nameof(User.Admin)" Title="No Template" />
        <GridColumn Field="@nameof(User.Admin)" Title="Template - ValueChanged" Editable="false">
            <Template>
                @{
                    var user = (User)context;
                }
                <TelerikCheckBox Value="@user.Admin"
                                 ValueExpression="@( () => user.Admin )"
                                 ValueChanged="@( (bool newValue) => OnAdminValueChanged(newValue, user) )" />
            </Template>
        </GridColumn>
        <GridColumn Field="@nameof(User.Admin)" Title="Template - OnChange" Editable="false">
            <Template>
                @{
                    var user = (User)context;
                }
                <TelerikCheckBox @bind-Value="@user.Admin"
                                 OnChange="@( (object newValue) => OnAdminChange((bool)newValue, user) )" />
            </Template>
        </GridColumn>
    </GridColumns>
</TelerikGrid>

@code {
    private List<User> Users { get; set; }

    private async Task OnAdminValueChanged(bool newValue, User user)
    {
        // Update the local value in the Grid.
        // Required when using a ValueChanged handler.
        user.Admin = newValue;

        // Update the remote data source.
        await TriggerGridUpdate(user);
    }

    private async Task OnAdminChange(bool newValue, User user)
    {
        // Update the remote data source.
        await TriggerGridUpdate(user);
    }

    private async Task TriggerGridUpdate(User user)
    {
        // Here we simulate an actual Grid update.
        // The goal is to reuse the existing OnUpdate event handler.
        // However, such OnUpdate simulation is not required.
        // Instead, you can call the remote data service directly.
        await OnGridUpdate(new GridCommandEventArgs()
        {
            Field = nameof(User.Admin),
            IsNew = false,
            Item = user,
            Value = user.Admin
        });
    }

    private async Task OnGridUpdate(GridCommandEventArgs args)
    {
        // simulate network delay
        await Task.Delay(100);

        var user = (User)args.Item;
        var index = Users.FindIndex(x => x.Id == user.Id);

        if (index >= 0)
        {
            Users[index] = user;
        }
    }

    private async Task OnGridRead(GridReadEventArgs args)
    {
        // simulate network delay
        await Task.Delay(100);

        var result = Users.ToDataSourceResult(args.Request);

        args.Data = result.Data;
        args.Total = result.Total;
    }

    protected override void OnInitialized()
    {
        Users = new List<User>();

        for (int i = 1; i <= 3; i++)
        {
            Users.Add(new User()
            {
                Id = i,
                Name = "User Name " + i,
                Admin = i % 2 == 0
            });
        }

        base.OnInitialized();
    }

    public class User
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public bool Admin { get; set; }
    }
}

Notes

The built-in Grid editing feature creates a copy of the original data item while a row is in edit mode. As a result, CheckBox value changes in the non-templated column above are applied to the template columns after the OnUpdate handler executes.

See Also

In this article