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
-
Create a new instance of the class you bound the Grid to in order to contain the information for the selected item.
-
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.
-
Enable the
Edit
andDelete
buttons when the selected item is notnull
by using theEnabled
parameter for theTelerikButton
. -
Add a
bool
flag that would allow you to determine if the Grid is in Edit mode. -
Based on the flag created in the previous point conditionally show the
Save
andCancel
buttons. -
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);
}
}
}