Nesco.MudDataTableCRUD 3.0.1

dotnet add package Nesco.MudDataTableCRUD --version 3.0.1
                    
NuGet\Install-Package Nesco.MudDataTableCRUD -Version 3.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Nesco.MudDataTableCRUD" Version="3.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Nesco.MudDataTableCRUD" Version="3.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Nesco.MudDataTableCRUD" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Nesco.MudDataTableCRUD --version 3.0.1
                    
#r "nuget: Nesco.MudDataTableCRUD, 3.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Nesco.MudDataTableCRUD@3.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Nesco.MudDataTableCRUD&version=3.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Nesco.MudDataTableCRUD&version=3.0.1
                    
Install as a Cake Tool

MudDataTableCRUD

A comprehensive CRUD data table component for Blazor applications built on top of MudBlazor. Provides advanced features including filtering, sorting, grouping, Excel export, and customizable dialogs for Create, Read, Update, and Delete operations.

Features

  • ✅ Full CRUD operations (Create, Read, Update, Delete)
  • ✅ Advanced column configuration with multiple render options
  • ✅ Built-in filtering and searching capabilities
  • ✅ Column sorting and grouping
  • ✅ Excel export functionality
  • ✅ Customizable dialogs for data entry
  • ✅ Child row expansion support
  • ✅ Row selection (single and multiple)
  • ✅ Conditional CRUD operations
  • ✅ REST API integration support
  • ✅ Responsive design
  • ✅ Column resizing and hiding/showing
  • ✅ Pagination with customizable page sizes

Installation

NuGet Package

dotnet add package MudDataTableCRUD

Prerequisites

This package requires:

  • .NET 8.0 or higher
  • MudBlazor 8.0.0 or higher
  • EPPlus 7.5.2 or higher (for Excel export)

Setup

  1. Add JavaScript Reference

Add the following to your index.html (Blazor WebAssembly) or _Host.cshtml/_Layout.cshtml (Blazor Server):

<script src="_content/MudDataTableCRUD/js/mudDataTableCRUD.js"></script>
  1. Register Services

In your Program.cs:

Option A: Simple registration (using default HttpClient)

using MudDataTableCRUD.Extensions;

builder.Services.AddMudDataTableCRUD();

Option B: With custom HttpClient configuration (Recommended)

using MudDataTableCRUD.Extensions;

builder.Services.AddMudDataTableCRUD(
    configureClient: client =>
    {
        client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress);
        client.Timeout = TimeSpan.FromMinutes(5);
        client.DefaultRequestHeaders.Add("Accept", "application/json");
    });

Option C: With base address shorthand

using MudDataTableCRUD.Extensions;

// Using string base address
builder.Services.AddMudDataTableCRUD(builder.HostEnvironment.BaseAddress);

// OR using Uri
builder.Services.AddMudDataTableCRUD(new Uri("https://api.example.com"));

Note: The library is completely self-contained for Excel export functionality. You don't need to register any additional services.

The AddMudDataTableCRUD extension method registers:

  • Named HttpClient (using Constants.HttpClientName) for REST API calls with the configured settings

Excel export functionality is built-in and requires no additional configuration.

  1. Add Using Directive

In your _Imports.razor:

@using MudDataTableCRUD.Components

Usage Examples

Example 1: Simple Read-Only Table

The simplest use case - display data without CRUD operations:

@page "/simple-table"

<MudDataTableCRUD T="Customer"
                  Title="Customers"
                  Data="@customers">
    <TableColumns>
        <TableColumn T="Customer" Title="ID" Property="@(c => c.Id)" Width="10%" />
        <TableColumn T="Customer" Title="Name" Property="@(c => c.Name)" Width="30%" />
        <TableColumn T="Customer" Title="Email" Property="@(c => c.Email)" Width="30%" />
        <TableColumn T="Customer" Title="Phone" Property="@(c => c.Phone)" Width="30%" />
    </TableColumns>
</MudDataTableCRUD>

@code {
    private List<Customer> customers = new()
    {
        new Customer { Id = 1, Name = "John Doe", Email = "john@example.com", Phone = "555-1234" },
        new Customer { Id = 2, Name = "Jane Smith", Email = "jane@example.com", Phone = "555-5678" }
    };

    public class Customer : ICloneable
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public string Phone { get; set; }

        public object Clone() => this.MemberwiseClone();
    }
}

Example 2: CRUD Operations with Dialog

Enable Create, Update, and Delete operations with custom dialogs:

@page "/crud-table"
@inject ISnackbar Snackbar

<MudDataTableCRUD T="Product"
                  Title="Products"
                  Data="@products"
                  DataChanged="@OnDataChanged"
                  CRUD="CUD"
                  OnCreate="@HandleCreate"
                  OnUpdate="@HandleUpdate"
                  OnDelete="@HandleDelete"
                  OnSuccess="@((msg) => Snackbar.Add(msg, Severity.Success))"
                  OnError="@((msg) => Snackbar.Add(msg, Severity.Error))">
    <TableColumns>
        <TableColumn T="Product" Title="ID" Property="@(p => p.Id)" Width="10%" InitialSort="true" InitialSortDirection="SortDirection.Descending" />
        <TableColumn T="Product" Title="Name" Property="@(p => p.Name)" Width="30%" Search="true" />
        <TableColumn T="Product" Title="Price" Property="@(p => p.Price)" Width="20%" Format="N2" />
        <TableColumn T="Product" Title="Stock" Property="@(p => p.Stock)" Width="20%" />
        <TableColumn T="Product" Title="Active" Property="@(p => p.IsActive)" Width="20%" />
    </TableColumns>
    <DialogBody Context="editContext">
        <MudGrid>
            <MudItem md="6">
                <MudTextField @bind-Value="editContext.Name" Label="Product Name" Required="true" />
            </MudItem>
            <MudItem md="6">
                <MudNumericField @bind-Value="editContext.Price" Label="Price" Format="N2" />
            </MudItem>
            <MudItem md="6">
                <MudNumericField @bind-Value="editContext.Stock" Label="Stock Quantity" />
            </MudItem>
            <MudItem md="6">
                <MudCheckBox @bind-Value="editContext.IsActive" Label="Active" />
            </MudItem>
        </MudGrid>
    </DialogBody>
</MudDataTableCRUD>

@code {
    private List<Product> products = new();

    protected override void OnInitialized()
    {
        // Initialize with sample data
        products = new List<Product>
        {
            new Product { Id = 1, Name = "Laptop", Price = 999.99m, Stock = 15, IsActive = true },
            new Product { Id = 2, Name = "Mouse", Price = 29.99m, Stock = 50, IsActive = true }
        };
    }

    private void OnDataChanged(List<Product> updatedData)
    {
        products = updatedData;
    }

    private Task HandleCreate(Product product)
    {
        product.Id = products.Max(p => p.Id) + 1;
        return Task.CompletedTask;
    }

    private Task HandleUpdate(Product product)
    {
        // Handle update logic
        return Task.CompletedTask;
    }

    private Task HandleDelete(Product product)
    {
        // Handle delete logic
        return Task.CompletedTask;
    }

    public class Product : ICloneable
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
        public int Stock { get; set; }
        public bool IsActive { get; set; }

        public object Clone() => this.MemberwiseClone();
    }
}

Example 3: REST API Integration

Load data from a REST API and perform CRUD operations:

@page "/api-table"
@inject ISnackbar Snackbar

<MudDataTableCRUD T="CustomerDTO"
                  @ref="_customerTable"
                  Title="Customers from API"
                  Url="api/customers"
                  CRUD="CRUD"
                  UseDefaultRestCalls="true"
                  OnUrlUpdated="@OnDataLoaded"
                  ShowRefreshButton="true"
                  ShowExportToExcelButton="true">
    <TableColumns>
        <TableColumn T="CustomerDTO" Title="ID" Property="@(c => c.Id)" Width="10%" InitialSort="true" InitialSortDirection="SortDirection.Descending" />
        <TableColumn T="CustomerDTO" Title="Name" Property="@(c => c.Name)" Width="25%" Search="true" Sort="true" />
        <TableColumn T="CustomerDTO" Title="Email" Property="@(c => c.Email)" Width="25%" Search="true" />
        <TableColumn T="CustomerDTO" Title="Phone" Property="@(c => c.Phone)" Width="20%" />
        <TableColumn T="CustomerDTO" Title="Created" Property="@(c => c.CreatedDate)" Width="20%" Format="dd-MMM-yy" />
    </TableColumns>
    <DialogBody Context="editContext">
        <MudGrid>
            <MudItem md="6">
                <MudTextField @bind-Value="editContext.Name" Label="Customer Name" Required="true" />
            </MudItem>
            <MudItem md="6">
                <MudTextField @bind-Value="editContext.Email" Label="Email" InputType="InputType.Email" />
            </MudItem>
            <MudItem md="6">
                <MudTextField @bind-Value="editContext.Phone" Label="Phone" />
            </MudItem>
            <MudItem md="6">
                <MudTextField @bind-Value="editContext.Address" Label="Address" Lines="3" />
            </MudItem>
        </MudGrid>
    </DialogBody>
</MudDataTableCRUD>

@code {
    private MudDataTableCRUD<CustomerDTO> _customerTable;

    private Task OnDataLoaded(List<CustomerDTO> data)
    {
        // Handle data loaded event
        return Task.CompletedTask;
    }

    public class CustomerDTO : ICloneable
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public string Phone { get; set; }
        public string Address { get; set; }
        public DateTime CreatedDate { get; set; }

        public object Clone() => this.MemberwiseClone();
    }
}

Example 4: Advanced Features - Filtering, Grouping, and Custom Cells

@page "/advanced-table"

<MudDataTableCRUD T="SalesOrder"
                  Title="Sales Orders"
                  Data="@orders"
                  Filterable="true"
                  Groupable="true"
                  GroupExpanded="true"
                  ColumnResizeMode="ResizeMode.Column"
                  Hideable="true"
                  ShowColumnOptions="true">
    <TableColumns>
        <TableColumn T="SalesOrder" Title="Order #" Property="@(o => o.OrderNumber)" Width="15%" Search="true" Sort="true" InitialSort="true" />

        <TableColumn T="SalesOrder" Title="Customer" Property="@(o => o.CustomerName)" Width="20%"
                     Search="true" Filter="true" Grouping="true" GroupBy="@_groupByCustomer">
            <GroupTemplate>
                <span style="font-weight:bold">
                    Customer: @context.Grouping.Key
                    <MudChip T="string" Variant="Variant.Outlined" Color="Color.Primary" Size="Size.Small">
                        @context.Grouping.Count() Orders
                    </MudChip>
                </span>
            </GroupTemplate>
        </TableColumn>

        <TableColumn T="SalesOrder" Title="Status" Property="@(o => o.Status)" Width="15%" Filter="true">
            <Cell Context="cellContext">
                @if (cellContext.Status == "Completed")
                {
                    <MudChip T="string" Color="Color.Success" Size="Size.Small">Completed</MudChip>
                }
                else if (cellContext.Status == "Pending")
                {
                    <MudChip T="string" Color="Color.Warning" Size="Size.Small">Pending</MudChip>
                }
                else
                {
                    <MudChip T="string" Color="Color.Error" Size="Size.Small">Cancelled</MudChip>
                }
            </Cell>
        </TableColumn>

        <TableColumn T="SalesOrder" Title="Amount" Property="@(o => o.TotalAmount)" Width="15%" Format="N2" Sort="true"
                     CellBackgroundColorFunction="@(o => o.TotalAmount > 1000 ? \"#90EE90\" : \"transparent\")" />

        <TableColumn T="SalesOrder" Title="Order Date" Property="@(o => o.OrderDate)" Width="20%" Format="dd-MMM-yyyy" Sort="true" />

        <TableColumn T="SalesOrder" Title="Actions" Width="15%">
            <Cell Context="cellContext">
                <MudIconButton Icon="@Icons.Material.Filled.Visibility" Size="Size.Small" Color="Color.Info"
                               OnClick="@(() => ViewOrder(cellContext))" />
                <MudIconButton Icon="@Icons.Material.Filled.Print" Size="Size.Small" Color="Color.Default"
                               OnClick="@(() => PrintOrder(cellContext))" />
            </Cell>
        </TableColumn>
    </TableColumns>
</MudDataTableCRUD>

@code {
    private List<SalesOrder> orders = new();
    private Func<SalesOrder, object> _groupByCustomer = x => x.CustomerName;

    protected override void OnInitialized()
    {
        orders = new List<SalesOrder>
        {
            new SalesOrder { Id = 1, OrderNumber = "SO-001", CustomerName = "Acme Corp", Status = "Completed", TotalAmount = 1500, OrderDate = DateTime.Now.AddDays(-5) },
            new SalesOrder { Id = 2, OrderNumber = "SO-002", CustomerName = "Acme Corp", Status = "Pending", TotalAmount = 800, OrderDate = DateTime.Now.AddDays(-3) },
            new SalesOrder { Id = 3, OrderNumber = "SO-003", CustomerName = "Tech Solutions", Status = "Completed", TotalAmount = 2200, OrderDate = DateTime.Now.AddDays(-1) }
        };
    }

    private void ViewOrder(SalesOrder order)
    {
        // Handle view logic
    }

    private void PrintOrder(SalesOrder order)
    {
        // Handle print logic
    }

    public class SalesOrder : ICloneable
    {
        public int Id { get; set; }
        public string OrderNumber { get; set; }
        public string CustomerName { get; set; }
        public string Status { get; set; }
        public decimal TotalAmount { get; set; }
        public DateTime OrderDate { get; set; }

        public object Clone() => this.MemberwiseClone();
    }
}

Example 5: Child Row Expansion

Display detailed information in expandable child rows:

@page "/child-rows"

<MudDataTableCRUD T="Invoice"
                  Title="Invoices with Line Items"
                  Data="@invoices"
                  ShowChildRowIfExists="true">
    <TableColumns>
        <TableColumn T="Invoice" Title="Invoice #" Property="@(i => i.InvoiceNumber)" Width="20%" />
        <TableColumn T="Invoice" Title="Customer" Property="@(i => i.CustomerName)" Width="30%" />
        <TableColumn T="Invoice" Title="Total" Property="@(i => i.Total)" Width="20%" Format="N2" />
        <TableColumn T="Invoice" Title="Date" Property="@(i => i.InvoiceDate)" Width="30%" Format="dd-MMM-yyyy" />
    </TableColumns>
    <ChildRowContent>
        <MudCard Elevation="0">
            <MudCardHeader>
                <CardHeaderContent>
                    <MudText Typo="Typo.h6">Line Items for @context.InvoiceNumber</MudText>
                </CardHeaderContent>
            </MudCardHeader>
            <MudCardContent>
                <MudTable Items="@context.LineItems" Hover="true" Dense="true" Elevation="0">
                    <HeaderContent>
                        <MudTh>Item</MudTh>
                        <MudTh>Quantity</MudTh>
                        <MudTh>Unit Price</MudTh>
                        <MudTh>Amount</MudTh>
                    </HeaderContent>
                    <RowTemplate>
                        <MudTd>@context.ItemName</MudTd>
                        <MudTd>@context.Quantity</MudTd>
                        <MudTd>@context.UnitPrice.ToString("N2")</MudTd>
                        <MudTd>@((context.Quantity * context.UnitPrice).ToString("N2"))</MudTd>
                    </RowTemplate>
                </MudTable>
            </MudCardContent>
        </MudCard>
    </ChildRowContent>
</MudDataTableCRUD>

@code {
    private List<Invoice> invoices = new();

    protected override void OnInitialized()
    {
        invoices = new List<Invoice>
        {
            new Invoice
            {
                Id = 1,
                InvoiceNumber = "INV-001",
                CustomerName = "Acme Corp",
                InvoiceDate = DateTime.Now,
                LineItems = new List<LineItem>
                {
                    new LineItem { ItemName = "Product A", Quantity = 5, UnitPrice = 100 },
                    new LineItem { ItemName = "Product B", Quantity = 3, UnitPrice = 150 }
                }
            }
        };

        foreach (var invoice in invoices)
        {
            invoice.Total = invoice.LineItems.Sum(l => l.Quantity * l.UnitPrice);
        }
    }

    public class Invoice : ICloneable
    {
        public int Id { get; set; }
        public string InvoiceNumber { get; set; }
        public string CustomerName { get; set; }
        public decimal Total { get; set; }
        public DateTime InvoiceDate { get; set; }
        public List<LineItem> LineItems { get; set; } = new();

        public object Clone()
        {
            var clone = (Invoice)this.MemberwiseClone();
            clone.LineItems = new List<LineItem>(this.LineItems);
            return clone;
        }
    }

    public class LineItem
    {
        public string ItemName { get; set; }
        public int Quantity { get; set; }
        public decimal UnitPrice { get; set; }
    }
}

Example 6: Conditional CRUD with Custom Validation

Control CRUD operations based on conditions and add form validation:

@page "/conditional-crud"
@inject ISnackbar Snackbar

<MudDataTableCRUD T="Employee"
                  Title="Employees"
                  Data="@employees"
                  DataChanged="@OnDataChanged"
                  CRUD="CRUD"
                  ConditionalCRUD="true"
                  ConditionForUpdate="@((e) => e.IsActive)"
                  ConditionForDelete="@((e) => !e.IsActive)"
                  UseFormValidationForDialog="true"
                  FromValidationFunction="@ValidateEmployee"
                  OnCreate="@HandleCreate"
                  OnUpdate="@HandleUpdate"
                  OnDelete="@HandleDelete">
    <TableColumns>
        <TableColumn T="Employee" Title="ID" Property="@(e => e.Id)" Width="10%" />
        <TableColumn T="Employee" Title="Name" Property="@(e => e.Name)" Width="25%" Search="true" />
        <TableColumn T="Employee" Title="Email" Property="@(e => e.Email)" Width="25%" />
        <TableColumn T="Employee" Title="Department" Property="@(e => e.Department)" Width="20%" Filter="true" />
        <TableColumn T="Employee" Title="Active" Property="@(e => e.IsActive)" Width="20%">
            <Cell Context="cellContext">
                @if (cellContext.IsActive)
                {
                    <MudIcon Icon="@Icons.Material.Filled.CheckCircle" Color="Color.Success" />
                }
                else
                {
                    <MudIcon Icon="@Icons.Material.Filled.Cancel" Color="Color.Error" />
                }
            </Cell>
        </TableColumn>
    </TableColumns>
    <DialogBody Context="editContext">
        <MudForm @ref="_form">
            <MudGrid>
                <MudItem md="6">
                    <MudTextField @bind-Value="editContext.Name" Label="Name" Required="true" />
                </MudItem>
                <MudItem md="6">
                    <MudTextField @bind-Value="editContext.Email" Label="Email" Required="true"
                                  Validation="@(new EmailAddressAttribute())" />
                </MudItem>
                <MudItem md="6">
                    <MudSelect @bind-Value="editContext.Department" Label="Department" Required="true">
                        <MudSelectItem T="string" Value="@("IT")">IT</MudSelectItem>
                        <MudSelectItem T="string" Value="@("Sales")">Sales</MudSelectItem>
                        <MudSelectItem T="string" Value="@("HR")">HR</MudSelectItem>
                    </MudSelect>
                </MudItem>
                <MudItem md="6">
                    <MudCheckBox @bind-Value="editContext.IsActive" Label="Active" />
                </MudItem>
            </MudGrid>
        </MudForm>
    </DialogBody>
</MudDataTableCRUD>

@code {
    private List<Employee> employees = new();
    private MudForm _form;

    protected override void OnInitialized()
    {
        employees = new List<Employee>
        {
            new Employee { Id = 1, Name = "John Doe", Email = "john@company.com", Department = "IT", IsActive = true },
            new Employee { Id = 2, Name = "Jane Smith", Email = "jane@company.com", Department = "Sales", IsActive = false }
        };
    }

    private bool ValidateEmployee(Employee employee)
    {
        return _form?.IsValid ?? false;
    }

    private void OnDataChanged(List<Employee> updatedData)
    {
        employees = updatedData;
    }

    private Task HandleCreate(Employee employee)
    {
        employee.Id = employees.Max(e => e.Id) + 1;
        Snackbar.Add($"Employee {employee.Name} created successfully", Severity.Success);
        return Task.CompletedTask;
    }

    private Task HandleUpdate(Employee employee)
    {
        Snackbar.Add($"Employee {employee.Name} updated successfully", Severity.Success);
        return Task.CompletedTask;
    }

    private Task HandleDelete(Employee employee)
    {
        Snackbar.Add($"Employee {employee.Name} deleted successfully", Severity.Success);
        return Task.CompletedTask;
    }

    public class Employee : ICloneable
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public string Department { get; set; }
        public bool IsActive { get; set; }

        public object Clone() => this.MemberwiseClone();
    }
}

API Reference

MudDataTableCRUD Parameters

Core Parameters
Parameter Type Default Description
Title string null Table title displayed in the toolbar
Data List<T> new() The data source for the table
DataChanged EventCallback<List<T>> - Event fired when data changes
SelectedItem T null Currently selected item
SelectedItemChanged EventCallback<T> - Event fired when selection changes
CRUD Parameters
Parameter Type Default Description
CRUD string null CRUD operations to enable ("C" = Create, "R" = Read, "U" = Update, "D" = Delete)
OnCreate EventCallback<T> - Event fired when creating an item
OnUpdate EventCallback<T> - Event fired when updating an item
OnDelete EventCallback<T> - Event fired when deleting an item
OnSuccess EventCallback<string> - Event fired on successful operation
OnError EventCallback<string> - Event fired on error
URL Parameters
Parameter Type Default Description
Url string null URL to load data from (GET request)
AddUrl string null URL for navigation when clicking Add button
UpdateUrl string null URL for navigation when clicking Update button
OnCreateUrl string null POST URL for creating items
OnUpdateUrl string null PUT URL for updating items
OnDeleteUrl string null DELETE URL for deleting items
UseDefaultRestCalls bool false Use default REST API calls (POST/PUT/DELETE to Url)
OnUrlUpdated EventCallback<List<T>> - Event fired after data is loaded from URL
Display Parameters
Parameter Type Default Description
Dense bool false Enable dense mode
Hover bool false Enable hover effect
Striped bool false Enable striped rows
FixedHeader bool false Enable fixed header
Elevation int 1 Material elevation level
Virtualize bool false Enable row virtualization
Class string null Additional CSS class
Feature Parameters
Parameter Type Default Description
ShowRefreshButton bool false Show refresh button in toolbar
ShowExportToExcelButton bool true Show Excel export button
ShowColumnOptions bool false Show column options in MudDataGrid
Hideable bool true Allow columns to be hidden
Filterable bool false Enable column filtering
Groupable bool false Enable row grouping
GroupExpanded bool false Expand groups by default
Selectable bool false Enable row selection
SelectedItemsChanged EventCallback<HashSet<T>> - Event fired when selection changes (multi-select)
Dialog Parameters
Parameter Type Default Description
DialogBody RenderFragment<T> null Custom dialog body content
CustomDialogOptions DialogOptions null Custom dialog options
IsDialogReadOnly bool false Make dialog read-only
UseFormValidationForDialog bool false Enable form validation
FromValidationFunction Func<T, bool> null Custom validation function
InitializeDialogForAddition Action<T> null Initialize data when creating
InitializeDialogForEditing Action<T> null Initialize data when editing
Conditional CRUD Parameters
Parameter Type Default Description
ConditionalCRUD bool false Enable conditional CRUD operations
ConditionForCreate bool true Condition for showing Create button
ConditionForRead Func<T, bool> null Condition for showing Read button
ConditionForUpdate Func<T, bool> null Condition for showing Update button
ConditionForDelete Func<T, bool> null Condition for showing Delete button
DisableCreateButtonFunction Func<T, bool> null Function to disable Create/Save button
Other Parameters
Parameter Type Default Description
TableColumns RenderFragment null Table column definitions
ChildRowContent RenderFragment<T> null Child row content
CustomAdditionalActions RenderFragment<T> null Additional action buttons
CustomToolbarSection RenderFragment null Custom toolbar content
EmptyTableTemplate RenderFragment null Template shown when table is empty
Options DataTableOptions new() Table display options
ColumnResizeMode ResizeMode ResizeMode.None Column resize mode
ActionColumnWidth string "20%" Width of action column

TableColumn Parameters

Parameter Type Default Description
Title string null Column header text
Width string null Column width (e.g., "20%")
Property Expression<Func<T, object>> null Property expression for the column
Selector string null Property name (supports nested: "Customer.Name")
TextRenderFunction Func<T, string> null Custom text rendering function
Cell RenderFragment<T> null Custom cell rendering
Sort bool false Enable sorting
Filter bool false Enable filtering
Search bool false Include in search
InitialSort bool false Set as initial sort column
InitialSortDirection SortDirection Ascending Initial sort direction
Format string null Format string (e.g., "N2", "dd-MMM-yy")
Hidden bool false Hide column
Hideable bool true Allow column to be hidden
Grouping bool false Enable grouping on this column
GroupBy Func<T, object> null Grouping function
GroupTemplate RenderFragment<GroupDefinition<T>> null Custom group header template
CellBackgroundColorFunction Func<T, string> null Custom cell background color
CellTextColorFunction Func<T, string> null Custom cell text color
ColumnColor string null Column background color
Comparer IComparer<object> null Custom comparer for sorting

DataTableOptions

Property Type Default Description
Dense bool true Use dense mode
Sort bool true Enable sorting
Search bool true Enable search
Hover bool true Enable hover effect
Pagination bool true Enable pagination
RowsPerPage int 10 Rows per page
Striped bool true Striped rows
ImmediateSearchTextField bool true Immediate search vs debounced

Public Methods

Method Description
AddToTable(T item) Add an item to the table
UpdateRowById(T item) Update an item by ID
RemoveRowById(string id) Remove an item by ID
ReloadDataAsync() Reload data from URL
SetData(List<T> data) Set table data programmatically
CollapseAll(bool collapse) Collapse or expand all groups
ProcessActionWithSnackbarErrorHandling(ISnackbar snackbar, T dto, Func<T, Task<T>> func) Execute an action with error handling

Tips and Best Practices

1. ICloneable Implementation

All entity types must implement ICloneable. For simple objects:

public object Clone() => this.MemberwiseClone();

For objects with collections or nested objects, implement a deep clone:

public object Clone()
{
    var clone = (MyEntity)this.MemberwiseClone();
    clone.Items = new List<Item>(this.Items);
    return clone;
}

2. Excel Export with Custom Cells

When using custom Cell render fragments, the component automatically extracts text content for Excel export using JavaScript interop. For best results:

  • Use MudBlazor input components (they are automatically detected)
  • Ensure input fields have values set
  • Avoid purely visual elements in cells meant for export

Alternatively, provide a TextRenderFunction for explicit control:

<TableColumn T="Product" Title="Status"
             TextRenderFunction="@(p => p.IsActive ? "Active" : "Inactive")">
    <Cell Context="cellContext">
        <MudChip T="string" Color="@(cellContext.IsActive ? Color.Success : Color.Error)">
            @(cellContext.IsActive ? "Active" : "Inactive")
        </MudChip>
    </Cell>
</TableColumn>

3. Performance Optimization

For large datasets:

  • Enable virtualization: Virtualize="true"
  • Use pagination: Set appropriate RowsPerPage in Options
  • Consider server-side paging for very large datasets

4. Custom Styling

Use the styling parameters for custom appearance:

<TableColumn T="Order" Title="Amount" Property="@(o => o.Total)"
             CellBackgroundColorFunction="@(o => o.Total > 1000 ? \"lightgreen\" : \"transparent\")"
             CellTextColorFunction="@(o => o.Total > 1000 ? \"darkgreen\" : \"black\")" />

5. REST API Pattern

When using UseDefaultRestCalls="true", the component expects:

  • GET {Url} - Returns List<T>
  • POST {Url} - Accepts T, returns created T
  • PUT {Url} - Accepts T, returns updated T
  • DELETE {Url}/{id} - Deletes item by ID

6. Form Validation

For form validation in dialogs:

  1. Set UseFormValidationForDialog="true"
  2. Create a MudForm in your DialogBody
  3. Provide a validation function:
private bool ValidateForm(MyEntity entity)
{
    return _form?.IsValid ?? false;
}

License

This project is licensed under the MIT License.

Contributing

Contributions are welcome! Please feel free to submit pull requests or open issues.

Support

For issues, questions, or feature requests, please visit the GitHub repository.

Changelog

Version 1.0.0

  • Initial release
  • Full CRUD functionality
  • Excel export
  • Column filtering and sorting
  • Row grouping
  • Child row expansion
  • REST API integration
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.0.1 95 2/3/2026
2.0.0 90 1/20/2026
1.0.0 277 12/16/2025

Initial release with comprehensive CRUD functionality