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.
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);
}
}
}
}