blazor-docs/knowledge-base/grid-edit-selected-item.md

6.4 KiB

title description type page_title slug position tags ticketid res_type
Edit the Selected Item From the ToolBar How to edit the Selected Item from the toolbar. how-to Edit the Selected Item From the ToolBar grid-edit-selected-item 1499119 kb

Environment

Product Grid for Blazor

Description

I would like to edit the selected item in the Grid when the GridSelectionMode is set to Single. The buttons for editing, deleting, saving and canceling the operation should be located in the GridToolBarTemplate rather than on each row.

Solution

You can use the regular [TelerikButton]({%slug components/button/overview%}) and the [Grid State]({%slug grid-state%}). Below you can see a detailed step by step explanation and a sample implementation.

Step by Step Explanation

  1. Create a new instance of the class you bound the Grid to in order to contain the information for the selected item.

  2. Use one-way data binding for the [SelectedItems]({%slug grid-selection-row%}#selected-rows) parameter and in the handler for the [SelectedItemsChanged]({%slug grid-selection-row%}#selecteditemschanged) populate the instance of the class created in the previous point.

  3. Enable the Edit and Delete buttons when the selected item is not null by using the Enabled parameter for the TelerikButton.

  4. Add a bool flag that would allow you to determine if the Grid is in Edit mode.

  5. Based on the flag created in the previous point conditionally show the Save and Cancel buttons.

  6. Toggle the value of the bool flag in the respective methods.

Sample Implementation

@*Edit the SelectedItem with buttons located in the GridToolBarTemplate*@

<TelerikGrid Data="@GridData"
             EditMode="@GridEditMode.Inline"
             SelectionMode="@GridSelectionMode.Single"
             SelectedItemsChanged="@((IEnumerable<Employee> employeeList) => OnSelect(employeeList))"
             SelectedItems="@SelectedItems"
             OnRowClick="@OnRowClickHandler"
             Pageable="true"
             Height="300px"
             @ref="@GridRef">
    <GridToolBarTemplate>
        <TelerikButton Enabled="@(SelectedEmployee != null)" OnClick="@EditEmployee">Edit</TelerikButton>
        <TelerikButton Enabled="@(SelectedEmployee != null)" OnClick="@DeleteEmployee">Delete</TelerikButton>
        @if (isInEdit)
        {
            <TelerikButton OnClick="@SaveEmployee">Save</TelerikButton>
            <TelerikButton OnClick="@CancelEdit">Cancel</TelerikButton>
        }
    </GridToolBarTemplate>
    <GridColumns>
        <GridColumn Field=@nameof(Employee.Name) />
        <GridColumn Field=@nameof(Employee.Team) Title="Team" />
    </GridColumns>
</TelerikGrid>

@code {
    public List<Employee> GridData { get; set; }
    public IEnumerable<Employee> SelectedItems { get; set; } = Enumerable.Empty<Employee>();
    public bool isInEdit { get; set; }
    TelerikGrid<Employee> GridRef { get; set; }

    public Employee SelectedEmployee { get; set; }

    async Task OnRowClickHandler(GridRowClickEventArgs args)
    {
        await CancelEdit();
    }

    protected void OnSelect(IEnumerable<Employee> employees)
    {
        SelectedEmployee = employees.FirstOrDefault();

        SelectedItems = new List<Employee> { SelectedEmployee };
    }

    async Task EditEmployee()
    {
        isInEdit = true;
        var currentState = GridRef.GetState();
        currentState.InsertedItem = null;

        Employee itemToEdit = Employee.GetClonedInstance(GridData.Where(itm => itm.EmployeeId == SelectedEmployee.EmployeeId).FirstOrDefault());

        currentState.OriginalEditItem = itemToEdit;

        await GridRef.SetStateAsync(currentState);
    }

    async Task SaveEmployee()
    {
        var currentState = GridRef.GetState();

        int indexOfEditedItem = GridData.IndexOf(SelectedEmployee);

        // perform database operation here

        GridData[indexOfEditedItem] = currentState.OriginalEditItem;

        currentState.OriginalEditItem = default;
        currentState.EditItem = default;

        await GridRef.SetStateAsync(currentState);

        isInEdit = false;
    }

    async Task DeleteEmployee()
    {
        GridData.Remove(SelectedEmployee); // call your database delete method here

        GridData = new List<Employee>(GridData); // changing the reference of the collection so that the Grid renders with the new data
    }

    async Task CancelEdit()
    {
        var currentState = GridRef.GetState();

        currentState.OriginalEditItem = default;
        currentState.EditItem = default;

        await GridRef.SetStateAsync(currentState);

        isInEdit = false;
    }

    protected override async Task OnInitializedAsync()
    {

        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; }
        
        // example of comparing stored items (from editing or selection)
        // with items from the current data source - IDs are used instead of the default references

        public override bool Equals(object obj)
        {
            if (obj is Employee)
            {
                return this.EmployeeId == (obj as Employee).EmployeeId;
            }
            return false;
        }


        // define constructors and a static method so we can deep clone instances
        // we use that to define the edited item - otherwise the references will point
        // to the item in the grid data sources and all changes will happen immediately on
        // the Data collection, and we don't want that - so we need a deep clone with its own reference
        // this is just one way to implement this, you can do it in a different way
        
        public Employee()
        {

        }

        public Employee(Employee itmToClone)
        {
            this.EmployeeId = itmToClone.EmployeeId;
            this.Name = itmToClone.Name;
            this.Team = itmToClone.Team;
        }

        public static Employee GetClonedInstance(Employee itmToClone)
        {
            return new Employee(itmToClone);
        }
    }
}