DataGrid: Templates

Templates

For extra customization DataGrid will provide you with two additional templates that you can use to extend it’s default behavior.

A display template is used to customize display cells and an edit template is used to customize cell editors. You can place anything inside of the templates, be it a Blazorise components, regular html tags or your own components.

Both templates have a special context attribute that is used to give access to the underline cell value. To learn more about context please go to official Blazor documentation.

DisplayTemplate

Display template is using TItem as a context value.
Date Of Birth
12-2-1984 | Age: 37
2-10-1995 | Age: 26
1-7-1970 | Age: 51
18-9-1992 | Age: 29
19-6-1959 | Age: 62
<DataGrid TItem="Employee"
          Data="@employeeList"
          Responsive>
    <DataGridNumericColumn TItem="Employee" Field="@nameof(Employee.DateOfBirth)" Caption="Date Of Birth" Editable="true">
    <DisplayTemplate>
        @{
            var date = ( context as Employee )?.DateOfBirth;

            if ( date != null )
            {
                @($"{date.Value.ToShortDateString()} | Age: {( DateTime.Now.Year - date.Value.Year )}")
            }
        }
    </DisplayTemplate>
</DataGridNumericColumn>
</DataGrid>
@code{
    [Inject]
    public EmployeeData EmployeeData { get; set; }
    private List<Employee> employeeList;


    protected override async Task OnInitializedAsync()
    {
        employeeList = await EmployeeData.GetDataAsync();
        await base.OnInitializedAsync();
    }
}

EditTemplate

Edit template will give you a way to handle the editing of grid cell values. For this template CellEditContext is used as a context value. Use it to get or set the cell values.
Salary
84 414,66 €
78 566,12 €
89 153,38 €
73 625,86 €
58 321,87 €
<DataGrid TItem="Employee"
          Data="@employeeList"
          Editable
          Responsive>
    <DataGridCommandColumn TItem="Employee" />
    <DataGridColumn TItem="Employee" Field="@nameof(Employee.Salary)" Caption="Salary" DisplayFormat="{0:C}" DisplayFormatProvider="@System.Globalization.CultureInfo.GetCultureInfo("fr-FR")" Editable="true">
        <EditTemplate>
            <NumericEdit TValue="decimal" Value="@((decimal)context.CellValue)" ValueChanged="@( v => context.CellValue = v)" />
        </EditTemplate>
    </DataGridColumn>
</DataGrid>
@code{
    [Inject]
    public EmployeeData EmployeeData { get; set; }
    private List<Employee> employeeList;

    protected override async Task OnInitializedAsync()
    {
        employeeList = await EmployeeData.GetDataAsync();
        await base.OnInitializedAsync();
    }
}

DetailRowTemplate

DetailRowTemplate allows you to display nested structure bellow each row in the grid. One of the examples is “master-detail” relationship between two data-source inside the DataGrid.

For this template the context value is the item from the parent grid.

Once it’s defined a detail-row will be visible for every row in the grid by default. You may change this behaviour by setting DetailRowStartsVisible to false.

If you want to control the visibility of detail-row you can use DetailRowTrigger attribute that can be defined in it’s parent grid. Once defined, whenever a user clicks a row, the DetailRowTrigger will be evaluated. You may also use the DataGrid API, ToggleDetailRow to programatically trigger the detail-row.

First Name
Cora
Jessie
Maryann
Angelina
Kara
<DataGrid TItem="Employee"
          Data="@employeeList"
          @bind-SelectedRow="@selectedEmployee"
          DetailRowTrigger="@((item)=>item.Salaries?.Count > 0 && item.Id == selectedEmployee?.Id)"
          Responsive>
    <DataGridColumns>
        <DataGridCommandColumn TItem="Employee" />
        <DataGridColumn TItem="Employee" Field="@nameof(Employee.FirstName)" Caption="First Name" />
    </DataGridColumns>
    <DetailRowTemplate>
        @{
            var salaries = ( context as Employee ).Salaries;

            <DataGrid TItem="Salary"
                      Data="salaries"
                      Sortable="false"
                      ShowCaptions="false">
                <DataGridCommandColumn TItem="Salary" />
                <DataGridDateColumn TItem="Salary" Field="@nameof(Salary.Date)" Caption="Date" />
                <DataGridNumericColumn TItem="Salary" Field="@nameof(Salary.Total)" Caption="Total" />
            </DataGrid>
        }
    </DetailRowTemplate>
</DataGrid>
@code{
    [Inject]
    public EmployeeData EmployeeData { get; set; }
    private List<Employee> employeeList;
    private Employee selectedEmployee;

    protected override async Task OnInitializedAsync()
    {
        employeeList = await EmployeeData.GetDataAsync();
        await base.OnInitializedAsync();
    }
}

Command Templates

If you want to change the default command buttons, you can use following templates:

  • NewCommandTemplate
  • EditCommandTemplate
  • SaveCommandTemplate
  • CancelCommandTemplate
  • DeleteCommandTemplate
  • ClearFilterCommandTemplate
#First NameLast NameEmailSalary
4CoraConnCora27@yahoo.com84 414,66 €
6JessieWilkinsonJessie_Wilkinson@gmail.com78 566,12 €
8MaryannHilpertMaryann.Hilpert12@gmail.com89 153,38 €
10AngelinaWardAngelina42@gmail.com73 625,86 €
11KaraBrekkeKara.Brekke@hotmail.com58 321,87 €
<DataGrid TItem="Employee"
          Data="@employeeList"
          @bind-SelectedRow="@selectedEmployee"
          Editable
          Responsive>
    <DataGridCommandColumn TItem="Employee">
        <NewCommandTemplate>
            <Button Color="Color.Success" Clicked="@context.Clicked">New</Button>
        </NewCommandTemplate>
        <EditCommandTemplate>
            <Button Color="Color.Primary" Clicked="@context.Clicked">Edit</Button>
        </EditCommandTemplate>
    </DataGridCommandColumn>
    <DataGridColumn TItem="Employee" Field="@nameof(Employee.Id)" Caption="#" Sortable="false" />
    <DataGridColumn TItem="Employee" Field="@nameof(Employee.FirstName)" Caption="First Name" Editable="true" />
    <DataGridColumn TItem="Employee" Field="@nameof(Employee.LastName)" Caption="Last Name" Editable="true" />
    <DataGridColumn TItem="Employee" Field="@nameof(Employee.Email)" Caption="Email" Editable="true" />
    <DataGridColumn TItem="Employee" Field="@nameof(Employee.Salary)" Caption="Salary" DisplayFormat="{0:C}" DisplayFormatProvider="@System.Globalization.CultureInfo.GetCultureInfo("fr-FR")" Editable="true">
        <EditTemplate>
            <NumericEdit TValue="decimal" Value="@((decimal)context.CellValue)" ValueChanged="@( v => context.CellValue = v)" />
        </EditTemplate>
    </DataGridColumn>
</DataGrid>
@code{
    [Inject]
    public EmployeeData EmployeeData { get; set; }
    private List<Employee> employeeList;
    private Employee selectedEmployee;

    protected override async Task OnInitializedAsync()
    {
        employeeList = await EmployeeData.GetDataAsync();
        await base.OnInitializedAsync();
    }
}

Loading Templates

If you want to change display of content, while grid is empty or ReadData is executing, you can use following templates:

  • EmptyTemplate
  • LoadingTemplate
#First NameLast NameEmailSalary
No employees were found!
<DataGrid @ref="datagridRef"
          TItem="Employee"
          Data="@employeeList"
          @bind-SelectedRow="@selectedEmployee"
          TotalItems="@totalEmployees"
          ReadData="@LoadEmployeesFromService"
          Responsive>
    <DataGridColumns>
        <DataGridCommandColumn TItem="Employee" />
        <DataGridColumn TItem="Employee" Field="@nameof(Employee.Id)" Caption="#" Sortable="false" />
        <DataGridColumn TItem="Employee" Field="@nameof(Employee.FirstName)" Caption="First Name" Editable="true" />
        <DataGridColumn TItem="Employee" Field="@nameof(Employee.LastName)" Caption="Last Name" Editable="true" />
        <DataGridColumn TItem="Employee" Field="@nameof(Employee.Email)" Caption="Email" Editable="true" />
        <DataGridColumn TItem="Employee" Field="@nameof(Employee.Salary)" Caption="Salary" DisplayFormat="{0:C}" DisplayFormatProvider="@System.Globalization.CultureInfo.GetCultureInfo("fr-FR")" Editable="true">
            <EditTemplate>
                <NumericEdit TValue="decimal" Value="@((decimal)context.CellValue)" ValueChanged="@( v => context.CellValue = v)" />
            </EditTemplate>
        </DataGridColumn>
    </DataGridColumns>
    <EmptyTemplate>
        <div class="box">
            No employees were found!
        </div>
    </EmptyTemplate>
    <LoadingTemplate>
        <Progress @ref="progressRef" Color="Color.Primary" Max="100" Value="progress" />
    </LoadingTemplate>
</DataGrid>

<Button Background="Background.Primary" Color="Color.Light" Clicked="() => datagridRef.Reload()">Load</Button>
@code{
    protected DataGrid.DataGrid<Employee> datagridRef;
    protected Progress progressRef;
    protected int progress;
    protected Employee selectedEmployee;
    protected int totalEmployees = 0;
    protected List<Employee> employeeList;

    public async Task LoadEmployeesFromService( DataGridReadDataEventArgs<Employee> e )
    {
        /*
        * This can be call to anything like calling an api to load employees.
        * During execution 'LoadingTemplate' will be displayed.
        * If your api call returns empty result, then 'EmptyTemplate' will be displayed,
        * this way you have proper feedback, for when your datagrid is loading or empty.
        */
        progress = 0;
        await InvokeAsync( StateHasChanged );

        await Task.Delay( 500 );
        progress = 25;
        await InvokeAsync( StateHasChanged );

        await Task.Delay( 500 );
        progress = 50;
        await InvokeAsync( StateHasChanged );

        await Task.Delay( 500 );
        progress = 75;
        await InvokeAsync( StateHasChanged );


        await Task.Delay( 500 );
        progress = 100;
        await InvokeAsync( StateHasChanged );
    }
}

ButtonRow Template

Provide a ButtonRowTemplate and have the DataGridCommandMode set to either Default or ButtonRow.

The template has access to the internal commands so you’re also able to construct your own buttons on the pager that can also trigger the Datagrid’s CRUD and clear filter operations as shown in the example below:

Note: ButtonRowTemplate is located inside the Datagrid's Pager, as such the ShowPager Parameter should be set to true.

Note: If you'd like to provide New/Edit buttons, when DataGridEditMode is set to Inline you must provide a DataGridCommandColumn as the Save / Cancel buttons are rendered in this column.

#First NameLast NameEmailSalary
4CoraConnCora27@yahoo.com84 414,66 €
6JessieWilkinsonJessie_Wilkinson@gmail.com78 566,12 €
8MaryannHilpertMaryann.Hilpert12@gmail.com89 153,38 €
10AngelinaWardAngelina42@gmail.com73 625,86 €
11KaraBrekkeKara.Brekke@hotmail.com58 321,87 €
1 - 5 van de 492 items
492 items
<DataGrid TItem="Employee"
          Data="@employeeList"
          @bind-SelectedRow="@selectedEmployee"
          Editable
          Responsive
          ShowPager
          CommandMode="DataGridCommandMode.ButtonRow">
    <DataGridColumns>
        <DataGridColumn TItem="Employee" Field="@nameof(Employee.Id)" Caption="#" Sortable="false" />
        <DataGridColumn TItem="Employee" Field="@nameof(Employee.FirstName)" Caption="First Name" Editable="true" />
        <DataGridColumn TItem="Employee" Field="@nameof(Employee.LastName)" Caption="Last Name" Editable="true" />
        <DataGridColumn TItem="Employee" Field="@nameof(Employee.Email)" Caption="Email" Editable="true" />
        <DataGridColumn TItem="Employee" Field="@nameof(Employee.Salary)" Caption="Salary" DisplayFormat="{0:C}" DisplayFormatProvider="@System.Globalization.CultureInfo.GetCultureInfo("fr-FR")" Editable="true">
            <EditTemplate>
                <NumericEdit TValue="decimal" Value="@((decimal)context.CellValue)" ValueChanged="@( v => context.CellValue = v)" />
            </EditTemplate>
        </DataGridColumn>
    </DataGridColumns>
    <ButtonRowTemplate>
        <Button Color="Color.Success" Clicked="context.NewCommand.Clicked">New</Button>
        <Button Color="Color.Primary" Disabled="(selectedEmployee is null)" Clicked="context.EditCommand.Clicked">Edit</Button>
        <Button Color="Color.Danger" Disabled="(selectedEmployee is null)" Clicked="context.DeleteCommand.Clicked">Delete</Button>
    </ButtonRowTemplate>
</DataGrid>
@code{
    [Inject]
    public EmployeeData EmployeeData { get; set; }
    private List<Employee> employeeList;
    private Employee selectedEmployee;

    protected override async Task OnInitializedAsync()
    {
        employeeList = await EmployeeData.GetDataAsync();
        await base.OnInitializedAsync();
    }
}