Table

A sortable, filterable table with multiselection and pagination.

Default Table

The default table displays your data in simple rows and is responsive, it breaks into mobile layout on Breakpoint.Xs unless changed.
Add the DataLabel property to your MudTd cells to properly display the column label when the table has changed to mobile layout.
The table can be prevented from breaking into mobile layout by setting the Breakpoint to Breakpoint.None.

Nr Sign Name Position Molar mass
1 H Hydrogen 0 1.00794
2 He Helium 17 4.002602
3 Li Lithium 0 6.941
4 Be Beryllium 1 9.012182
@using System.Net.Http.Json
@using MudBlazor.Examples.Data.Models
@inject HttpClient httpClient

<MudTable Items="@Elements.Take(4)" Hover="true" Breakpoint="Breakpoint.Sm" Loading="@_loading" LoadingProgressColor="Color.Info">
    <HeaderContent>
        <MudTh>Nr</MudTh>
        <MudTh>Sign</MudTh>
        <MudTh>Name</MudTh>
        <MudTh>Position</MudTh>
        <MudTh>Molar mass</MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd DataLabel="Nr">@context.Number</MudTd>
        <MudTd DataLabel="Sign">@context.Sign</MudTd>
        <MudTd DataLabel="Name">@context.Name</MudTd>
        <MudTd DataLabel="Position" HideSmall="_hidePosition">@context.Position</MudTd>
        <MudTd DataLabel="Molar mass">@context.Molar</MudTd>
    </RowTemplate>
</MudTable>

<MudSwitch @bind-Value="_hidePosition" Color="Color.Primary">Hide <b>position</b> when Breakpoint=Xs</MudSwitch>
<MudSwitch @bind-Value="_loading" Color="Color.Primary">Show Loading</MudSwitch>
@code { 
    private bool _hidePosition;
    private bool _loading;
    private IEnumerable<Element> Elements = new List<Element>();

    protected override async Task OnInitializedAsync()
    {
        Elements = await httpClient.GetFromJsonAsync<List<Element>>("webapi/periodictable");
    }

}
Click Event and display for selected Row

The RowClassFunc function can be used to customize the display of the selected row. RowClickEvent is triggered each time the row is clicked. In addition to that the RowClass can be used to apply a general row style independent of the selection state. In this example we show a pointer curser.

Nr Sign Name Position Molar mass
1 H Hydrogen 0 1.00794
2 He Helium 17 4.002602
3 Li Lithium 0 6.941
Show inline-clicked event log
@using System.Net.Http.Json
@using MudBlazor.Examples.Data.Models
@inject HttpClient httpClient

<style>
    .selected {
        background-color: #1E88E5 !important;
    }
    .selected > td {
        color: white !important;
    }
    .selected > td .mud-input {
        color: white !important;
    }
</style>

<MudTable T="Element" Items="@Elements.Take(4)" Hover="true" Breakpoint="Breakpoint.Sm" @ref="mudTable"
          RowClass="cursor-pointer" RowClassFunc="@SelectedRowClassFunc" OnRowClick="RowClickEvent">
    <HeaderContent>
        <MudTh>Nr</MudTh>
        <MudTh>Sign</MudTh>
        <MudTh>Name</MudTh>
        <MudTh>Position</MudTh>
        <MudTh>Molar mass</MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd DataLabel="Nr">@context.Number</MudTd>
        <MudTd DataLabel="Sign">@context.Sign</MudTd>
        <MudTd DataLabel="Name">@context.Name</MudTd>
        <MudTd DataLabel="Position">@context.Position</MudTd>
        <MudTd DataLabel="Molar mass">@context.Molar</MudTd>
    </RowTemplate>
</MudTable>
<MudExpansionPanels Style="flex: 1;">
    <MudExpansionPanel Text="Show inline-clicked event log">
        @foreach (var message in clickedEvents)
        {
            <MudText>@message</MudText>
        }
        @if(clickedEvents.Count > 0) {
            <div class="d-flex">
                <MudSpacer/>
                <MudButton Class="mt-3" ButtonType="ButtonType.Button" Variant="Variant.Filled" OnClick="@(() => clickedEvents.Clear())">Clear events</MudButton>
            </div>
        }
    </MudExpansionPanel>
</MudExpansionPanels>
@code {
    private int selectedRowNumber = -1;
    private MudTable<Element> mudTable;
    private List<string> clickedEvents = new();
    private IEnumerable<Element> Elements = new List<Element>()
    {
        new Element() { Number = 1, Sign = "H", Name = "Hydrogen", Position = 0, Molar = 1.00794 },
        new Element() { Number = 2, Sign = "He", Name = "Helium", Position = 17, Molar = 4.002602 },
        new Element() { Number = 3, Sign = "Li", Name = "Lithium", Position = 0, Molar = 6.941 }
    };

    private void RowClickEvent(TableRowClickEventArgs<Element> tableRowClickEventArgs)
    {
        clickedEvents.Add("Row has been clicked");
    }

    private string SelectedRowClassFunc(Element element, int rowNumber)
    {
        if (selectedRowNumber == rowNumber)
        {
            selectedRowNumber = -1;
            clickedEvents.Add("Selected Row: None");
            return string.Empty;
        }
        else if (mudTable.SelectedItem != null && mudTable.SelectedItem.Equals(element))
        {
            selectedRowNumber = rowNumber;
            clickedEvents.Add($"Selected Row: {rowNumber}");
            return "selected";
        }
        else
        {
            return string.Empty;
        }
    }
}
Hover Events

OnRowMouseEnter is triggered when the row starts being hovered (onpointerenter event). OnRowMouseLeave is triggered when the row stops being hovered (onpointerleave event).

Nr Sign Name Position Molar mass
1 H Hydrogen 0 1.00794
2 He Helium 17 4.002602
3 Li Lithium 0 6.941

Currently hovered:

Last hovered:

@using System.Net.Http.Json
@using MudBlazor.Examples.Data.Models
@inject HttpClient httpClient

<MudTable T="Element" Items="@elements.Take(3)" Hover="true" OnRowMouseEnter="RowMouseEnterEvent" OnRowMouseLeave="RowMouseLeaveEvent" Breakpoint="Breakpoint.Sm">
    <HeaderContent>
        <MudTh>Nr</MudTh>
        <MudTh>Sign</MudTh>
        <MudTh>Name</MudTh>
        <MudTh>Position</MudTh>
        <MudTh>Molar mass</MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd DataLabel="Nr">@context.Number</MudTd>
        <MudTd DataLabel="Sign">@context.Sign</MudTd>
        <MudTd DataLabel="Name">@context.Name</MudTd>
        <MudTd DataLabel="Position">@context.Position</MudTd>
        <MudTd DataLabel="Molar mass">@context.Molar</MudTd>
    </RowTemplate>
</MudTable>

<MudText>Currently hovered: @(currentlyHoveredElement)</MudText>
<MudText>Last hovered: @(lastHoveredElement)</MudText>
@code {
    private IEnumerable<Element> elements = new List<Element>();

    private string currentlyHoveredElement;
    private string lastHoveredElement;

    protected override async Task OnInitializedAsync()
    {
        elements = await httpClient.GetFromJsonAsync<List<Element>>("webapi/periodictable");
    }

    private void RowMouseEnterEvent(TableRowHoverEventArgs<Element> eventArgs)
    {
        currentlyHoveredElement = eventArgs.Item.Name;
    }

    private void RowMouseLeaveEvent(TableRowHoverEventArgs<Element> eventArgs)
    {
        currentlyHoveredElement = "";
        lastHoveredElement = eventArgs.Item.Name;
    }
}
Table with pagination and filtering

The <MudTable> component supports pagination, sorting and filtering of rows, as well as single and multiple row selection. To tell the table how to render your data, define a <RowTemplate> containing a <MudTableCell> or a <td> for every column.

Note: you can not fill this table in a conventional way, i.e. by defining multiple <tr> tags. See SimpleTable if you want that. Instead, you pass the collection of items to be displayed to the table's Items parameter.

Nr Sign Name Position Molar mass
1 H Hydrogen 0 1.00794
2 He Helium 17 4.002602
3 Li Lithium 0 6.941
4 Be Beryllium 1 9.012182
5 B Boron 12 10.811
6 C Carbon 13 12.0107
7 N Nitrogen 14 14.0067
8 O Oxygen 15 15.9994
9 F Fluorine 16 18.998404
10 Ne Neon 17 20.1797

Selected1:

@using System.Net.Http.Json
@using MudBlazor.Examples.Data.Models
@inject HttpClient httpClient

<MudTable Items="@Elements" Dense="@dense" Hover="@hover" Bordered="@bordered" Striped="@striped" Filter="new Func<Element,bool>(FilterFunc1)" @bind-SelectedItem="selectedItem1">
    <ToolBarContent>
        <MudText Typo="Typo.h6">Periodic Elements</MudText>
        <MudSpacer />
        <MudTextField @bind-Value="searchString1" Placeholder="Search" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"></MudTextField>
    </ToolBarContent>
    <HeaderContent>
        <MudTh>Nr</MudTh>
        <MudTh>Sign</MudTh>
        <MudTh>Name</MudTh>
        <MudTh>Position</MudTh>
        <MudTh>Molar mass</MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd DataLabel="Nr">@context.Number</MudTd>
        <MudTd DataLabel="Sign">@context.Sign</MudTd>
        <MudTd DataLabel="Name">@context.Name</MudTd>
        <MudTd DataLabel="Position">@context.Position</MudTd>
        <MudTd DataLabel="Molar mass">@context.Molar</MudTd>
    </RowTemplate>
    <PagerContent>
        <MudTablePager />
    </PagerContent>
</MudTable>

<div class="d-flex flex-wrap mt-4">
    <MudSwitch @bind-Value="hover" Color="Color.Primary">Hover</MudSwitch>
    <MudSwitch @bind-Value="dense" Color="Color.Secondary">Dense</MudSwitch>
    <MudSwitch @bind-Value="striped" Color="Color.Tertiary">Striped</MudSwitch>
    <MudSwitch @bind-Value="bordered" Color="Color.Warning">Bordered</MudSwitch>
    <MudSpacer />
    <div style="min-width:200px;">
        <MudText Class="align-self-center d-inline">Selected1: @selectedItem1?.Name</MudText>
    </div>
</div>
@code {
    private bool dense = false;
    private bool hover = true;
    private bool striped = false;
    private bool bordered = false;
    private string searchString1 = "";
    private Element selectedItem1 = null;
    private HashSet<Element> selectedItems = new HashSet<Element>();

    private IEnumerable<Element> Elements = new List<Element>();

    protected override async Task OnInitializedAsync()
    {
        Elements = await httpClient.GetFromJsonAsync<List<Element>>("webapi/periodictable");
    }

    private bool FilterFunc1(Element element) => FilterFunc(element, searchString1);

    private bool FilterFunc(Element element, string searchString)
    {
        if (string.IsNullOrWhiteSpace(searchString))
            return true;
        if (element.Sign.Contains(searchString, StringComparison.OrdinalIgnoreCase))
            return true;
        if (element.Name.Contains(searchString, StringComparison.OrdinalIgnoreCase))
            return true;
        if ($"{element.Number} {element.Position} {element.Molar}".Contains(searchString))
            return true;
        return false;
    }
}
TablePager Customization

The TablePager has many properties to customize it. The property HorizontalAlignment can be used to define the position. The properties RowsPerPageString, InfoFormat and AllItemsText can be used to customize the displayed text. The properties HideRowsPerPage, HidePageNumber and HidePagination can be used to hide the corresponding information.

See TablePager API for more informations.

RowsPerPage parameter of MudTable is independent of PageSizeOptions parameter of PagerContent. Therefore, the RowsPerPage value does not have to be one of the values ​​in the PageSizeOptions list. If the table pager is shown you should make sure the value of RowsPerPage is also available in the PageSizeOptions list, otherwise the users can not go back to this RowsPerPage value once they have chosen another one.
Specifying int.MaxValue in the PageSizeOptions will render as "All" in the Page Size dropdown. Use it when you want users to be able to show all items at once, but be careful, as this can lead to poor performance.

Nr Sign Name Position Molar mass
1 H Hydrogen 0 1.00794
2 He Helium 17 4.002602
3 Li Lithium 0 6.941
4 Be Beryllium 1 9.012182
5 B Boron 12 10.811
6 C Carbon 13 12.0107
7 N Nitrogen 14 14.0067
8 O Oxygen 15 15.9994
9 F Fluorine 16 18.998404
10 Ne Neon 17 20.1797
@using System.Net.Http.Json
@using MudBlazor.Examples.Data.Models
@inject HttpClient httpClient

<MudTable Items="@Elements">
    <ToolBarContent>
        <MudText Typo="Typo.h6">Periodic Elements</MudText>
    </ToolBarContent>
    <HeaderContent>
        <MudTh>Nr</MudTh>
        <MudTh>Sign</MudTh>
        <MudTh>Name</MudTh>
        <MudTh>Position</MudTh>
        <MudTh>Molar mass</MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd DataLabel="Nr">@context.Number</MudTd>
        <MudTd DataLabel="Sign">@context.Sign</MudTd>
        <MudTd DataLabel="Name">@context.Name</MudTd>
        <MudTd DataLabel="Position">@context.Position</MudTd>
        <MudTd DataLabel="Molar mass">@context.Molar</MudTd>
    </RowTemplate>
    <PagerContent>
            <MudTablePager PageSizeOptions="new int[] { 10, 25, 50, 100, int.MaxValue }"
                           RowsPerPageString="@rowsPerPageString"
                           InfoFormat="@infoFormat"
                           AllItemsText="@allItemsText"
                           HorizontalAlignment="@horizontalAlignment"
                           HideRowsPerPage="@hideRowsPerPage"
                           HidePageNumber="@hidePageNumber"
                           HidePagination="@hidePagination" />
    </PagerContent>
</MudTable>

<div class="d-flex flex-wrap mt-4">
    <MudSelect T="HorizontalAlignment" Label="HorizontalAlignment" @bind-Value="horizontalAlignment">
        <MudSelectItem Value="HorizontalAlignment.Center" />
        <MudSelectItem Value="HorizontalAlignment.Left" />
        <MudSelectItem Value="HorizontalAlignment.Right" />
        <MudSelectItem Value="HorizontalAlignment.Start" />
        <MudSelectItem Value="HorizontalAlignment.End" />
    </MudSelect>
</div>
<div class="d-flex flex-wrap mt-4">
    <MudTextField Label="RowsPerPageString" @bind-Value="rowsPerPageString" Immediate/>
     <MudTextField Class="ml-4" Label="AllItemsText" @bind-Value="allItemsText" Immediate />
     <MudTextField Class="ml-4" Label="InfoFormat" @bind-Value="infoFormat" Immediate />
</div>
<div class="d-flex flex-wrap mt-4">
     <MudSwitch @bind-Value="hideRowsPerPage" Color="Color.Tertiary">HideRowsPerPage</MudSwitch>
     <MudSwitch @bind-Value="hidePageNumber" Color="Color.Primary">HidePageNumber</MudSwitch>
     <MudSwitch @bind-Value="hidePagination" Color="Color.Secondary">HidePagination</MudSwitch>
</div>
@code {
    private HorizontalAlignment horizontalAlignment = HorizontalAlignment.Right;
    private bool hidePageNumber;
    private bool hidePagination;
    private bool hideRowsPerPage;
    private string rowsPerPageString = "Rows per page:";
    private string infoFormat = "{first_item}-{last_item} of {all_items}";
    private string allItemsText = "All";

    private IEnumerable<Element> Elements = new List<Element>();

    protected override async Task OnInitializedAsync()
    {
        Elements = await httpClient.GetFromJsonAsync<List<Element>>("webapi/periodictable");
    }
}
Sorting

To enable sorting, add <MudTableSortLabel> to the header cells and define a function that simply returns the value which should be sorted by when sorting by the specific column. You can also specify whether default ordering direction should be ascending or descending by specifying the <InitialDirection> parameter of <MudTableSortLabel>.
Click on a header to sort the table by that column, then click to cycle through sorting directions. By default, sorting directions are ascending, descending and unsorted; if you want to cycle through ascending and descending only, you need to specify the <AllowUnsorted> parameter of the <MudTable>. Sorting can be allowed and disallowed on the column level with the property Enabled.

Name
Nr Sign Name Position Mass
13 Al Aluminium 12 26.981539
51 Sb Antimony 14 121.76
18 Ar Argon 17 39.948
33 As Arsenic 14 74.9216
85 At Astatine 16 210
56 Ba Barium 1 137.327
4 Be Beryllium 1 9.012182
83 Bi Bismuth 14 208.9804
107 Bh Bohrium 6 272
5 B Boron 12 10.811
@using System.Net.Http.Json
@using MudBlazor.Examples.Data.Models
@inject HttpClient httpClient

<MudTable Items="@Elements" Hover="true" SortLabel="Sort By">
    <HeaderContent>
        <MudTh><MudTableSortLabel SortBy="new Func<Element, object>(x=>x.Number)">Nr</MudTableSortLabel></MudTh>
        <MudTh><MudTableSortLabel Enabled="@enabled" SortBy="new Func<Element, object>(x=>x.Sign)">Sign</MudTableSortLabel></MudTh>
        <MudTh><MudTableSortLabel InitialDirection="SortDirection.Ascending" SortBy="new Func<Element, object>(x=>x.Name)">Name</MudTableSortLabel></MudTh>
        <MudTh><MudTableSortLabel SortBy="new Func<Element, object>(x=>x.Position)">Position</MudTableSortLabel></MudTh>
        <MudTh><MudTableSortLabel SortBy="new Func<Element, object>(x=>x.Molar)">Mass</MudTableSortLabel></MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd DataLabel="Nr">@context.Number</MudTd>
        <MudTd DataLabel="Sign">@context.Sign</MudTd>
        <MudTd DataLabel="Name">@context.Name</MudTd>
        <MudTd DataLabel="Position">@context.Position</MudTd>
        <MudTd DataLabel="Molar mass">@context.Molar</MudTd>
    </RowTemplate>
    <PagerContent>
        <MudTablePager PageSizeOptions="new int[] { 10, 25, 50, 100 }" />
    </PagerContent>
</MudTable>

<MudSwitch @bind-Value="enabled" Color="Color.Info">Enable sorting on the Sign Column</MudSwitch>
@code {
    private bool enabled = true;
    private IEnumerable<Element> Elements = new List<Element>();

    protected override async Task OnInitializedAsync()
    {
        Elements = await httpClient.GetFromJsonAsync<List<Element>>("webapi/periodictable");
    }
}
Multi-Selection

To enable multiselection of rows using checkboxes, set MultiSelection="true".
To disable toggling the checkbox state on row-click, set SelectOnRowClick="false".
To prevent editing the current selection, set SelectionChangeable="false".

Item: No row clicked

Selected items (0):

Nr Sign Name Position Molar mass
1 H Hydrogen 0 1.00794
2 He Helium 17 4.002602
3 Li Lithium 0 6.941
4 Be Beryllium 1 9.012182
5 B Boron 12 10.811
6 C Carbon 13 12.0107
7 N Nitrogen 14 14.0067
8 O Oxygen 15 15.9994
9 F Fluorine 16 18.998404
10 Ne Neon 17 20.1797
Select All
@using System.Net.Http.Json
@using MudBlazor.Examples.Data.Models
@inject HttpClient httpClient

<MudText HtmlTag="span">Item: @_selectedItemText</MudText>
<MudText>Selected items (@selectedItems?.Count): @(selectedItems == null ? "" : string.Join(", ", selectedItems.OrderBy(x => x.Sign).Select(x => x.Sign)))</MudText>

<MudTable @ref="_table" T="Element" Items="@Elements" MultiSelection="true" SelectionChangeable="_selectionChangeable" Hover="true"
          @bind-SelectedItems="selectedItems" OnRowClick="@OnRowClick" SelectOnRowClick="@_selectOnRowClick">
    <HeaderContent>
        <MudTh>Nr</MudTh>
        <MudTh>Sign</MudTh>
        <MudTh>Name</MudTh>
        <MudTh>Position</MudTh>
        <MudTh>Molar mass</MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd DataLabel="Nr">@context.Number</MudTd>
        <MudTd DataLabel="Sign">@context.Sign</MudTd>
        <MudTd DataLabel="Name">@context.Name</MudTd>
        <MudTd DataLabel="Position">@context.Position</MudTd>
        <MudTd DataLabel="Molar mass">@context.Molar</MudTd>
    </RowTemplate>
    <PagerContent>
        <MudTablePager PageSizeOptions="new int[] { 10, 25, 50, 100 }" />
    </PagerContent>
    <FooterContent>
        <MudTd colspan="5">Select All</MudTd>
    </FooterContent>
</MudTable>
<MudSwitch @bind-Value="_selectOnRowClick" Color="Color.Primary">Select on row click</MudSwitch>
<MudSwitch @bind-Value="_selectionChangeable" Color="Color.Primary">Selection is changeable</MudSwitch>
@code {
    private HashSet<Element> selectedItems = new HashSet<Element>();
    private IEnumerable<Element> Elements = new List<Element>();
    private bool _selectOnRowClick = true;
    private bool _selectionChangeable = true;
    private MudTable<Element> _table;
    private string _selectedItemText = "No row clicked";

    protected override async Task OnInitializedAsync()
    {
        Elements = await httpClient.GetFromJsonAsync<List<Element>>("webapi/periodictable");
    }

    void OnRowClick(TableRowClickEventArgs<Element> args)
    {
        _selectedItemText = $"{args.Item.Name} ({args.Item.Sign})";
    }
}
Nr Sign Name Position Molar mass
1 H Hydrogen 0 1.00794
2 He Helium 17 4.002602
3 Li Lithium 0 6.941
4 Be Beryllium 1 9.012182
5 B Boron 12 10.811
6 C Carbon 13 12.0107
7 N Nitrogen 14 14.0067
8 O Oxygen 15 15.9994
9 F Fluorine 16 18.998404
10 Ne Neon 17 20.1797
11 Na Sodium 0 22.989769
12 Mg Magnesium 1 24.305
13 Al Aluminium 12 26.981539
14 Si Silicon 13 28.0855
15 P Phosphorus 14 30.973763
16 S Sulfur 15 32.065
17 Cl Chlorine 16 35.453
18 Ar Argon 17 39.948
19 K Potassium 0 39.0983
20 Ca Calcium 1 40.078
21 Sc Scandium 2 44.955914
22 Ti Titanium 3 47.867
23 V Vanadium 4 50.9415
24 Cr Chromium 5 51.9961
25 Mn Manganese 6 54.938046
26 Fe Iron 7 55.845
27 Co Cobalt 8 58.933193
28 Ni Nickel 9 58.6934
29 Cu Copper 10 63.546
30 Zn Zinc 11 65.38
31 Ga Gallium 12 69.723
32 Ge Germanium 13 72.63
33 As Arsenic 14 74.9216
34 Se Selenium 15 78.96
35 Br Bromine 16 79.904
36 Kr Krypton 17 83.798
37 Rb Rubidium 0 85.4678
38 Sr Strontium 1 87.62
39 Y Yttrium 2 88.90585
40 Zr Zirconium 3 91.224
41 Nb Niobium 4 92.90638
42 Mo Molybdenum 5 95.96
43 Tc Technetium 6 98
44 Ru Ruthenium 7 101.07
45 Rh Rhodium 8 102.9055
46 Pd Palladium 9 106.42
47 Ag Silver 10 107.8682
48 Cd Cadmium 11 112.411
49 In Indium 12 114.818
50 Sn Tin 13 118.71
Nr Sign Name Position Molar mass
@using System.Net.Http.Json
@using MudBlazor.Examples.Data.Models
@inject HttpClient httpClient

<MudTable Items="@Elements" FixedHeader="@fixed_header" FixedFooter="@fixed_footer" Height="@(fixed_header || fixed_footer ?"400px":"")">
    <HeaderContent>
        <MudTh>Nr</MudTh>
        <MudTh>Sign</MudTh>
        <MudTh>Name</MudTh>
        <MudTh>Position</MudTh>
        <MudTh>Molar mass</MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd DataLabel="Nr">@context.Number</MudTd>
        <MudTd DataLabel="Sign">@context.Sign</MudTd>
        <MudTd DataLabel="Name">@context.Name</MudTd>
        <MudTd DataLabel="Position">@context.Position</MudTd>
        <MudTd DataLabel="Molar mass">@context.Molar</MudTd>
    </RowTemplate>
    <FooterContent>
        <MudTd>Nr</MudTd>
        <MudTd>Sign</MudTd>
        <MudTd>Name</MudTd>
        <MudTd>Position</MudTd>
        <MudTd>Molar mass</MudTd>
    </FooterContent>
    <PagerContent>
        <MudTablePager PageSizeOptions="new int[]{50, 100}" />
    </PagerContent>
</MudTable>

<MudSwitch @bind-Value="fixed_header" Color="Color.Primary">Fixed Header</MudSwitch>
<MudSwitch @bind-Value="fixed_footer" Color="Color.Primary">Fixed Footer</MudSwitch>
@code {
    bool fixed_header = true;
    bool fixed_footer = false;

    private IEnumerable<Element> Elements = new List<Element>();

    protected override async Task OnInitializedAsync()
    {
        Elements = await httpClient.GetFromJsonAsync<List<Element>>("webapi/periodictable");
    }
}
Column Group and Text Alignment

Specifies a group of one or more columns in a table for formatting.

Nr Sign Name Position Molar mass
1 H Hydrogen 0 1.00794
2 He Helium 17 4.002602
3 Li Lithium 0 6.941
4 Be Beryllium 1 9.012182
5 B Boron 12 10.811
6 C Carbon 13 12.0107
7 N Nitrogen 14 14.0067
8 O Oxygen 15 15.9994
9 F Fluorine 16 18.998404
10 Ne Neon 17 20.1797
@using System.Net.Http.Json
@using MudBlazor.Examples.Data.Models
@inject HttpClient httpClient

<MudTable Items="@Elements">
    <ColGroup>
        <col style="width: 60px;" />
        <col />
        <col style="width: 60%;" />
        <col style="width: 60px;" />
        <col />
    </ColGroup>
    <HeaderContent>
        <MudTh>Nr</MudTh>
        <MudTh>Sign</MudTh>
        <MudTh>Name</MudTh>
        <MudTh>Position</MudTh>
        <MudTh Style="text-align:center">Molar mass</MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd DataLabel="Nr">@context.Number</MudTd>
        <MudTd DataLabel="Sign">@context.Sign</MudTd>
        <MudTd DataLabel="Name">@context.Name</MudTd>
        <MudTd DataLabel="Position">@context.Position</MudTd>
        <MudTd DataLabel="Molar mass" Style="text-align:right">@context.Molar</MudTd>
    </RowTemplate>
    <PagerContent>
        <MudTablePager />
    </PagerContent>
</MudTable>
@code {
    private IEnumerable<Element> Elements = new List<Element>();

    protected override async Task OnInitializedAsync()
    {
        Elements = await httpClient.GetFromJsonAsync<List<Element>>("webapi/periodictable");
    } 
}
Inline Edit Mode

Provides input elements for Selected Row. A click on a row makes the row editable. A Cancel button appears and can be used if CanCancelEdit="true". In this case, the RowEditPreview and RowEditCancel methods must be defined to save and retrieve the initial values of the edited item. RowEditCommit method can be used to handle the commit of the item.

Name
Nr Sign Name Position Mass
13 Al Aluminium 12 26.981539
51 Sb Antimony 14 121.76
18 Ar Argon 17 39.948
33 As Arsenic 14 74.9216
85 At Astatine 16 210
56 Ba Barium 1 137.327
4 Be Beryllium 1 9.012182
83 Bi Bismuth 14 208.9804
107 Bh Bohrium 6 272
5 B Boron 12 10.811
Row Click
End
Selected1:
Show inline-edit event log
@using System.Net.Http.Json
@using MudBlazor
@using MudBlazor.Examples.Data.Models
@inject HttpClient httpClient
@inject ISnackbar Snackbar

<MudTable Items="@Elements" Dense="@dense" Hover="@hover" ReadOnly="@ronly" CanCancelEdit="@canCancelEdit" Filter="new Func<Element,bool>(FilterFunc)"
          @bind-SelectedItem="selectedItem1" SortLabel="Sort By" CommitEditTooltip="Commit Edit"
          OnCommitEditClick="@(() => Snackbar.Add("Commit Edit Handler Invoked"))" RowEditPreview="BackupItem" RowEditCancel="ResetItemToOriginalValues"
          RowEditCommit="ItemHasBeenCommitted" IsEditRowSwitchingBlocked="@blockSwitch" ApplyButtonPosition="@applyButtonPosition" EditButtonPosition="@editButtonPosition" EditTrigger="@editTrigger">
    <ToolBarContent>
        <MudText Typo="Typo.h6">Periodic Elements</MudText>
        <MudSpacer />
        <MudTextField @bind-Value="searchString" Placeholder="Search" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"></MudTextField>
    </ToolBarContent>
    <ColGroup>
        @if (applyButtonPosition.DisplayApplyButtonAtStart() || (editButtonPosition.DisplayEditButtonAtStart() && editTrigger == TableEditTrigger.EditButton))
        {
            <col style="width:50px;" />
        }
        <col style="width:50px;" />
        <col style="width:80px;" />
        <col style="width:50%;" />
        <col />
        <col />
        @if (applyButtonPosition.DisplayApplyButtonAtEnd() || (editButtonPosition.DisplayEditButtonAtEnd() && editTrigger == TableEditTrigger.EditButton))
        {
            <col style="width:50px;" />
        }
    </ColGroup>
    <HeaderContent>
        <MudTh><MudTableSortLabel SortBy="new Func<Element, object>(x=>x.Number)">Nr</MudTableSortLabel></MudTh>
        <MudTh><MudTableSortLabel SortBy="new Func<Element, object>(x=>x.Sign)">Sign</MudTableSortLabel></MudTh>
        <MudTh><MudTableSortLabel InitialDirection="SortDirection.Ascending" SortBy="new Func<Element, object>(x=>x.Name)">Name</MudTableSortLabel></MudTh>
        <MudTh><MudTableSortLabel SortBy="new Func<Element, object>(x=>x.Position)">Position</MudTableSortLabel></MudTh>
        <MudTh><MudTableSortLabel SortBy="new Func<Element, object>(x=>x.Molar)">Mass</MudTableSortLabel></MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd DataLabel="Nr">@context.Number</MudTd>
        <MudTd DataLabel="Sign">@context.Sign</MudTd>
        <MudTd DataLabel="Name">@context.Name</MudTd>
        <MudTd DataLabel="Position">@context.Position</MudTd>
        <MudTd DataLabel="Molar mass">@context.Molar</MudTd>
    </RowTemplate>
    <RowEditingTemplate>
        <MudTd DataLabel="Nr">@context.Number</MudTd>
        <MudTd DataLabel="Sign">
            <MudTextField @bind-Value="context.Sign" Required />
        </MudTd>
        <MudTd DataLabel="Name">
            <MudTextField @bind-Value="context.Name" Required />
        </MudTd>
        <MudTd DataLabel="Position">
            <MudNumericField @bind-Value="context.Position" Required Min="1" />
        </MudTd>
        <MudTd DataLabel="Molar mass">
            <MudTextField @bind-Value="context.Molar" Required />
        </MudTd>
    </RowEditingTemplate>
    <PagerContent>
        <MudTablePager />
    </PagerContent>
    <EditButtonContent Context="button">
        <MudIconButton Size="@Size.Small" Icon="@Icons.Material.Outlined.Edit" Class="pa-0" OnClick="@button.ButtonAction" Disabled="@button.ButtonDisabled" />
    </EditButtonContent>
</MudTable>

<MudSwitch @bind-Value="hover" Color="Color.Primary">Hover</MudSwitch>
<MudSwitch @bind-Value="dense" Color="Color.Secondary">Dense</MudSwitch>
<MudSwitch @bind-Value="ronly" Color="Color.Tertiary">Read Only</MudSwitch>
<MudSwitch @bind-Value="canCancelEdit" Color="Color.Info">Can Cancel Edit</MudSwitch>
<MudSwitch @bind-Value="blockSwitch" Color="Color.Success">Block Edit Row Switching</MudSwitch>
<MudGrid>
    <MudItem xs="12" md="4">
        <MudSelect Label="Edit Trigger" T="TableEditTrigger" @bind-Value="editTrigger">
            <MudSelectItem Value="TableEditTrigger.RowClick">Row Click</MudSelectItem>
            <MudSelectItem Value="TableEditTrigger.EditButton">Edit Button</MudSelectItem>
        </MudSelect>
    </MudItem>
    @if (editTrigger == TableEditTrigger.EditButton)
    {
        <MudItem xs="12" md="4">
            <MudSelect Label="Edit Button Position" T="TableEditButtonPosition" @bind-Value="editButtonPosition">
                <MudSelectItem Value="TableEditButtonPosition.Start">Start</MudSelectItem>
                <MudSelectItem Value="TableEditButtonPosition.End">End</MudSelectItem>
                <MudSelectItem Value="TableEditButtonPosition.StartAndEnd">Start and End</MudSelectItem>
            </MudSelect>
        </MudItem>
    }
    <MudItem xs="12" md="4">
        <MudSelect Label="Apply Button Position" T="TableApplyButtonPosition" @bind-Value="applyButtonPosition">
            <MudSelectItem Value="TableApplyButtonPosition.Start">Start</MudSelectItem>
            <MudSelectItem Value="TableApplyButtonPosition.End">End</MudSelectItem>
            <MudSelectItem Value="TableApplyButtonPosition.StartAndEnd">Start and End</MudSelectItem>
        </MudSelect>
    </MudItem>
</MudGrid>

<MudText HtmlTag="span">Selected1: @selectedItem1?.Name</MudText>

<MudExpansionPanels Style="flex: 1;">
    <MudExpansionPanel Text="Show inline-edit event log">
        @foreach (var message in editEvents)
        {
            <MudText>@message</MudText>
        }
        @if (editEvents.Count > 0)
        {
            <div class="d-flex">
                <MudSpacer />
                <MudButton Class="mt-3" ButtonType="ButtonType.Button" Variant="Variant.Filled" OnClick="ClearEventLog">Clear event log</MudButton>
            </div>
        }
    </MudExpansionPanel>
</MudExpansionPanels>
@code {
    private List<string> editEvents = new();
    private bool dense = false;
    private bool hover = true;
    private bool ronly = false;
    private bool canCancelEdit = false;
    private bool blockSwitch = false;
    private string searchString = "";
    private Element selectedItem1 = null;
    private Element elementBeforeEdit;
    private HashSet<Element> selectedItems1 = new HashSet<Element>();
    private TableApplyButtonPosition applyButtonPosition = TableApplyButtonPosition.End;
    private TableEditButtonPosition editButtonPosition = TableEditButtonPosition.End;
    private TableEditTrigger editTrigger = TableEditTrigger.RowClick;
    private IEnumerable<Element> Elements = new List<Element>();

    protected override async Task OnInitializedAsync()
    {
        Elements = await httpClient.GetFromJsonAsync<List<Element>>("webapi/periodictable");
    }

    private void ClearEventLog()
    {
        editEvents.Clear();
    }

    private void AddEditionEvent(string message)
    {
        editEvents.Add(message);
        StateHasChanged();
    }

    private void BackupItem(object element)
    {
        elementBeforeEdit = new()
            {
                Sign = ((Element)element).Sign,
                Name = ((Element)element).Name,
                Molar = ((Element)element).Molar,
                Position = ((Element)element).Position
            };
        AddEditionEvent($"RowEditPreview event: made a backup of Element {((Element)element).Name}");
    }

    private void ItemHasBeenCommitted(object element)
    {
        AddEditionEvent($"RowEditCommit event: Changes to Element {((Element)element).Name} committed");
    }

    private void ResetItemToOriginalValues(object element)
    {
        ((Element)element).Sign = elementBeforeEdit.Sign;
        ((Element)element).Name = elementBeforeEdit.Name;
        ((Element)element).Molar = elementBeforeEdit.Molar;
        ((Element)element).Position = elementBeforeEdit.Position;
        AddEditionEvent($"RowEditCancel event: Editing of Element {((Element)element).Name} canceled");
    }

    private bool FilterFunc(Element element)
    {
        if (string.IsNullOrWhiteSpace(searchString))
            return true;
        if (element.Sign.Contains(searchString, StringComparison.OrdinalIgnoreCase))
            return true;
        if (element.Name.Contains(searchString, StringComparison.OrdinalIgnoreCase))
            return true;
        if ($"{element.Number} {element.Position} {element.Molar}".Contains(searchString))
            return true;
        return false;
    }
}
Server Side Filtering, Sorting and Pagination

Set ServerData to load data from the backend that is filtered, sorted and paginated. Table will call this async function whenever the user navigates the pager or changes sorting by clicking on the sort header icons. In this example, we also show how to force the table to update when the search textfield blurs, so that the table reloads server-filtered data.

Note: with a ServerData func you don't need Items and Filter.

Nr Sign Name Position Molar mass

Loading...

@using System.Net.Http.Json
@using MudBlazor.Examples.Data.Models
@using System.Threading
@inject HttpClient httpClient

<MudTable ServerData="ServerReload" Dense="true" Hover="true" @ref="table">
    <ToolBarContent>
        <MudText Typo="Typo.h6">Periodic Elements</MudText>
        <MudSpacer />
        <MudTextField T="string" ValueChanged="@(s=>OnSearch(s))" Placeholder="Search" Adornment="Adornment.Start"
                      AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"></MudTextField>
    </ToolBarContent>
    <HeaderContent>
        <MudTh><MudTableSortLabel SortLabel="nr_field" T="Element">Nr</MudTableSortLabel></MudTh>
        <MudTh><MudTableSortLabel SortLabel="sign_field" T="Element">Sign</MudTableSortLabel></MudTh>
        <MudTh><MudTableSortLabel SortLabel="name_field" T="Element">Name</MudTableSortLabel></MudTh>
        <MudTh><MudTableSortLabel SortLabel="position_field" T="Element">Position</MudTableSortLabel></MudTh>
        <MudTh><MudTableSortLabel SortLabel="mass_field" T="Element">Molar mass</MudTableSortLabel></MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd DataLabel="Nr">@context.Number</MudTd>
        <MudTd DataLabel="Sign">@context.Sign</MudTd>
        <MudTd DataLabel="Name">@context.Name</MudTd>
        <MudTd DataLabel="Position">@context.Position</MudTd>
        <MudTd DataLabel="Molar mass">@context.Molar</MudTd>
    </RowTemplate>
    <NoRecordsContent>
        <MudText>No matching records found</MudText>
    </NoRecordsContent>
    <LoadingContent>
        <MudText>Loading...</MudText>
    </LoadingContent>
    <PagerContent>
        <MudTablePager />
    </PagerContent>
</MudTable>
@code {
    private IEnumerable<Element> pagedData;
    private MudTable<Element> table;

    private int totalItems;
    private string searchString = null;

    /// <summary>
    /// Here we simulate getting the paged, filtered and ordered data from the server
    /// </summary>
    private async Task<TableData<Element>> ServerReload(TableState state, CancellationToken token)
    {
        IEnumerable<Element> data = await httpClient.GetFromJsonAsync<List<Element>>("webapi/periodictable", token);
        await Task.Delay(300, token);
        data = data.Where(element =>
        {
            if (string.IsNullOrWhiteSpace(searchString))
                return true;
            if (element.Sign.Contains(searchString, StringComparison.OrdinalIgnoreCase))
                return true;
            if (element.Name.Contains(searchString, StringComparison.OrdinalIgnoreCase))
                return true;
            if ($"{element.Number} {element.Position} {element.Molar}".Contains(searchString))
                return true;
            return false;
        }).ToArray();
        totalItems = data.Count();
        switch (state.SortLabel)
        {
            case "nr_field":
                data = data.OrderByDirection(state.SortDirection, o => o.Number);
                break;
            case "sign_field":
                data = data.OrderByDirection(state.SortDirection, o => o.Sign);
                break;
            case "name_field":
                data = data.OrderByDirection(state.SortDirection, o => o.Name);
                break;
            case "position_field":
                data = data.OrderByDirection(state.SortDirection, o => o.Position);
                break;
            case "mass_field":
                data = data.OrderByDirection(state.SortDirection, o => o.Molar);
                break;
        }

        pagedData = data.Skip(state.Page * state.PageSize).Take(state.PageSize).ToArray();
        return new TableData<Element>() {TotalItems = totalItems, Items = pagedData};
    }

    private void OnSearch(string text)
    {
        searchString = text;
        table.ReloadServerData();
    }
}
Server Side Data With Cancellation

Use the CancellationToken to detect when a request for data has been superceded by a new request. By forwarding the token to methods which support it, such as common HttpClient or DbContent methods, the table can perform well even with frequent updates.

Note: When using ServerData, you don't need Items or Filter.

Nr Sign Name Position Molar mass

Loading...

@using MudBlazor.Examples.Data.Models
@using System.Net.Http.Json
@using System.Threading
@inject HttpClient httpClient

<MudTable ServerData="ServerReload" Dense="true" Hover="true">
    <ToolBarContent>
        <MudText Typo="Typo.h6">Periodic Elements</MudText>
    </ToolBarContent>
    <HeaderContent>
        <MudTh><MudTableSortLabel SortLabel="nr_field" T="Element">Nr</MudTableSortLabel></MudTh>
        <MudTh><MudTableSortLabel SortLabel="sign_field" T="Element">Sign</MudTableSortLabel></MudTh>
        <MudTh><MudTableSortLabel SortLabel="name_field" T="Element">Name</MudTableSortLabel></MudTh>
        <MudTh><MudTableSortLabel SortLabel="position_field" T="Element">Position</MudTableSortLabel></MudTh>
        <MudTh><MudTableSortLabel SortLabel="mass_field" T="Element">Molar mass</MudTableSortLabel></MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd DataLabel="Nr">@context.Number</MudTd>
        <MudTd DataLabel="Sign">@context.Sign</MudTd>
        <MudTd DataLabel="Name">@context.Name</MudTd>
        <MudTd DataLabel="Position">@context.Position</MudTd>
        <MudTd DataLabel="Molar mass">@context.Molar</MudTd>
    </RowTemplate>
    <NoRecordsContent>
        <MudText>No matching records found</MudText>
    </NoRecordsContent>
    <LoadingContent>
        <MudText>Loading...</MudText>
    </LoadingContent>
    <PagerContent>
        <MudTablePager />
    </PagerContent>
</MudTable>
@code {
    /// <summary>
    /// Here we simulate getting the paged, filtered and ordered data from the server, with a token for canceling this request
    /// </summary>
    private async Task<TableData<Element>> ServerReload(TableState state, CancellationToken token)
    {
        // Forward the provided token to methods which support it
        var data = await httpClient.GetFromJsonAsync<List<Element>>("webapi/periodictable", token);
        // Simulate a long-running operation
        await Task.Delay(300, token);
        // Get the total count
        var totalItems = data.Count();
        // Get the paged data
        var pagedData = data.Skip(state.Page * state.PageSize).Take(state.PageSize).ToList();
        // Return the data
        return new TableData<Element>() { TotalItems = totalItems, Items = pagedData };
    }
}
Record Type Support

By default, mutable record types do not work with multi-selection or editing. This is due to the way record equality works. To support multi-selection or editing of records in a MudTable, you must define a custom Comparer that implements IEqualityComparer<T>. The example below demonstrates multi-selection and paging while modifying a record type on SelectedItemsChanged.

Nr Sign Name Position Molar mass
1 H Hydrogen 0 1.00794
2 He Helium 17 4.002602
3 Li Lithium 0 6.941
4 Be Beryllium 1 9.012182
5 B Boron 12 10.811
6 C Carbon 13 12.0107
7 N Nitrogen 14 14.0067
8 O Oxygen 15 15.9994
9 F Fluorine 16 18.998404
10 Ne Neon 17 20.1797
Select All
Selected items:
@using System.Net.Http.Json
@using System.Text.Json.Serialization;
@using MudBlazor.Examples.Data.Models
@inject HttpClient httpClient

<MudTable Items="@Elements" MultiSelection="true" T="Element" SelectedItemsChanged="OnSelectedItemsChanged" Comparer="Comparer">
    <HeaderContent>
        <MudTh>Nr</MudTh>
        <MudTh>Sign</MudTh>
        <MudTh>Name</MudTh>
        <MudTh>Position</MudTh>
        <MudTh>Molar mass</MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd DataLabel="Nr">@context.Number</MudTd>
        <MudTd DataLabel="Sign">@context.Sign</MudTd>
        <MudTd DataLabel="Name">@context.Name</MudTd>
        <MudTd DataLabel="Position">@context.Position</MudTd>
        <MudTd DataLabel="Molar mass">@context.Molar</MudTd>
    </RowTemplate>
    <PagerContent>
        <MudTablePager PageSizeOptions="new int[] { 10, 25, 50, 100 }" />
    </PagerContent>
    <FooterContent>
        <MudTd colspan="5">Select All</MudTd>
    </FooterContent>
</MudTable>

<MudText HtmlTag="span">Selected items: @(selectedItems1 == null ? "" : string.Join(", ", selectedItems1.OrderBy(x => x.Sign).Select(x => x.Sign)))</MudText>
@code {
    private HashSet<Element> selectedItems1 = new HashSet<Element>();

    private List<Element> Elements = new List<Element>();

    private ElementComparer Comparer = new();

    private void OnSelectedItemsChanged(HashSet<Element> elements)
    {
        if (elements.Any())
            elements.First().Name = "Changed";
    }

    protected override async Task OnInitializedAsync()
    {
        Elements = await httpClient.GetFromJsonAsync<List<Element>>("webapi/periodictable");
    }

    class ElementComparer : IEqualityComparer<Element>
    {
        public bool Equals(Element a, Element b) => a?.Number == b?.Number;
        public int GetHashCode(Element x) => HashCode.Combine(x?.Number);
    }

    public record Element
    {
        public string Group { get; set; }
        public int Position { get; set; }
        public string Name { get; set; }
        public int Number { get; set; }

        [JsonPropertyName("small")]
        public string Sign { get; set; }
        public double Molar { get; set; }
        public IList<int> Electrons { get; set; }

        public override string ToString() => $"{Sign} - {Name}";
    }
}
Periodic Elements Info
Basic Extended
Nr Sign Name Position Molar mass
1 H Hydrogen 0 1.00794
2 He Helium 17 4.002602
3 Li Lithium 0 6.941
4 Be Beryllium 1 9.012182
5 B Boron 12 10.811
6 C Carbon 13 12.0107
7 N Nitrogen 14 14.0067
8 O Oxygen 15 15.9994
9 F Fluorine 16 18.998404
10 Ne Neon 17 20.1797
Nr Sign Name Position Molar mass
Selected: 0
@using System.Net.Http.Json
@using MudBlazor.Examples.Data.Models
@inject HttpClient httpClient

<style type="text/css">
    .mud-table-head .header-centered th {
        text-align: center;
        font-size: 1.2em;
    }

   .mud-table-foot .bold-text .mud-table-cell {
       font-weight: 500;
   }
</style>

<MudTable Items="@Elements.Take(10)" MultiSelection="true" @bind-SelectedItems="selectedItems" Hover="true" Breakpoint="Breakpoint.Sm" Striped="true" Bordered="true"
          CustomHeader="true" CustomFooter="true" HeaderClass="table-head-bordered" FooterClass="table-foot-bordered">
    <HeaderContent>
        <MudTHeadRow IgnoreCheckbox="true" Class="header-centered">
            <MudTh colspan="6">Periodic Elements Info</MudTh>
        </MudTHeadRow>
        <MudTHeadRow Class="header-centered">
            <MudTh colspan="2">Basic</MudTh>
            <MudTh colspan="3">Extended</MudTh>
        </MudTHeadRow>
        <MudTHeadRow Checkable="true">
            <MudTh>Nr</MudTh> 
            <MudTh>Sign</MudTh>
            <MudTh>Name</MudTh>
            <MudTh>Position</MudTh>
            <MudTh>Molar mass</MudTh>
        </MudTHeadRow>
    </HeaderContent>
    <RowTemplate>
        <MudTd DataLabel="Nr">@context.Number</MudTd>
        <MudTd DataLabel="Sign">@context.Sign</MudTd>
        <MudTd DataLabel="Name">@context.Name</MudTd>
        <MudTd DataLabel="Position" HideSmall="_hidePosition">@context.Position</MudTd>
        <MudTd DataLabel="Molar mass">@context.Molar</MudTd>
    </RowTemplate>
    <FooterContent>
        <MudTFootRow Class="bold-text">
            <MudTd>Nr</MudTd>
            <MudTd>Sign</MudTd>
            <MudTd>Name</MudTd>
            <MudTd>Position</MudTd>
            <MudTd>Molar mass</MudTd>
        </MudTFootRow>
        <MudTFootRow Checkable="true">
            <MudTd colspan="5">Selected: @selectedItems.Count</MudTd>
        </MudTFootRow>
    </FooterContent>
</MudTable>
<MudSwitch @bind-Value="_hidePosition" Color="Color.Primary">Hide <b>position</b> when Breakpoint=Xs</MudSwitch>
@code {
    private bool _hidePosition;
    private IEnumerable<Element> Elements = new List<Element>();
    private HashSet<Element> selectedItems = new HashSet<Element>();

    protected override async Task OnInitializedAsync()
    {
        Elements = await httpClient.GetFromJsonAsync<List<Element>>("webapi/periodictable");
    }
}
Nr Name Age
1 Harry Potter 11
2 Ash Ketchum 18
3 Frodo Baggins 24

Address Details for Frodo Baggins

Address Line 1 Address Line 2 Postal Code
123 Shire Lane Bag End 223
456 Shire Street Bag End 445
789 Shire Avenue Bag End 667
<MudTable Items="@People" Hover="true" Breakpoint="Breakpoint.Sm">
    <ColGroup>
        <col style="width:300px;" />
        <col style="width:100px;" />
        <col />
        <col style="width:100px;" />
    </ColGroup>
    <HeaderContent>
        <MudTh></MudTh>
        <MudTh>Nr</MudTh>
        <MudTh>Name</MudTh>
        <MudTh>Age</MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd><MudButton Variant="Variant.Outlined" Size="Size.Small" OnClick="@(() => ShowBtnPress(context.Number))">@((context.ShowDetails == true)? "Hide" : "Show") Address Details</MudButton></MudTd>
        <MudTd DataLabel="Nr">@context.Number</MudTd>
        <MudTd DataLabel="Name">@context.Name</MudTd>
        <MudTd DataLabel="Age">@context.Age</MudTd>
    </RowTemplate>
    <ChildRowContent>
        @if (context.ShowDetails)
                {
  <MudTr>
   <td colspan="4">
    <MudCard Elevation="0">
     <MudCardHeader>
      <CardHeaderContent>
       <MudText Typo="Typo.body1">Address Details for <strong>@context.Name</strong></MudText>
      </CardHeaderContent>
     </MudCardHeader>
     <MudCardContent Class="pa-0">
      <MudTable Items="@context.Addresses" Context="AddressContext" Hover="true" Breakpoint="Breakpoint.Sm" Elevation="0">
       <ColGroup>
        <col />
        <col />
        <col style="width:200px;" />
       </ColGroup>
       <HeaderContent>
        <MudTh>Address Line 1</MudTh>
        <MudTh>Address Line 2</MudTh>
        <MudTh>Postal Code</MudTh>
       </HeaderContent>
       <RowTemplate>
        <MudTd DataLabel="Address Line 1">@AddressContext.Address_Line_1</MudTd>
        <MudTd DataLabel="Address Line 2">@AddressContext.Address_Line_2</MudTd>
        <MudTd DataLabel="Postal Code">@AddressContext.Postal_Code</MudTd>
       </RowTemplate>
      </MudTable>
     </MudCardContent>
    </MudCard>
   </td>
  </MudTr>
        }
    </ChildRowContent>
</MudTable>
@code
{
    protected override void OnInitialized()
    {
        FillPeople();
    }

    public class Address
    {
        public string Address_Line_1 { get; set; }
        public string Address_Line_2 { get; set; }
        public int Postal_Code { get; set; }
    }
    public class Person
    {
        public bool ShowDetails { get; set; }
        public int Number { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public IList<Address> Addresses { get; set; }
    }
    private void FillPeople()
    {
        IList<Person> people = new List<Person>();
        IList<Address> addresses = new List<Address>();
        addresses.Add(new Address { Address_Line_1 = "4 Privet Drive", Address_Line_2 = "Little Whinging", Postal_Code = 111 });
        addresses.Add(new Address { Address_Line_1 = "12 Grimmauld Place", Address_Line_2 = "The Burrow", Postal_Code = 333 });
        people.Add(new Person
        {
            ShowDetails = false,
            Number = 1,
            Name = "Harry Potter",
            Age = 11,
            Addresses = addresses
        });

        addresses = new List<Address>();
        addresses.Add(new Address { Address_Line_1 = "123 Pikachu Lane", Address_Line_2 = "Pallet Town", Postal_Code = 777 });
        addresses.Add(new Address { Address_Line_1 = "456 Mew Street", Address_Line_2 = "Pallet Town", Postal_Code = 999 });
        people.Add(new Person
        {
            ShowDetails = false,
            Number = 2,
            Name = "Ash Ketchum",
            Age = 18,
            Addresses = addresses
        });
        People = people;

        addresses = new List<Address>();
        addresses.Add(new Address { Address_Line_1 = "123 Shire Lane", Address_Line_2 = "Bag End", Postal_Code = 223 });
        addresses.Add(new Address { Address_Line_1 = "456 Shire Street", Address_Line_2 = "Bag End", Postal_Code = 445 });
        addresses.Add(new Address { Address_Line_1 = "789 Shire Avenue", Address_Line_2 = "Bag End", Postal_Code = 667 });
        people.Add(new Person
        {
            ShowDetails = true,
            Number = 3,
            Name = "Frodo Baggins",
            Age = 24,
            Addresses = addresses
        });
        People = people;
    }
    private static IEnumerable<Person> People { get; set; }

    private void ShowBtnPress(int nr)
    {
        Person tmpPerson = People.First(f => f.Number == nr);
        tmpPerson.ShowDetails = !tmpPerson.ShowDetails;
    }
}
Horizontal Scrolling

If too many columns are displayed, setting HorizontalScrollbar="true" will allow the user to scroll the content horizontally.

Column1 Column2 Column3 Column4 Column5 Column6 Column7 Column8 Column9 Column10 Column11 Column12 Column13 Column14 Column15
Value_0 Value_0 Value_0 Value_0 Value_0 Value_0 Value_0 Value_0 Value_0 Value_0 Value_0 Value_0 Value_0 Value_0 Value_0
Value_1 Value_1 Value_1 Value_1 Value_1 Value_1 Value_1 Value_1 Value_1 Value_1 Value_1 Value_1 Value_1 Value_1 Value_1
Value_2 Value_2 Value_2 Value_2 Value_2 Value_2 Value_2 Value_2 Value_2 Value_2 Value_2 Value_2 Value_2 Value_2 Value_2
Value_3 Value_3 Value_3 Value_3 Value_3 Value_3 Value_3 Value_3 Value_3 Value_3 Value_3 Value_3 Value_3 Value_3 Value_3
Value_4 Value_4 Value_4 Value_4 Value_4 Value_4 Value_4 Value_4 Value_4 Value_4 Value_4 Value_4 Value_4 Value_4 Value_4
Value_5 Value_5 Value_5 Value_5 Value_5 Value_5 Value_5 Value_5 Value_5 Value_5 Value_5 Value_5 Value_5 Value_5 Value_5
Value_6 Value_6 Value_6 Value_6 Value_6 Value_6 Value_6 Value_6 Value_6 Value_6 Value_6 Value_6 Value_6 Value_6 Value_6
Value_7 Value_7 Value_7 Value_7 Value_7 Value_7 Value_7 Value_7 Value_7 Value_7 Value_7 Value_7 Value_7 Value_7 Value_7
Value_8 Value_8 Value_8 Value_8 Value_8 Value_8 Value_8 Value_8 Value_8 Value_8 Value_8 Value_8 Value_8 Value_8 Value_8
Value_9 Value_9 Value_9 Value_9 Value_9 Value_9 Value_9 Value_9 Value_9 Value_9 Value_9 Value_9 Value_9 Value_9 Value_9
Value_10 Value_10 Value_10 Value_10 Value_10 Value_10 Value_10 Value_10 Value_10 Value_10 Value_10 Value_10 Value_10 Value_10 Value_10
Value_11 Value_11 Value_11 Value_11 Value_11 Value_11 Value_11 Value_11 Value_11 Value_11 Value_11 Value_11 Value_11 Value_11 Value_11
Value_12 Value_12 Value_12 Value_12 Value_12 Value_12 Value_12 Value_12 Value_12 Value_12 Value_12 Value_12 Value_12 Value_12 Value_12
Value_13 Value_13 Value_13 Value_13 Value_13 Value_13 Value_13 Value_13 Value_13 Value_13 Value_13 Value_13 Value_13 Value_13 Value_13
Value_14 Value_14 Value_14 Value_14 Value_14 Value_14 Value_14 Value_14 Value_14 Value_14 Value_14 Value_14 Value_14 Value_14 Value_14
Value_15 Value_15 Value_15 Value_15 Value_15 Value_15 Value_15 Value_15 Value_15 Value_15 Value_15 Value_15 Value_15 Value_15 Value_15
Value_16 Value_16 Value_16 Value_16 Value_16 Value_16 Value_16 Value_16 Value_16 Value_16 Value_16 Value_16 Value_16 Value_16 Value_16
Value_17 Value_17 Value_17 Value_17 Value_17 Value_17 Value_17 Value_17 Value_17 Value_17 Value_17 Value_17 Value_17 Value_17 Value_17
Value_18 Value_18 Value_18 Value_18 Value_18 Value_18 Value_18 Value_18 Value_18 Value_18 Value_18 Value_18 Value_18 Value_18 Value_18
Value_19 Value_19 Value_19 Value_19 Value_19 Value_19 Value_19 Value_19 Value_19 Value_19 Value_19 Value_19 Value_19 Value_19 Value_19
<MudTable Items="_items" Height="350px" Breakpoint="Breakpoint.Sm" HorizontalScrollbar="true">
    <HeaderContent>
        <MudTh>Column1</MudTh>
        <MudTh>Column2</MudTh>
        <MudTh>Column3</MudTh>
        <MudTh>Column4</MudTh>
        <MudTh>Column5</MudTh>
        <MudTh>Column6</MudTh>
        <MudTh>Column7</MudTh>
        <MudTh>Column8</MudTh>
        <MudTh>Column9</MudTh>
        <MudTh>Column10</MudTh>
        <MudTh>Column11</MudTh>
        <MudTh>Column12</MudTh>
        <MudTh>Column13</MudTh>
        <MudTh>Column14</MudTh>
        <MudTh>Column15</MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd DataLabel="Column1">@context.Column1</MudTd>
        <MudTd DataLabel="Column2">@context.Column2</MudTd>
        <MudTd DataLabel="Column3">@context.Column3</MudTd>
        <MudTd DataLabel="Column4">@context.Column4</MudTd>
        <MudTd DataLabel="Column5">@context.Column5</MudTd>
        <MudTd DataLabel="Column6">@context.Column6</MudTd>
        <MudTd DataLabel="Column7">@context.Column7</MudTd>
        <MudTd DataLabel="Column8">@context.Column8</MudTd>
        <MudTd DataLabel="Column9">@context.Column9</MudTd>
        <MudTd DataLabel="Column10">@context.Column10</MudTd>
        <MudTd DataLabel="Column11">@context.Column11</MudTd>
        <MudTd DataLabel="Column12">@context.Column12</MudTd>
        <MudTd DataLabel="Column13">@context.Column13</MudTd>
        <MudTd DataLabel="Column14">@context.Column14</MudTd>
        <MudTd DataLabel="Column15">@context.Column15</MudTd>
    </RowTemplate>
</MudTable>
@code {
    public class TestItem{
        public string Column1 {get;set;}
        public string Column2 {get;set;}
        public string Column3 {get;set;}
        public string Column4 {get;set;}
        public string Column5 {get;set;}
        public string Column6 {get;set;}
        public string Column7 {get;set;}
        public string Column8 {get;set;}
        public string Column9 {get;set;}
        public string Column10 {get;set;}
        public string Column11 {get;set;}
        public string Column12 {get;set;}
        public string Column13 {get;set;}
        public string Column14 {get;set;}
        public string Column15 {get;set;}
    }
    
    
    private List<TestItem> _items;

    protected override void OnInitialized() {
        _items = new List<TestItem>();
        for (int i = 0; i < 20; i++) {
            _items.Add(new TestItem {
                Column1 = $"Value_{i}",
                Column2 = $"Value_{i}",
                Column3 = $"Value_{i}",
                Column4 = $"Value_{i}",
                Column5 = $"Value_{i}",
                Column6 = $"Value_{i}",
                Column7 = $"Value_{i}",
                Column8 = $"Value_{i}",
                Column9 = $"Value_{i}",
                Column10 = $"Value_{i}",
                Column11 = $"Value_{i}",
                Column12 = $"Value_{i}",
                Column13 = $"Value_{i}",
                Column14 = $"Value_{i}",
                Column15 = $"Value_{i}"
            });
        }
    }
}
Table Virtualization

You can virtualize the results of a table to increase rendering speed.

Column1 Column2 Column3 Column4 Column5
<MudTable Items="_items" Height="350px" Breakpoint="Breakpoint.Sm" Virtualize="true" FixedHeader="true">
    <HeaderContent>
        <MudTh>Column1</MudTh>
        <MudTh>Column2</MudTh>
        <MudTh>Column3</MudTh>
        <MudTh>Column4</MudTh>
        <MudTh>Column5</MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd DataLabel="Column1">@context.Column1</MudTd>
        <MudTd DataLabel="Column2">@context.Column2</MudTd>
        <MudTd DataLabel="Column3">@context.Column3</MudTd>
        <MudTd DataLabel="Column4">@context.Column4</MudTd>
        <MudTd DataLabel="Column5">@context.Column5</MudTd>
    </RowTemplate>
</MudTable>
@code {
    public class TestItem
    {
        public string Column1 { get; set; }
        public string Column2 { get; set; }
        public string Column3 { get; set; }
        public string Column4 { get; set; }
        public string Column5 { get; set; }
    }


    private List<TestItem> _items;

    protected override void OnInitialized()
    {
        _items = new List<TestItem>();
        for (int i = 0; i < 20000; i++)
        {
            _items.Add(new TestItem
            {
                Column1 = $"Value_{i}",
                Column2 = $"Value_{i}",
                Column3 = $"Value_{i}",
                Column4 = $"Value_{i}",
                Column5 = $"Value_{i}",
            });
        }
    }

}
Grouping (Basic)

Displays items in a grouped way, with Header and Footer by every group, allowing summaries on both.
NOTE: Grouping and Virtualization should not be used together.

Nr Sign Name Position Molar mass
Group: Other
1 H Hydrogen 0 1.00794"
Total Mass: 1.00794
Group: Noble Gas (p)
2 He Helium 17 4.002602"
10 Ne Neon 17 20.1797"
18 Ar Argon 17 39.948"
36 Kr Krypton 17 83.798"
54 Xe Xenon 17 131.293"
86 Rn Radon 17 222"
118 Og Oganesson 17 294"
Total Mass: 795.221302
Group: Alkaline Earth Metal (s)
3 Li Lithium 0 6.941"
11 Na Sodium 0 22.989769"
19 K Potassium 0 39.0983"
37 Rb Rubidium 0 85.4678"
55 Cs Caesium 0 132.90546"
87 Fr Francium 0 223"
Total Mass: 510.402329
Group: Alkaline Metal (s)
4 Be Beryllium 1 9.012182"
12 Mg Magnesium 1 24.305"
20 Ca Calcium 1 40.078"
38 Sr Strontium 1 87.62"
56 Ba Barium 1 137.327"
88 Ra Radium 1 226"
Total Mass: 524.342182
Group: Metalloid Boron (p)
5 B Boron 12 10.811"
Total Mass: 10.811
Group: Nonmetal Carbon (p)
6 C Carbon 13 12.0107"
Total Mass: 12.0107
Group: Nonmetal Pnictogen (p)
7 N Nitrogen 14 14.0067"
15 P Phosphorus 14 30.973763"
Total Mass: 44.980463
Group: Nonmetal Chalcogen (p)
8 O Oxygen 15 15.9994"
16 S Sulfur 15 32.065"
34 Se Selenium 15 78.96"
Total Mass: 127.02439999999999
Group: Halogen (p)
9 F Fluorine 16 18.998404"
17 Cl Chlorine 16 35.453"
35 Br Bromine 16 79.904"
53 I Iodine 16 126.90447"
85 At Astatine 16 210"
117 Ts Tennessine 16 294"
Total Mass: 765.259874
Group: Poor Boron (p)
13 Al Aluminium 12 26.981539"
31 Ga Gallium 12 69.723"
49 In Indium 12 114.818"
81 Tl Thallium 12 204.3833"
113 Nh Nihonium 12 284"
Total Mass: 699.905839
Group: Metalloid Carbon (p)
14 Si Silicon 13 28.0855"
32 Ge Germanium 13 72.63"
Total Mass: 100.71549999999999
Group: Transition Metal (d)
21 Sc Scandium 2 44.955914"
22 Ti Titanium 3 47.867"
23 V Vanadium 4 50.9415"
24 Cr Chromium 5 51.9961"
25 Mn Manganese 6 54.938046"
26 Fe Iron 7 55.845"
27 Co Cobalt 8 58.933193"
28 Ni Nickel 9 58.6934"
29 Cu Copper 10 63.546"
30 Zn Zinc 11 65.38"
39 Y Yttrium 2 88.90585"
40 Zr Zirconium 3 91.224"
41 Nb Niobium 4 92.90638"
42 Mo Molybdenum 5 95.96"
43 Tc Technetium 6 98"
44 Ru Ruthenium 7 101.07"
45 Rh Rhodium 8 102.9055"
46 Pd Palladium 9 106.42"
47 Ag Silver 10 107.8682"
48 Cd Cadmium 11 112.411"
72 Hf Hafnium 3 178.49"
73 Ta Tantalum 4 180.94788"
74 W Tungsten 5 183.84"
75 Re Rhenium 6 186.207"
76 Os Osmium 7 190.23"
77 Ir Iridium 8 192.217"
78 Pt Platinum 9 195.084"
79 Au Gold 10 196.96657"
80 Hg Mercury 11 200.59"
104 Rf Rutherfordium 3 267"
105 Db Dubnium 4 268"
106 Sg Seaborgium 5 271"
107 Bh Bohrium 6 272"
108 Hs Hassium 7 270"
109 Mt Meitnerium 8 276"
110 Ds Darmstadtium 9 281"
111 Rg Roentgenium 10 280"
112 Cn Copernicium 11 285"
Total Mass: 5725.339533
Group: Metalloid Pnictogen (p)
33 As Arsenic 14 74.9216"
51 Sb Antimony 14 121.76"
Total Mass: 196.6816
Group: Poor Carbon (p)
50 Sn Tin 13 118.71"
82 Pb Lead 13 207.2"
114 Fl Flerovium 13 289"
Total Mass: 614.91
Group: Metalloid Chalcogen (p)
52 Te Tellurium 15 127.6"
84 Po Polonium 15 209"
Total Mass: 336.6
Group: Poor Pnictogen (p)
83 Bi Bismuth 14 208.9804"
115 Mc Moscovium 14 288"
Total Mass: 496.98040000000003
Group: Poor Chalcogen (p)
116 Lv Livermorium 15 293"
Total Mass: 293
@using System.Net.Http.Json
@using MudBlazor.Examples.Data.Models
@inject HttpClient httpClient

<style>
    .mud-table-cell-custom-group {
        font-weight: 500;
    }

    .mud-table-cell-custom-group-footer {
        padding-bottom: 50px;
        text-align: right;
    }
</style>

<MudTable Hover="true" Breakpoint="Breakpoint.Sm" Height="500px" FixedHeader="true"
          Items="@Elements"
          Virtualize="@_virtualize"
          GroupBy="@_groupDefinition"
          GroupHeaderStyle="background-color:var(--mud-palette-background-gray)"
          GroupFooterClass="mb-4"
          Dense="_dense"
          MultiSelection="_multiSelect">
    <ColGroup>
        @if (_multiSelect)
        {
            <col style="width: 60px;" />
        }
        @if (_groupDefinition.Expandable)
        {
            <col style="width: 60px;" />
        }
        <col />
        <col />
        <col />
        <col />
        <col />
    </ColGroup>
    <HeaderContent>
        <MudTh>Nr</MudTh>
        <MudTh>Sign</MudTh>
        <MudTh>Name</MudTh>
        <MudTh>Position</MudTh>
        <MudTh>Molar mass</MudTh>
    </HeaderContent>
    <GroupHeaderTemplate>
        <MudTh Class="mud-table-cell-custom-group" colspan="5">@($"{context.GroupName}: {context.Key}")</MudTh>
    </GroupHeaderTemplate>
    <RowTemplate>
        <MudTd DataLabel="Nr">@context.Number</MudTd>
        <MudTd DataLabel="Sign">@context.Sign</MudTd>
        <MudTd DataLabel="Name">@context.Name</MudTd>
        <MudTd DataLabel="Position">@context.Position</MudTd>
        <MudTd Style="text-align: right" DataLabel="Molar mass">@context.Molar"</MudTd>
    </RowTemplate>
    <GroupFooterTemplate>
        <MudTh Class="mud-table-cell-custom-group mud-table-cell-custom-group-footer" colspan="5">Total Mass: @context.Items.Sum((e) => e.Molar)</MudTh>
    </GroupFooterTemplate>
</MudTable>

<MudSwitch @bind-Value="_dense" Color="Color.Primary">Dense</MudSwitch>
<MudSwitch @bind-Value="_multiSelect" Color="Color.Primary">MultiSelect</MudSwitch>
<MudSwitch @bind-Value="_virtualize" Color="Color.Primary">Virtualize</MudSwitch>
<MudSwitch @bind-Value="_groupDefinition.Indentation" Color="Color.Primary">Indentation</MudSwitch>
<MudSwitch @bind-Value="_groupDefinition.Expandable" Color="Color.Primary">Expandable</MudSwitch>
@code { 
    private bool _dense = false;
    private bool _multiSelect = true;
    private bool _virtualize = false;    

    private TableGroupDefinition<Element> _groupDefinition = new()
    {
        GroupName = "Group",
        Indentation = false,
        Expandable = false,
        Selector = (e) => e.Group
    };

    private IEnumerable<Element> Elements = new List<Element>();

    protected override async Task OnInitializedAsync()
    {
        Elements = await httpClient.GetFromJsonAsync<List<Element>>("webapi/periodictable");
    }
}
Grouping (Basic) - Initially collapsed

Displays items in a grouped way, but the groups are all collapsed as default.
Groups can be expanded or collapsed all at once by calling ExpandAllGroups() or CollapseAllGroups().

Nr Sign Name Position Molar mass
Group: Other
Group: Noble Gas (p)
Group: Alkaline Earth Metal (s)
Group: Alkaline Metal (s)
Group: Metalloid Boron (p)
Group: Nonmetal Carbon (p)
Group: Nonmetal Pnictogen (p)
Group: Nonmetal Chalcogen (p)
Group: Halogen (p)
Group: Poor Boron (p)
Group: Metalloid Carbon (p)
Group: Transition Metal (d)
Group: Metalloid Pnictogen (p)
Group: Poor Carbon (p)
Group: Metalloid Chalcogen (p)
Group: Poor Pnictogen (p)
Group: Poor Chalcogen (p)
@using System.Net.Http.Json
@using MudBlazor.Examples.Data.Models
@inject HttpClient httpClient

<style>
    .mud-table-cell-custom-group {
        font-weight: 500;
    }

    .mud-table-cell-custom-group-footer {
        padding-bottom: 50px;
        text-align: right;
    }
</style>

<MudTable Hover="true" Breakpoint="Breakpoint.Sm" Height="500px" FixedHeader="true"
          Items="@Elements"
          GroupBy="@_groupDefinition"
          GroupHeaderStyle="background-color:var(--mud-palette-background-gray)"
          GroupFooterClass="mb-4"
          Dense="true"
          @ref="_tableRef">
    <ColGroup>
        <col style="width: 60px;" />
        <col />
        <col />
        <col />
        <col />
        <col />
    </ColGroup>
    <HeaderContent>
        <MudTh>Nr</MudTh>
        <MudTh>Sign</MudTh>
        <MudTh>Name</MudTh>
        <MudTh>Position</MudTh>
        <MudTh>Molar mass</MudTh>
    </HeaderContent>
    <GroupHeaderTemplate>
        <MudTh Class="mud-table-cell-custom-group" colspan="5">@($"{context.GroupName}: {context.Key}") </MudTh>
    </GroupHeaderTemplate>
    <RowTemplate>
        <MudTd DataLabel="Nr">@context.Number</MudTd>
        <MudTd DataLabel="Sign">@context.Sign</MudTd>
        <MudTd DataLabel="Name">@context.Name</MudTd>
        <MudTd DataLabel="Position">@context.Position</MudTd>
        <MudTd Style="text-align: right" DataLabel="Molar mass">@context.Molar"</MudTd>
    </RowTemplate>
    <GroupFooterTemplate>
        <MudTh Class="mud-table-cell-custom-group mud-table-cell-custom-group-footer" colspan="5">Total Mass: @context.Items.Sum((e) => e.Molar)</MudTh>
    </GroupFooterTemplate>
</MudTable>

<MudButton Variant="Variant.Filled" Color="Color.Primary" Class="mt-3" OnClick="@((args) => _tableRef?.ExpandAllGroups())">Expand all groups</MudButton>
<MudButton Variant="Variant.Filled" Color="Color.Secondary" Class="mt-3 ml-3" OnClick="@((args) => _tableRef?.CollapseAllGroups())">Collapse all groups</MudButton>
@code {
    private MudTable<Element> _tableRef;

    private TableGroupDefinition<Element> _groupDefinition = new()
        {
            GroupName = "Group",
            Indentation = false,
            Expandable = true,
            IsInitiallyExpanded = false,
            Selector = (e) => e.Group
        };

    private IEnumerable<Element> Elements = new List<Element>();

    protected override async Task OnInitializedAsync()
    {
        Elements = await httpClient.GetFromJsonAsync<List<Element>>("webapi/periodictable");
    }
}
Grouping (Multi Levels)

Displays items recursively grouped.

Total items: 88 - Selected items: 0

Nr Sign Name Group Position Molar mass
Group: Other
Position: 0
1 H Hydrogen Other 0 1.00794
Total Mass: 1.00794
Total Mass: 1.00794
Group: Noble Gas (p)
Position: 17
2 He Helium Noble Gas (p) 17 4.002602
10 Ne Neon Noble Gas (p) 17 20.1797
18 Ar Argon Noble Gas (p) 17 39.948
36 Kr Krypton Noble Gas (p) 17 83.798
54 Xe Xenon Noble Gas (p) 17 131.293
86 Rn Radon Noble Gas (p) 17 222
118 Og Oganesson Noble Gas (p) 17 294
Total Mass: 795.221302
Total Mass: 795.221302
Group: Alkaline Earth Metal (s)
Position: 0
3 Li Lithium Alkaline Earth Metal (s) 0 6.941
11 Na Sodium Alkaline Earth Metal (s) 0 22.989769
19 K Potassium Alkaline Earth Metal (s) 0 39.0983
37 Rb Rubidium Alkaline Earth Metal (s) 0 85.4678
55 Cs Caesium Alkaline Earth Metal (s) 0 132.90546
87 Fr Francium Alkaline Earth Metal (s) 0 223
Total Mass: 510.402329
Total Mass: 510.402329
Group: Alkaline Metal (s)
Position: 1
4 Be Beryllium Alkaline Metal (s) 1 9.012182
12 Mg Magnesium Alkaline Metal (s) 1 24.305
20 Ca Calcium Alkaline Metal (s) 1 40.078
38 Sr Strontium Alkaline Metal (s) 1 87.62
56 Ba Barium Alkaline Metal (s) 1 137.327
88 Ra Radium Alkaline Metal (s) 1 226
Total Mass: 524.342182
Total Mass: 524.342182
Group: Metalloid Boron (p)
Position: 12
5 B Boron Metalloid Boron (p) 12 10.811
Total Mass: 10.811
Total Mass: 10.811
Group: Nonmetal Carbon (p)
Position: 13
6 C Carbon Nonmetal Carbon (p) 13 12.0107
Total Mass: 12.0107
Total Mass: 12.0107
Group: Nonmetal Pnictogen (p)
Position: 14
7 N Nitrogen Nonmetal Pnictogen (p) 14 14.0067
15 P Phosphorus Nonmetal Pnictogen (p) 14 30.973763
Total Mass: 44.980463
Total Mass: 44.980463
Group: Nonmetal Chalcogen (p)
Position: 15
8 O Oxygen Nonmetal Chalcogen (p) 15 15.9994
16 S Sulfur Nonmetal Chalcogen (p) 15 32.065
34 Se Selenium Nonmetal Chalcogen (p) 15 78.96
Total Mass: 127.02439999999999
Total Mass: 127.02439999999999
Group: Halogen (p)
Position: 16
9 F Fluorine Halogen (p) 16 18.998404
17 Cl Chlorine Halogen (p) 16 35.453
35 Br Bromine Halogen (p) 16 79.904
53 I Iodine Halogen (p) 16 126.90447
85 At Astatine Halogen (p) 16 210
117 Ts Tennessine Halogen (p) 16 294
Total Mass: 765.259874
Total Mass: 765.259874
Group: Poor Boron (p)
Position: 12
13 Al Aluminium Poor Boron (p) 12 26.981539
31 Ga Gallium Poor Boron (p) 12 69.723
49 In Indium Poor Boron (p) 12 114.818
81 Tl Thallium Poor Boron (p) 12 204.3833
113 Nh Nihonium Poor Boron (p) 12 284
Total Mass: 699.905839
Total Mass: 699.905839
Group: Metalloid Carbon (p)
Position: 13
14 Si Silicon Metalloid Carbon (p) 13 28.0855
32 Ge Germanium Metalloid Carbon (p) 13 72.63
Total Mass: 100.71549999999999
Total Mass: 100.71549999999999
Group: Transition Metal (d)
Position: 2
21 Sc Scandium Transition Metal (d) 2 44.955914
39 Y Yttrium Transition Metal (d) 2 88.90585
Total Mass: 133.861764
Position: 3
22 Ti Titanium Transition Metal (d) 3 47.867
40 Zr Zirconium Transition Metal (d) 3 91.224
72 Hf Hafnium Transition Metal (d) 3 178.49
104 Rf Rutherfordium Transition Metal (d) 3 267
Total Mass: 584.581
Position: 4
23 V Vanadium Transition Metal (d) 4 50.9415
41 Nb Niobium Transition Metal (d) 4 92.90638
73 Ta Tantalum Transition Metal (d) 4 180.94788
105 Db Dubnium Transition Metal (d) 4 268
Total Mass: 592.79576
Position: 5
24 Cr Chromium Transition Metal (d) 5 51.9961
42 Mo Molybdenum Transition Metal (d) 5 95.96
74 W Tungsten Transition Metal (d) 5 183.84
106 Sg Seaborgium Transition Metal (d) 5 271
Total Mass: 602.7961
Position: 6
25 Mn Manganese Transition Metal (d) 6 54.938046
43 Tc Technetium Transition Metal (d) 6 98
75 Re Rhenium Transition Metal (d) 6 186.207
107 Bh Bohrium Transition Metal (d) 6 272
Total Mass: 611.145046
Position: 7
26 Fe Iron Transition Metal (d) 7 55.845
44 Ru Ruthenium Transition Metal (d) 7 101.07
76 Os Osmium Transition Metal (d) 7 190.23
108 Hs Hassium Transition Metal (d) 7 270
Total Mass: 617.145
Position: 8
27 Co Cobalt Transition Metal (d) 8 58.933193
45 Rh Rhodium Transition Metal (d) 8 102.9055
77 Ir Iridium Transition Metal (d) 8 192.217
109 Mt Meitnerium Transition Metal (d) 8 276
Total Mass: 630.055693
Position: 9
28 Ni Nickel Transition Metal (d) 9 58.6934
46 Pd Palladium Transition Metal (d) 9 106.42
78 Pt Platinum Transition Metal (d) 9 195.084
110 Ds Darmstadtium Transition Metal (d) 9 281
Total Mass: 641.1974
Position: 10
29 Cu Copper Transition Metal (d) 10 63.546
47 Ag Silver Transition Metal (d) 10 107.8682
79 Au Gold Transition Metal (d) 10 196.96657
111 Rg Roentgenium Transition Metal (d) 10 280
Total Mass: 648.38077
Position: 11
30 Zn Zinc Transition Metal (d) 11 65.38
48 Cd Cadmium Transition Metal (d) 11 112.411
80 Hg Mercury Transition Metal (d) 11 200.59
112 Cn Copernicium Transition Metal (d) 11 285
Total Mass: 663.381
Total Mass: 5725.339533
Group: Metalloid Pnictogen (p)
Position: 14
33 As Arsenic Metalloid Pnictogen (p) 14 74.9216
51 Sb Antimony Metalloid Pnictogen (p) 14 121.76
Total Mass: 196.6816
Total Mass: 196.6816
Group: Poor Carbon (p)
Position: 13
50 Sn Tin Poor Carbon (p) 13 118.71
82 Pb Lead Poor Carbon (p) 13 207.2
114 Fl Flerovium Poor Carbon (p) 13 289
Total Mass: 614.91
Total Mass: 614.91
Group: Metalloid Chalcogen (p)
Position: 15
52 Te Tellurium Metalloid Chalcogen (p) 15 127.6
84 Po Polonium Metalloid Chalcogen (p) 15 209
Total Mass: 336.6
Total Mass: 336.6
Group: Poor Pnictogen (p)
Position: 14
83 Bi Bismuth Poor Pnictogen (p) 14 208.9804
115 Mc Moscovium Poor Pnictogen (p) 14 288
Total Mass: 496.98040000000003
Total Mass: 496.98040000000003
Group: Poor Chalcogen (p)
Position: 15
116 Lv Livermorium Poor Chalcogen (p) 15 293
Total Mass: 293
Total Mass: 293
@using System.Net.Http.Json
@using MudBlazor.Examples.Data.Models
@inject HttpClient httpClient

<style>
    .mud-table-cell-custom-group {
        font-weight: 500;
    }

    .mud-table-cell-custom-group-footer {
        padding-bottom: 50px;
        text-align: right;
    }
</style>

<MudText>Total items: @Elements?.Count() - Selected items: @selectedItems?.Count</MudText>

<MudTable Hover="true" Breakpoint="Breakpoint.Sm" Height="500px" FixedHeader="true"
          Items="@Elements"
          GroupBy="@_groupDefinition"
          GroupHeaderStyle="background-color:var(--mud-palette-background-gray)"
          GroupFooterClass="mb-4"
          Dense="_dense"
          MultiSelection="_multiSelect"
          @bind-SelectedItems="selectedItems">
    <HeaderContent>
        <MudTh>Nr</MudTh>
        <MudTh>Sign</MudTh>
        <MudTh>Name</MudTh>
        <MudTh>Group</MudTh>
        <MudTh>Position</MudTh>
        <MudTh>Molar mass</MudTh>
    </HeaderContent>
    <GroupHeaderTemplate>
        <MudTh Class="mud-table-cell-custom-group" colspan="6">@($"{context.GroupName}: {context.Key}")</MudTh>
    </GroupHeaderTemplate>
    <RowTemplate>
        <MudTd DataLabel="Nr">@context.Number</MudTd>
        <MudTd DataLabel="Sign">@context.Sign</MudTd>
        <MudTd DataLabel="Name">@context.Name</MudTd>
        <MudTd DataLabel="Group">@context.Group</MudTd>
        <MudTd DataLabel="Position">@context.Position</MudTd>
        <MudTd Style="text-align:right" DataLabel="Molar mass">@context.Molar</MudTd>
    </RowTemplate>
    <GroupFooterTemplate>
        <MudTh Class="mud-table-cell-custom-group mud-table-cell-custom-group-footer" colspan="6">Total Mass: @context.Items.Sum((e) => e.Molar)</MudTh>
    </GroupFooterTemplate>
</MudTable>
<MudSwitch @bind-Value="_dense" Color="Color.Primary">Dense</MudSwitch>
<MudSwitch @bind-Value="_multiSelect" Color="Color.Primary">MultiSelect</MudSwitch>
<MudSwitch @bind-Value="_groupDefinition.Indentation" Color="Color.Primary">Indentation</MudSwitch>
<MudSwitch @bind-Value="_groupDefinition.Expandable" Color="Color.Primary">Expandable (Root Level)</MudSwitch>
<MudSwitch @bind-Value="_groupDefinition.InnerGroup.Expandable" Color="Color.Primary">Expandable (Second Level)</MudSwitch>
@code {
    private bool _dense = false;
    private bool _multiSelect = true;
    private HashSet<Element> selectedItems = new HashSet<Element>();

    private TableGroupDefinition<Element> _groupDefinition = new TableGroupDefinition<Element>()
    {
        GroupName = "Group",
        Indentation = false,
        Expandable = false,
        Selector = (e) => e.Group,
        InnerGroup = new TableGroupDefinition<Element>()
        {
            GroupName = "Position",
            Expandable = false,
            Selector = (e) => e.Position
        }

    };


    private IEnumerable<Element> Elements = new List<Element>();

    protected override async Task OnInitializedAsync()
    {
        Elements = await httpClient.GetFromJsonAsync<List<Element>>("webapi/periodictable");
    }

}
An unhandled error has occurred. Reload 🗙