Search code examples
blazorblazor-server-sideblazor-webassemblymudblazor

How to use SortBy in Dynamic Mudtable


I am creating MudTab with MudTable .The columns and data are passed dynamically to the MudTab and MudTable. But I cannot figure it out how to set <MudTh><MudTableSortLabel SortBy</MudTableSortLabel></MudTh>

    Tab.razor
    <MudTabs  @bind-ActivePanelIndex="_index">
    <ChildContent>
    @foreach (var tab in tabs)
    {
    <MudTabPanel Text="@tab.Text">
    <MudTable Items="@tab.TableData" Hover="true">          
    <HeaderContent>
     @foreach (var column in tab.ColumnNames)
     {
     <MudTh>                                 
      @column 
     </MudTh>
     }
     </HeaderContent> 
     <RowTemplate>
     @foreach (var column in tab.ColumnNames)
     {
     <MudTd DataLabel="@column">@context.GetDisplayValue(column)</MudTd>
     }
     </RowTemplate>
     </MudTable>
     </MudTabPanel>
      }
    </ChildContent>

   </MudTabs>

    Tab.razor.cs
    public partial class Tab
    {
    public interface ITableData
    {
    string GetDisplayValue(string propertyName);
    object GetSortValue(string propertyName);
    }
    public class TabModel 
    {
    public int Index { get; set; }
    public string Text { get; set; } = string.Empty;
    public List<string> ColumnNames { get; set; } = new();
    public List<ITableData> TableData { get; set; } = new();         
    }       

    public class All : ITableData
    {
    public string Field1 { get; set; } = string.Empty;
    public string Field2 { get; set; } = string.Empty;
    public string GetDisplayValue(string propertyName)
    {
    return propertyName switch
    {
    "Field1" => Field1 ,
    "Field2" => Field2 
    };
    }
    public object GetSortValue(string propertyName)
    {
    return propertyName switch
    {
    "Field1" => Field1,
    "Field2" => Field2,
    _ => string.Empty,
    };
    }
    }
    public class Net  : ITableData
    {
    public string NetField1 { get; set; } = string.Empty;
    public string NetField2 { get; set; } = string.Empty;
    public string GetDisplayValue(string propertyName)
    {
    return propertyName switch
    {
    "NetField1" => NetField1 ,
    "NetField2" => NetField2 ,               
     _ => string.Empty,
    };
    }
    public object GetSortValue(string propertyName)
    {
    return propertyName switch
    {
    "NetField1" => NetField1 ,
    "NetField2" => NetField2 ,               
    _ => string.Empty
     };
     }
     }
    private int _index = 0;      
    private int? _nextIndex = null;
    private int selectedIndex = 0;
    private List<TabModel> tabs = new();
    protected override void OnInitialized()
    {
    base.OnInitialized();
    tabs = new List<TabModel>
    {
    new TabModel
    {
    Index = 0,
    Text = "All",
    ColumnNames = new List<string> { "Field1", "Field1"},
    TableData = new List<ITableData>
    {
    new All { Field1 = "Name1",Field2 ="125KB" },
    new All {  Field1 = "Name2", Field2 ="125KB" }
    } 
    },
    new TabModel
    {
    Index = 1,
    Text = "Net",
    ColumnNames = new List<string> { "NetField1", "NetField2"},
    TableData = new List<ITableData>
    {
    new Net { NetField1 = "25%" , NetField2 = "Process1" },
    new Net { NetField1 = "35%" , NetField2 = "Process2" }
    }  
    }; 
    }     
 }

I tried the following options

 <MudTableSortLabel SortBy="((object)(column))">@column</MudTableSortLabel>
    <MudTableSortLabel SortBy="@(context => context.GetSortValue(column))">
    <MudTableSortLabel SortBy="@(x => x.GetSortValue(column))">
        @column
    </MudTableSortLabel>

And tried other options too. but nothing worked out. Getting error asking to enter the T explicitly

for Funct<T,object> How do I add the Class name


Solution

  • If you know your Type T and you have a SortLabel and a SortHeader you can do it like this:

    Note: config is a custom class, you have to get it from somewhere in your code - SortLabel and SortHeader are just strings.

    <MudTableSortLabel SortLabel="@config.Sortlabel" T="YourType">
         @config.SortHeader
    </MudTableSortLabel>
    

    Edit

    If you have a simple scenario I would just go with this solution. Otherwise it would become very complicated.

    If you want to go with the dynamic solution, you should consider the following:

    • Think about having server side pagination and sorting and filtering
    • Restructure your component to have only the MudTable in it - no tabs or something else
    • I´m building a nuget package which addresses exact this use case: Server side pagination, sorting and filtering with MudTable in Blazor. Coming soon. You would need this package at the server side.
    • Set on MudTable AllowUnsorted="false" to disable the third state