Aishh
Aishh

Reputation: 21

Blazor: SortIndex Not Reset After Reloading Grid on DropDown Value Change

I want to reload the grid when the dropdown value changes. However, the SortIndex here:

<span class="mud-sort-index mud-text-disabled">1</span>

is not cleared after reloading, even though the SortDefinitions are being cleared in the OnCategoryChange method.

SortIndex

What I have tried

Clearing the sorting definitions before reloading the data.

dataGrid?.SortDefinitions.Clear();

Please note I have applied sorting only for Number column.

Code:

private Task OnCategoryChange(string category)
{
    selectedCategory = category;
    dataGrid?.SortDefinitions.Clear();
    return dataGrid?.ReloadServerData() ?? Task.CompletedTask;
}

Full markup and code:

<MudDataGrid @ref="dataGrid" T="Element" ServerData="ServerReload" Filterable="false">
    <ToolBarContent>
        <MudText Typo="Typo.h6">Periodic Elements</MudText>
        <MudSpacer />
        
       <MudSelect T="string" Label="Select Category" Value="selectedCategory" ValueChanged="OnCategoryChange">
    <MudSelectItem Value="All">All</MudSelectItem>
    <MudSelectItem Value="Nonmetal">Nonmetal</MudSelectItem>
    <MudSelectItem Value="NobleGas">Noble Gas</MudSelectItem>
    <MudSelectItem Value="AlkaliMetal">Alkali Metal</MudSelectItem>
    <MudSelectItem Value="AlkalineEarthMetal">Alkaline Earth Metal</MudSelectItem>
    <MudSelectItem Value="Metalloid">Metalloid</MudSelectItem>
</MudSelect>

        <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>
    <Columns>
        <TemplateColumn Title="Nr" Sortable="true" SortBy="@(_ => _.Number)">
            <CellTemplate>
                @context.Item.Number
            </CellTemplate>
        </TemplateColumn>

        <TemplateColumn Title="Sign" Sortable="true" SortBy="@(_ => _.Sign)">
            <CellTemplate>
                @context.Item.Sign
            </CellTemplate>
        </TemplateColumn>

        <TemplateColumn Title="Name" Sortable="true" SortBy="@(_ => _.Name)">
            <CellTemplate>
                @context.Item.Name
            </CellTemplate>
        </TemplateColumn>

        <TemplateColumn Title="Position" Sortable="true" SortBy="@(_ => _.Position)">
            <CellTemplate>
                @context.Item.Position
            </CellTemplate>
        </TemplateColumn>

        <TemplateColumn Title="Molar mass" Sortable="true" SortBy="@(_ => _.Molar)">
            <CellTemplate>
                @context.Item.Molar
            </CellTemplate>
        </TemplateColumn>

        <TemplateColumn Title="Category" Sortable="true" SortBy="@(_ => _.Group)">
            <CellTemplate>
                @context.Item.Group
            </CellTemplate>
        </TemplateColumn>
    </Columns>
    <PagerContent>
        <MudDataGridPager T="Element" />
    </PagerContent>
</MudDataGrid>

@code {
    public class Element
    {
        public int Number { get; set; } = 0;
        public string Sign { get; set; } = string.Empty;
        public string Name { get; set; } = string.Empty;
        public int Position { get; set; } = 0;
        public double Molar { get; set; } = 0.0;
        public string Group { get; set; } = string.Empty;
    
        // Constructor to initialize properties
        public Element(int number, string sign, string name, int position, double molar, string group)
        {
            Number = number;
            Sign = sign;
            Name = name;
            Position = position;
            Molar = molar;
            Group = group;
        }
    
        // Default constructor
        public Element() { }
    }

    MudDataGrid<Element>? dataGrid;
    string searchString = string.Empty;
    string selectedCategory = "All";

    private const string NobleGas = "Noble Gas";
    private const string AlkaliMetal = "Alkali Metal";
    private const string AlkalineEarthMetal = "Alkaline Earth Metal";

    private const string All = "All";
    private const string Nonmetal = "Nonmetal";
    private const string Metalloid = "Metalloid";

    private async Task<GridData<Element>> ServerReload(GridState<Element> state)
    {
       IEnumerable<Element> data = new List<Element>
    {
        new Element(1, "H", "Hydrogen", 1, 1.008, "Nonmetal"),
        new Element(2, "He", "Helium", 18, 4.0026, "Noble Gas"),
        new Element(3, "Li", "Lithium", 1, 6.94, "Alkali Metal"),
        new Element(4, "Be", "Beryllium", 2, 9.0122, "Alkaline Earth Metal"),
        new Element(5, "B", "Boron", 13, 10.81, "Metalloid"),
        new Element(6, "C", "Carbon", 14, 12.011, "Nonmetal"),
        new Element(7, "N", "Nitrogen", 15, 14.007, "Nonmetal"),
        new Element(8, "O", "Oxygen", 16, 15.999, "Nonmetal"),
        new Element(9, "F", "Fluorine", 17, 18.998, "Halogen"),
        new Element(10, "Ne", "Neon", 18, 20.180, "Noble Gas"),
        new Element(11, "Na", "Sodium", 1, 22.990, "Alkali Metal"),
        new Element(12, "Mg", "Magnesium", 2, 24.305, "Alkaline Earth Metal"),
        new Element(13, "Al", "Aluminum", 13, 26.982, "Post-transition Metal"),
        new Element(14, "Si", "Silicon", 14, 28.085, "Metalloid"),
        new Element(15, "P", "Phosphorus", 15, 30.974, "Nonmetal"),
        new Element(16, "S", "Sulfur", 16, 32.06, "Nonmetal"),
        new Element(17, "Cl", "Chlorine", 17, 35.45, "Halogen"),
        new Element(18, "Ar", "Argon", 18, 39.948, "Noble Gas"),
        new Element(19, "K", "Potassium", 1, 39.098, "Alkali Metal"),
        new Element(20, "Ca", "Calcium", 2, 40.078, "Alkaline Earth Metal"),
        new Element(21, "Sc", "Scandium", 3, 44.956, "Transition Metal"),
        new Element(22, "Ti", "Titanium", 4, 47.867, "Transition Metal"),
        new Element(23, "V", "Vanadium", 5, 50.942, "Transition Metal"),
        new Element(24, "Cr", "Chromium", 6, 51.996, "Transition Metal"),
        new Element(25, "Mn", "Manganese", 7, 54.938, "Transition Metal"),
        new Element(26, "Fe", "Iron", 8, 55.845, "Transition Metal"),
        new Element(27, "Co", "Cobalt", 9, 58.933, "Transition Metal"),
        new Element(28, "Ni", "Nickel", 10, 58.693, "Transition Metal"),
        new Element(29, "Cu", "Copper", 11, 63.546, "Transition Metal")
    };
        await Task.Delay(300); // Simulating API delay

        // Apply filtering
        data = data.Where(element =>
            (string.IsNullOrWhiteSpace(searchString) ||
             element.Sign.Contains(searchString, StringComparison.OrdinalIgnoreCase) ||
             element.Name.Contains(searchString, StringComparison.OrdinalIgnoreCase) ||
             $"{element.Number} {element.Position} {element.Molar}".Contains(searchString)) &&
            (selectedCategory == "All" || element.Group == selectedCategory)
        );

    // Apply sorting logic
    var sortDefinition = state.SortDefinitions.FirstOrDefault();

    if (sortDefinition != null)
    {
        var sortBy = "Number";

        switch (sortBy)
        {
            case nameof(Element.Number):
                data = data.OrderByDirection(sortDefinition.Descending ? SortDirection.Descending : SortDirection.Ascending, o => o.Number);
                break;

            case nameof(Element.Sign):
                data = data.OrderByDirection(sortDefinition.Descending ? SortDirection.Descending : SortDirection.Ascending, o => o.Sign);
                break;

            case nameof(Element.Name):
                data = data.OrderByDirection(sortDefinition.Descending ? SortDirection.Descending : SortDirection.Ascending, o => o.Name);
                break;

            case nameof(Element.Position):
                data = data.OrderByDirection(sortDefinition.Descending ? SortDirection.Descending : SortDirection.Ascending, o =>  o.Position);
                break;

        case nameof(Element.Molar):
                data = data.OrderByDirection(sortDefinition.Descending ? SortDirection.Descending : SortDirection.Ascending, o => o.Molar);
                break;
        }
    }
        var totalItems = data.Count();
        var pagedData = data.Skip(state.Page * state.PageSize).Take(state.PageSize).ToArray();

        return new GridData<Element>
        {
            TotalItems = totalItems,
            Items = pagedData
        };
    }

    private Task OnSearch(string text)
    {
        searchString = text;
        return dataGrid?.ReloadServerData() ?? Task.CompletedTask;
    }

    private Task OnCategoryChange(string category)
    {
        selectedCategory = category;
        dataGrid?.SortDefinitions.Clear();
        return dataGrid?.ReloadServerData() ?? Task.CompletedTask;
    }
}

Here is the snippet:

https://try.mudblazor.com/snippet/GamTuxYnwmIPseoh

Upvotes: 1

Views: 33

Answers (1)

Aishh
Aishh

Reputation: 21

Try adding @key [@key="selectedCategory"]in your code.

<MudDataGrid @ref="dataGrid" @key="selectedCategory" T="Element" ServerData="ServerReload" Filterable="false">..

The Key parameter in Blazor is used to help the rendering engine identify components uniquely. When you set a Key on a component like , it forces Blazor to treat it as a new instance whenever the key changes, which can be useful for ensuring a fresh re-render.

Upvotes: 0

Related Questions