ASP.NET Core Blazor | DataGrid Editing


asp.net core blazor datagrid editing

In our previous video we discussed how to perform CRUD operations using Blazor DataGrid. It's a powerful and easy to use component. Out of the box it provides several customizations, so we can very easily and quickly implement most of the real world application use cases.

Blazor DataGrid Edit Modes

Three Edit Modes are supported.

  1. Normal
  2. Dialog
  3. Batch

Normal

  • Default edit mode.
  • When the row is in normal edit mode, we can change the cell values and then save the data to the data source.
  • To explicitly specify the edit mode, set Mode property on <GridEditSettings> component.
<SfGrid @ref="employeeGrid" DataSource="@Employees" AllowPaging="true"
        Toolbar="@(new List<string>() { "Add", "Edit", "Update", "Delete", "Cancel" })">
    <GridEditSettings Mode="EditMode.Normal" AllowAdding="true" AllowEditing="true" AllowDeleting="true">
    </GridEditSettings>
    <GridPageSettings PageSize="5"></GridPageSettings>
    <GridEvents OnActionBegin="ActionBeginHandler" TValue="Employee"></GridEvents>
    <GridColumns>
        <GridColumn AllowAdding="false" IsPrimaryKey="true" Field=@nameof(Employee.EmployeeId) 
                    HeaderText="ID" Width="60px"></GridColumn>
        <GridColumn Field=@nameof(Employee.FirstName) HeaderText="First Name"></GridColumn>
        <GridColumn Field=@nameof(Employee.LastName) HeaderText=" Last Name"></GridColumn>
        <GridColumn Field=@nameof(Employee.DateOfBrith) Format="d" HeaderText="Date of Birth"></GridColumn>
        <GridColumn Field="Department.DepartmentName" EditType="EditType.DropDownEdit" 
                    HeaderText="Department" Width="140px">
            <EditTemplate>
                <SfDropDownList DataSource="@Departments" TItem="Department" TValue="int"
                                @bind-Value="@((context as Employee).DepartmentId)">
                    <DropDownListFieldSettings Text="DepartmentName" Value="DepartmentId">
                    </DropDownListFieldSettings>
                </SfDropDownList>
            </EditTemplate>
        </GridColumn>
        <GridColumn Field=@nameof(Employee.Gender) HeaderText="Gender" Width="140px">
            <EditTemplate>
                <SfDropDownList DataSource="@GenderEnumValues" TItem="string" TValue="Gender"
                                @bind-Value="@((context as Employee).Gender)">
                </SfDropDownList>
            </EditTemplate>
        </GridColumn>
        <GridColumn Field=@nameof(Employee.Email) HeaderText="Email"></GridColumn>
    </GridColumns>
</SfGrid>

Dialog

As the name implies, in dialog edit mode, row data is presented in a dialog box, when we try to add or edit a row.

Set Mode property on <GridEditSettings> component to EditMode.Dialog.

syncfusion datagrid editing

To customize

  • Dialog Header - Use <HeaderTemplate>
  • Dialog Footer - Use <FooterTemplate>
  • Specific <GridColumn> - Use <EditTemplate>

syncfusion blazor datagrid edit

@page "/gridedit"
@using Syncfusion.Blazor.Grids
@using Syncfusion.Blazor.DropDowns
@using Syncfusion.Blazor.Buttons

<div style="width:850px">
    <SfGrid @ref="employeeGrid" DataSource="@Employees" AllowPaging="true"
            Toolbar="@(new List<string>() { "Add", "Edit", "Update", "Delete", "Cancel" })">
        <GridEditSettings Mode="EditMode.Dialog" AllowAdding="true" AllowEditing="true" AllowDeleting="true">
            <HeaderTemplate>
                <span>@GetDialogHeader(context as Employee)</span>
            </HeaderTemplate>
            <FooterTemplate>
                <SfButton OnClick="@Save" IsPrimary="true">@FooterSaveButtonText</SfButton>
                <SfButton OnClick="@Cancel">Cancel</SfButton>
            </FooterTemplate>
        </GridEditSettings>
        <GridPageSettings PageSize="5"></GridPageSettings>
        <GridEvents OnActionBegin="ActionBeginHandler" TValue="Employee"></GridEvents>
        <GridColumns>
            <GridColumn AllowAdding="false" IsPrimaryKey="true" Field=@nameof(Employee.EmployeeId)
                        HeaderText="ID" Width="60px"></GridColumn>
            <GridColumn Field=@nameof(Employee.FirstName) HeaderText="First Name"></GridColumn>
            <GridColumn Field=@nameof(Employee.LastName) HeaderText=" Last Name"></GridColumn>
            <GridColumn Field=@nameof(Employee.DateOfBrith) Format="d" HeaderText="Date of Birth"></GridColumn>
            <GridColumn Field="Department.DepartmentName" EditType="EditType.DropDownEdit"
                        HeaderText="Department" Width="140px">
                <EditTemplate>
                    <span>Department</span>
                    <SfDropDownList DataSource="@Departments" TItem="Department" TValue="int"
                                    @bind-Value="@((context as Employee).DepartmentId)">
                        <DropDownListFieldSettings Text="DepartmentName" Value="DepartmentId">
                        </DropDownListFieldSettings>
                    </SfDropDownList>
                </EditTemplate>
            </GridColumn>
            <GridColumn Field=@nameof(Employee.Gender) HeaderText="Gender" Width="140px">
                <EditTemplate>
                    <span>Gender</span>
                    <SfDropDownList DataSource="@GenderEnumValues" TItem="string" TValue="Gender"
                                    @bind-Value="@((context as Employee).Gender)">
                    </SfDropDownList>
                </EditTemplate>
            </GridColumn>
            <GridColumn Field=@nameof(Employee.Email) HeaderText="Email"></GridColumn>
        </GridColumns>
    </SfGrid>
</div>

@code{

    public List<Employee> Employees { get; set; }

    public List<Department> Departments { get; set; }

    public SfGrid<Employee> employeeGrid { get; set; }

    public string FooterSaveButtonText { get; set; }

    public string[] GenderEnumValues { get; set; } = Enum.GetNames(typeof(Gender));

    [Inject]
    public IEmployeeService EmployeeService { get; set; }

    [Inject]
    public IDepartmentService DepartmentService { get; set; }

    protected override async Task OnInitializedAsync()
    {
        Employees = (await EmployeeService.GetAllEmployees()).ToList();
        Departments = (await DepartmentService.GetAllDepartments()).ToList();
    }

    public string GetDialogHeader(Employee employee)
    {
        if (employee.EmployeeId == 0)
        {
            FooterSaveButtonText = "Add";
            return "Add New Employee";
        }
        else
        {
            FooterSaveButtonText = "Update";
            return $"Edit {employee.FirstName} Details";
        }
    }

    public async Task Cancel()
    {
        await employeeGrid.CloseEdit();
    }
    public async Task Save()
    {
        await employeeGrid.EndEdit();
    }

    public async void ActionBeginHandler(ActionEventArgs<Employee> Args)
    {
        if (Args.RequestType.Equals(Syncfusion.Blazor.Grids.Action.Save))
        {
            if (Args.Action == "Add")
            {
                await EmployeeService.AddEmployee(Args.Data);
                Employees = (await EmployeeService.GetAllEmployees()).ToList();
                employeeGrid.Refresh();
            }
            else
            {
                await EmployeeService.UpdateEmployee(Args.Data);
            }
        }
        if (Args.RequestType.Equals(Syncfusion.Blazor.Grids.Action.Delete))
        {
            await EmployeeService.DeleteEmployee(Args.Data.EmployeeId);
        }
    }
}

Batch

  • With Batch mode, we can perform multiple inserts, updates and deletes in the datagrid.
  • These changes are not saved until the Update button is clicked.
  • You can continue editing the next row or previous row from the current record in batch mode by enabling EditSettings.AllowNextRowEdit to true.
  • Pressing TAB from the last cell of the current row allows editing the next row and Pressing SHIFT + TAB from the first cell of the current row allows editing the previous row.
@page "/gridedit"
@using Syncfusion.Blazor.Grids
@using Syncfusion.Blazor.DropDowns
@using Syncfusion.Blazor.Buttons

<div style="width:850px">
    <SfGrid @ref="employeeGrid" DataSource="@Employees" AllowPaging="true"
            Toolbar="@(new List<string>() { "Add", "Edit", "Update", "Delete", "Cancel" })">
        <GridEditSettings Mode="EditMode.Batch" AllowAdding="true" AllowEditing="true" AllowDeleting="true">
            <HeaderTemplate>
                <span>@GetDialogHeader(context as Employee)</span>
            </HeaderTemplate>
            <FooterTemplate>
                <SfButton OnClick="@Save" IsPrimary="true">@FooterSaveButtonText</SfButton>
                <SfButton OnClick="@Cancel">Cancel</SfButton>
            </FooterTemplate>
        </GridEditSettings>
        <GridPageSettings PageSize="5"></GridPageSettings>
        <GridEvents TValue="Employee" OnBatchSave="BatchSaveHandler"></GridEvents>
        <GridColumns>
            <GridColumn AllowAdding="false" IsPrimaryKey="true" Field=@nameof(Employee.EmployeeId)
                        HeaderText="ID" Width="60px"></GridColumn>
            <GridColumn Field=@nameof(Employee.FirstName) HeaderText="First Name"></GridColumn>
            <GridColumn Field=@nameof(Employee.LastName) HeaderText=" Last Name"></GridColumn>
            <GridColumn Field=@nameof(Employee.DateOfBrith) Format="d" HeaderText="Date of Birth"></GridColumn>
            <GridColumn Field=@nameof(Employee.DepartmentId) HeaderText="Department" Width="140px">
                <Template>
                    <span>
                        @GetDepartmentNameById((context as Employee).DepartmentId)
                    </span>
                </Template>
                <EditTemplate>
                    <span>Department</span>
                    <SfDropDownList DataSource="@Departments" TItem="Department" TValue="int"
                                    @bind-Value="@((context as Employee).DepartmentId)">
                        <DropDownListFieldSettings Text="DepartmentName" Value="DepartmentId">
                        </DropDownListFieldSettings>
                    </SfDropDownList>
                </EditTemplate>
            </GridColumn>
            <GridColumn Field=@nameof(Employee.Gender) HeaderText="Gender" Width="140px">
                <EditTemplate>
                    <span>Gender</span>
                    <SfDropDownList DataSource="@GenderEnumValues" TItem="string" TValue="Gender"
                                    @bind-Value="@((context as Employee).Gender)">
                    </SfDropDownList>
                </EditTemplate>
            </GridColumn>
            <GridColumn Field=@nameof(Employee.Email) HeaderText="Email"></GridColumn>
        </GridColumns>
    </SfGrid>
</div>

@code{

    public List<Employee> Employees { get; set; }

    public List<Department> Departments { get; set; }

    public SfGrid<Employee> employeeGrid { get; set; }

    public string FooterSaveButtonText { get; set; }

    public string[] GenderEnumValues { get; set; } = Enum.GetNames(typeof(Gender));

    [Inject]
    public IEmployeeService EmployeeService { get; set; }

    [Inject]
    public IDepartmentService DepartmentService { get; set; }

    protected override async Task OnInitializedAsync()
    {
        Employees = (await EmployeeService.GetAllEmployees()).ToList();
        Departments = (await DepartmentService.GetAllDepartments()).ToList();
    }

    public string GetDepartmentNameById(int id)
    {
        if (id == 0)
        {
            return null;
        }
        else
        {
            return Departments.FirstOrDefault(d => d.DepartmentId == id).DepartmentName;
        }
    }

    public string GetDialogHeader(Employee employee)
    {
        if (employee.EmployeeId == 0)
        {
            FooterSaveButtonText = "Insert";
            return "Add New Employee";
        }
        else
        {
            FooterSaveButtonText = "Update";
            return $"Edit {employee.FirstName} Details";
        }
    }

    public async Task Cancel()
    {
        await employeeGrid.CloseEdit();
    }
    public async Task Save()
    {
        await employeeGrid.EndEdit();
    }

    public async Task BatchSaveHandler(BeforeBatchSaveArgs<Employee> Args)
    {
        var updates = Args.BatchChanges.ChangedRecords;
        var inserts = Args.BatchChanges.AddedRecords;
        var deletes = Args.BatchChanges.DeletedRecords;

        foreach (Employee employee in updates)
        {
            await EmployeeService.UpdateEmployee(employee);
        }

        foreach (Employee employee in inserts)
        {
            await EmployeeService.AddEmployee(employee);
        }

        foreach (Employee employee in deletes)
        {
            await EmployeeService.DeleteEmployee(employee.EmployeeId);
        }
    }
}




© 2020 Pragimtech. All Rights Reserved.