blazor-webassemblymudblazor

"MultiSelection" not working properly when using "Server Side Filtering" MudBlazor MudTable in Blazor WebAssembly


I started using MudBlazor in a Blazor WebAssembly project. The problem is that when I use server side filtering and pagination in MudTable, MultiSelection not working properly. I can select all the rows by clicking "Select All" checkbox but selectAll checkbox remains unchecked when All are selected; and unable to unselect all again. Unselect only working 1 by 1.

I am using this link: https://try.mudblazor.com/snippet/mEQcYHEKpSAoCWSn

I appreciate your helps.


Solution

  • If you change the code like this it works.

    <MudTable ServerData="@(new Func<TableState, Task<TableData<Element>>>(ServerReload))"
            @ref="table"
            CustomHeader="true"
            @bind-SelectedItems="selectedItems1" 
             MultiSelection="true"
            RowClassFunc="@SelectedRowClassFunc" 
            OnRowClick="RowClickEvent" 
            RowsPerPageChanged="OnRowsPerPageChanged"
            T="Element">
            
        <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>
            <MudTHeadRow IgnoreCheckbox="true">
                <MudTh>
                    <MudCheckBox T="bool" Checked="IsSelectAllChecked" CheckedChanged="@Select"></MudCheckBox>
                </MudTh>
                <MudTh><MudTableSortLabel SortBy="new Func<Element, object>(x=>x.Number)">Nr</MudTableSortLabel></MudTh>
                <MudTh>Sign</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>
            </MudTHeadRow>
        </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 PageSizeOptions="new int[]{1, 5, 10}" />
        </PagerContent>
        <FooterContent>
            <MudTd colspan="5">Select All</MudTd>
        </FooterContent>
    </MudTable>
        <MudText >@($"{selectedItems1.Count} items selected")</MudText>
        <MudText Inline="true">Selected items: @(selectedItems1==null ? "" : string.Join(", ", selectedItems1.OrderBy(x=>x.Sign).Select(x=>x.Sign)))</MudText>
    
    
    @code {
        private IEnumerable<Element> pagedData;
        private MudTable<Element> table;
    
        private int totalItems;
        private string searchString = null;
    
        private List<string> clickedEvents = new();
        private HashSet<Element> selectedItems1 = new HashSet<Element>();
    
        private async Task<TableData<Element>> ServerReload(TableState state)
        {
            IEnumerable<Element> data = await httpClient.GetFromJsonAsync<List<Element>>("webapi/periodictable");
            await Task.Delay(300);
            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 OnRowsPerPageChanged(int pageSize)
        {
            selectedItems1.Clear();
        }
    
        private void OnSelectedItemsChanged(HashSet<Element> elements)
        {
            clickedEvents.Add("Selected items changed");
        }
    
    
    
        private void OnSearch(string text)
        {
            searchString = text;
            table.ReloadServerData();
        }
    
         private void RowClickEvent(TableRowClickEventArgs<Element> tableRowClickEventArgs)
        {
            clickedEvents.Add("Row has been clicked");
        }
    
        private string SelectedRowClassFunc(Element element, int rowNumber)
        {
            return selectedItems1.Contains(element) ? "selected" : string.Empty;
        }
    
        private bool IsSelectAllChecked
        {
            get
            {
                var currentPage = table.CurrentPage;
                var rowsPerPage =table.RowsPerPage;
           
                var currentPageItems = table.FilteredItems.Skip(currentPage * rowsPerPage).Take(rowsPerPage);
    
                if (!selectedItems1.Any(x => currentPageItems.Any(y => x == y)))
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
        }
        private void Select()
        {
            var currentPage = table.CurrentPage;
            var rowsPerPage = table.RowsPerPage;
           
            var currentPageItems = table.FilteredItems.Skip(currentPage * rowsPerPage).Take(rowsPerPage);
    
            if (!selectedItems1.Any(x => currentPageItems.Any(y => x == y)))
            {
                foreach(var item in currentPageItems)
                {
                    selectedItems1.Add(item);
                }
            }
            else
            {
                foreach(var item in currentPageItems)
                {
                    selectedItems1.Remove(item);
                }
            }
        }
    
    }