MudBlazor

Community Support

Discord

GitHub Discussions

Tools and resources

TryMudBlazor

Templates

Sponsor

Open Collective


Switch to Blazor wasm
Toggle light/dark theme
GitHub repository
Toggle right-to-left/left-to-right

Community Support

Discord

GitHub Discussions

Tools and resources

TryMudBlazor

Templates

Sponsor

Open Collective

Table

A sortable, filterable table with multiselection and pagination.

See Table API for parameter documentation.

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
Show code example
Edit on TryMudBlazor
Copy Code
View the source on GitHub
@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-Checked="_hidePosition">Hide <b>position</b> when Breakpoint=Xs</MudSwitch>
<MudSwitch @bind-Checked="_loading">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");
    }
}

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.

Periodic Elements
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

Rows per page:

10

10

25

50

100

1-10 of 88

Selected:

Show code example
Edit on TryMudBlazor
Copy Code
View the source on GitHub
@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>(FilterFunc)" @bind-SelectedItem="selectedItem">
    <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>
    <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-Checked="@hover" Color="Color.Primary">Hover</MudSwitch>
    <MudSwitch @bind-Checked="@dense" Color="Color.Secondary">Dense</MudSwitch>
    <MudSwitch @bind-Checked="@striped" Color="Color.Tertiary">Striped</MudSwitch>
    <MudSwitch @bind-Checked="@bordered" Color="Color.Warning">Bordered</MudSwitch>
    <MudSpacer />
    <MudText Inline="true" Class="align-self-center" Style="min-width:200px;">Selected: @selectedItem?.Name</MudText>
</div>
@code {
    private bool dense = false;
    private bool hover = true;
    private bool striped = false;
    private bool bordered = false;
    private string searchString = "";
    private Element selectedItem = 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 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;
    }
}

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. Click on a header to sort the table by that column, then click to cycle through sorting directions. Sorting can be allowed and disallowed on the column level with the property Enabled.

Name

Nr

Sign

Name

Position

Mass

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

Rows per page:

50

100

1-10 of 88

Hide code example
Edit on TryMudBlazor
Copy Code
View the source on GitHub
@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[]{50, 100}" />
    </PagerContent>
</MudTable>

<MudSwitch @bind-Checked="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

Setting MultiSelection="true" will enable selection check boxes for selecting multiple lines.

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

Rows per page:

50

100

1-10 of 88

Selected items:

Hide code example
Edit on TryMudBlazor
Copy Code
View the source on GitHub
@using System.Net.Http.Json
@using MudBlazor.Examples.Data.Models
@inject HttpClient httpClient

<MudTable Items="@Elements" MultiSelection="true" @bind-SelectedItems="selectedItems" Hover="@hover">
    <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[]{50, 100}" />
    </PagerContent>
    <FooterContent>
        <MudTd colspan="5">Select All</MudTd>
    </FooterContent>
</MudTable>
<MudText Inline="true">Selected items: @(selectedItems==null ? "" : string.Join(", ", selectedItems.OrderBy(x=>x.Sign).Select(x=>x.Sign)))</MudText>
@code {
    private bool hover = true;
    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");
    } 
}

Fixed header and footer

Set FixedHeader="true" to make the header sticky when scrolling the table.
The same for FixedFooter="true" to show the footer even when the table is not scrolled all the way down.
The table will scroll if you constrain its height using Height="400px", for instance.

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

Rows per page:

50

100

1-10 of 88

Show code example
Edit on TryMudBlazor
Copy Code
View the source on GitHub
@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-Checked="@fixed_header">Fixed Header</MudSwitch>
<MudSwitch @bind-Checked="@fixed_footer">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");
    }
}

With 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

Rows per page:

10

10

25

50

100

1-10 of 88

Show code example
Edit on TryMudBlazor
Copy Code
View the source on GitHub
@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.

Periodic Elements
Name

Nr

Sign

Name

Position

Mass

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

Rows per page:

10

10

25

50

100

1-10 of 88

Selected:

Show inline-edit event log
Show code example
Edit on TryMudBlazor
Copy Code
View the source on GitHub
@using System.Net.Http.Json
@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="selectedItem" SortLabel="Sort By" 
 CommitEditTooltip="Commit Edit" OnCommitEditClick="@(() => Snackbar.Add("Commit Edit Handler Invoked"))" RowEditPreview="BackupItem" RowEditCancel="ResetItemToOriginalValues" RowEditCommit="ItemHasBeenCommitted">
    <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>
        <col style="width:50px;" />
        <col style="width:80px;" />
        <col style="width:50%;" />
        <col />
        <col />
        <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>
</MudTable>
<MudSwitch @bind-Checked="@hover" Color="Color.Primary">Hover</MudSwitch>
<MudSwitch @bind-Checked="@dense" Color="Color.Secondary">Dense</MudSwitch>
<MudSwitch @bind-Checked="@ronly" Color="Color.Tertiary">Read Only</MudSwitch>
<MudSwitch @bind-Checked="@canCancelEdit" Color="Color.Info">Can Cancel Edit</MudSwitch>
<MudText Inline="true">Selected: @selectedItem?.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 string searchString = "";
    private Element selectedItem = null;
    private Element elementBeforeEdit;
    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 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} cancelled");
    }

    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.

Periodic Elements
Nr Sign Name Position Molar mass

Rows per page:

10

25

50

100

1-0 of 0

Show code example
Edit on TryMudBlazor
Copy Code
View the source on GitHub
@using System.Net.Http.Json
@using MudBlazor.Examples.Data.Models
@inject HttpClient httpClient

<MudTable ServerData="@(new Func<TableState, Task<TableData<Element>>>(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>
    <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)
    {
        IEnumerable<Element> data = await httpClient.GetFromJsonAsync<List<Element>>("webapi/periodictable");
        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();
    }
}

Header and Footer

By default, you can put a list of <MudTh> inside <HeaderContent> and <MudTd> inside <FooterContent>, MudTable will automatically manage the table row for you, including the select-all column and adding an empty column for editable tables.
If you need to customize the behavior, as well as rendering multiple header or footer rows, you can set the CustomHeader and CustomFooter attributes to true.
Then setting a list of <MudTHeadRow> or <MudTFootRow> with their respective cells will render exactly what's required inside the table header and footer.

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
Show code example
Edit on TryMudBlazor
Copy Code
View the source on GitHub
@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 IsCheckable="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 IsCheckable="true">
            <MudTd colspan="5">Selected: @selectedItems.Count</MudTd>
        </MudTFootRow>
    </FooterContent>
</MudTable>

<MudSwitch @bind-Checked="_hidePosition">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");
    }
}

Table With related data

Making use of the <ChildRowContent> allows more control over the layout for scenarios such as showing the related address data for each person below.

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
Show code example
Edit on TryMudBlazor
Copy Code
View the source on GitHub
<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;
    }
}

Table with 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
Show code example
Edit on TryMudBlazor
Copy Code
View the source on GitHub
<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
Show code example
Edit on TryMudBlazor
Copy Code
View the source on GitHub
<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}",
            });
        }
    }

}
An error has occurred. This application may no longer respond until reloaded. Reload 🗙