Skip to content

Commit 94c33e8

Browse files
committed
Grid: fix page size, prerendering restore, checkbox filter rendering, async usage. Sidebar and Sibar2: fic mobile nav behavior
- Fixed page size reset issue when selecting PageSize from the table footer. Introduced pendingPageSizeChanging to prevent page reset during rendering and corrected OnPageSizeChangedAsync. - Fixed incorrect UI restore after LoadGridSettingsAsync. Added isColumnsLoading to show a temporary placeholder during prerendering and render filters correctly afterward. - Added InputFilterTemplate (RenderFragment) in GridColumnFilter.razor.cs to fix checkbox rendering where the checked state wasn’t applied properly. - Added missing async keywords and replaced return Task.CompletedTask with await calls in Grid.razor.cs. - Mobile version: added auto-close behavior for sidebar and sidebar2. NavMenu now closes correctly after selecting a menu item
1 parent 5aea3c7 commit 94c33e8

File tree

8 files changed

+120
-53
lines changed

8 files changed

+120
-53
lines changed

blazorbootstrap/Components/Grid/Grid.razor

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -68,21 +68,31 @@
6868
}
6969

7070
<th class="@string.Join(" ", columnClassList)" style="@string.Join(";", columnStyleList)">
71-
@if (column.Filterable)
71+
72+
@if (isColumnsLoading)
7273
{
73-
<GridColumnFilter EnumFilterSelectText="@EnumFilterSelectText"
74-
FilterButtonColor="@column.FilterButtonColor"
75-
FilterButtonCSSClass="@column.FilterButtonCSSClass"
76-
FilterOperator="@column.FilterOperator"
77-
FilterValue="@column.FilterValue"
78-
FilterWidth="@column.FilterTextboxWidth"
79-
FiltersTranslationProvider="GridFiltersTranslationProviderAsync!"
80-
FixedHeader="@FixedHeader"
81-
GridColumnFilterChanged="async args => await column.OnFilterChangedAsync(args, column)"
82-
PropertyType="@column.GetPropertyType()"
83-
PropertyTypeName="@column.GetPropertyTypeName()"
84-
Unit="@column.FilterTextboxWidthUnit" />
74+
<PlaceholderContainer Animation="PlaceholderAnimation.Glow">
75+
<Placeholder Width="PlaceholderWidth.Col12" />
76+
</PlaceholderContainer>
8577
}
78+
else
79+
{
80+
@if (column.Filterable)
81+
{
82+
<GridColumnFilter EnumFilterSelectText="@EnumFilterSelectText"
83+
FilterButtonColor="@column.FilterButtonColor"
84+
FilterButtonCSSClass="@column.FilterButtonCSSClass"
85+
FilterOperator="@column.FilterOperator"
86+
FilterValue="@column.FilterValue"
87+
FilterWidth="@column.FilterTextboxWidth"
88+
FiltersTranslationProvider="GridFiltersTranslationProviderAsync!"
89+
FixedHeader="@FixedHeader"
90+
GridColumnFilterChanged="async args => await column.OnFilterChangedAsync(args, column)"
91+
PropertyType="@column.GetPropertyType()"
92+
PropertyTypeName="@column.GetPropertyTypeName()"
93+
Unit="@column.FilterTextboxWidthUnit" />
94+
}
95+
}
8696
</th>
8797
}
8898
</tr>

blazorbootstrap/Components/Grid/Grid.razor.cs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ public partial class Grid<TItem> : BlazorBootstrapComponentBase
4343

4444
private int? totalCount = null;
4545

46+
private bool pendingPageSizeChanging = false;
47+
48+
private bool isColumnsLoading = false;
49+
4650
#endregion
4751

4852
#region Methods
@@ -68,17 +72,25 @@ protected override void OnInitialized()
6872
pageSize = PageSize;
6973
selectedItems = SelectedItems!;
7074

75+
isColumnsLoading = true;
76+
7177
base.OnInitialized();
7278
}
7379

74-
protected override Task OnParametersSetAsync()
80+
protected override async Task OnParametersSetAsync()
7581
{
7682
if ((Data is null && DataProvider is null) || (Data is not null && DataProvider is not null))
7783
throw new ArgumentException($"Grid requires either {nameof(Data)} or {nameof(DataProvider)}, but not both or neither.");
7884

7985
if (AllowPaging && PageSize < 0)
8086
throw new ArgumentException($"{nameof(PageSize)} must be greater than zero.");
8187

88+
if (pendingPageSizeChanging)
89+
{
90+
PageSize = pageSize;
91+
return;
92+
}
93+
8294
if (isFirstRenderComplete)
8395
{
8496
// Perform a re-query only if the data source or something else has changed
@@ -93,8 +105,8 @@ protected override Task OnParametersSetAsync()
93105
{
94106
mustRefreshData = true;
95107
pageSize = PageSize;
96-
_ = ResetPageNumberAsync();
97-
SaveGridSettingsAsync();
108+
await ResetPageNumberAsync();
109+
await SaveGridSettingsAsync();
98110
}
99111

100112
//if (!mustRefreshData && selectedItems != SelectedItems)
@@ -106,10 +118,11 @@ protected override Task OnParametersSetAsync()
106118
// We want to trigger the first data load when we've collected the initial set of columns
107119
// because they might perform some action, like setting the default sort order.
108120
// It would be wasteful to have to re-query immediately.
109-
return columns.Count > 0 && mustRefreshData ? RefreshDataAsync(false) : Task.CompletedTask;
121+
if (columns.Count > 0 && mustRefreshData)
122+
await RefreshDataAsync(false);
110123
}
111124

112-
return base.OnParametersSetAsync();
125+
await base.OnParametersSetAsync();
113126
}
114127

115128
/// <summary>
@@ -170,9 +183,9 @@ private string GetColumnSummaryValue(GridSummaryColumnType type, string property
170183
/// </summary>
171184
public async ValueTask ResetPageNumber() => await ResetPageNumberAsync(true);
172185

173-
public Task SelectAllItemsAsync() => SelectAllItemsInternalAsync(true);
186+
public async Task SelectAllItemsAsync() => await SelectAllItemsInternalAsync(true);
174187

175-
public Task UnSelectAllItemsAsync() => SelectAllItemsInternalAsync(false);
188+
public async Task UnSelectAllItemsAsync() => await SelectAllItemsInternalAsync(false);
176189

177190
internal void AddColumn(GridColumn<TItem> column) => columns.Add(column);
178191

@@ -254,6 +267,9 @@ internal async Task RefreshDataAsync(bool firstRender = false, CancellationToken
254267
await RefreshSelectionAsync();
255268
}
256269

270+
if (firstRender)
271+
isColumnsLoading = false;
272+
257273
requestInProgress = false;
258274

259275
await InvokeAsync(StateHasChanged);
@@ -476,10 +492,12 @@ private async Task OnPageChangedAsync(int newPageNumber)
476492

477493
private async Task OnPageSizeChangedAsync(int newPageSize)
478494
{
495+
pendingPageSizeChanging = true;
479496
pageSize = PageSize = newPageSize;
480497
await ResetPageNumberAsync();
481498
await SaveGridSettingsAsync();
482499
await RefreshDataAsync(false);
500+
pendingPageSizeChanging = false;
483501
}
484502

485503
private async Task OnRowCheckboxChanged(string id, TItem item, ChangeEventArgs args)
@@ -564,14 +582,14 @@ private async Task RowDoubleClick(TItem item, EventArgs args)
564582
await OnRowDoubleClick.InvokeAsync(new GridRowEventArgs<TItem>(item));
565583
}
566584

567-
private Task SaveGridSettingsAsync()
585+
private async Task SaveGridSettingsAsync()
568586
{
569587
if (!GridSettingsChanged.HasDelegate)
570-
return Task.CompletedTask;
588+
return;
571589

572590
var settings = new GridSettings { PageNumber = AllowPaging ? gridCurrentState.PageIndex : 0, PageSize = AllowPaging ? pageSize : 0, Filters = AllowFiltering ? GetFilters() : null };
573591

574-
return GridSettingsChanged.InvokeAsync(settings);
592+
await GridSettingsChanged.InvokeAsync(settings);
575593
}
576594

577595
private async Task SelectAllItemsInternalAsync(bool selectAll)
@@ -595,11 +613,9 @@ private async Task SelectAllItemsInternalAsync(bool selectAll)
595613
SelectedItems = selectedItems;
596614
}
597615

598-
private Task SetCheckboxStateAsync(string id, CheckboxState checkboxState)
616+
private async Task SetCheckboxStateAsync(string id, CheckboxState checkboxState)
599617
{
600-
queuedTasks.Enqueue(async () => await JSRuntime.InvokeVoidAsync("window.blazorBootstrap.grid.setSelectAllCheckboxState", id, (int)checkboxState));
601-
602-
return Task.CompletedTask;
618+
await JSRuntime.InvokeVoidAsync("window.blazorBootstrap.grid.setSelectAllCheckboxState", id, (int)checkboxState);
603619
}
604620

605621
/// <summary>

blazorbootstrap/Components/Grid/GridColumnFilter.razor

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -31,28 +31,7 @@
3131
}
3232
</ul>
3333

34-
@if (PropertyTypeName == StringConstants.PropertyTypeNameInt16
35-
|| PropertyTypeName == StringConstants.PropertyTypeNameInt32
36-
|| PropertyTypeName == StringConstants.PropertyTypeNameInt64
37-
|| PropertyTypeName == StringConstants.PropertyTypeNameSingle // float
38-
|| PropertyTypeName == StringConstants.PropertyTypeNameDecimal
39-
|| PropertyTypeName == StringConstants.PropertyTypeNameDouble)
40-
{
41-
<input class="form-control" style="@filterStyle" type="number" value="@filterValue" @oninput="@(async args => await OnFilterValueChangedAsync(args))">
42-
}
43-
else if (PropertyTypeName == StringConstants.PropertyTypeNameDateOnly)
44-
{
45-
<input class="form-control" style="@filterStyle" type="date" value="@filterValue" @oninput="@(async args => await OnFilterValueChangedAsync(args))" />
46-
}
47-
else if (PropertyTypeName == StringConstants.PropertyTypeNameDateTime)
48-
{
49-
<input class="form-control" style="@filterStyle" type="datetime-local" value="@filterValue" @oninput="@(async args => await OnFilterValueChangedAsync(args))" />
50-
}
51-
else if (PropertyTypeName == StringConstants.PropertyTypeNameBoolean)
52-
{
53-
<input class="form-check-input" type="checkbox" value="@filterValue" @onchange="@(async args => await OnFilterValueChangedAsync(args))" />
54-
}
55-
else if (PropertyTypeName == StringConstants.PropertyTypeNameEnum)
34+
@if (PropertyTypeName == StringConstants.PropertyTypeNameEnum)
5635
{
5736
<Dropdown Color="DropdownColor.Light">
5837
<DropdownToggleButton Class="px-1" Style="@filterStyle">
@@ -77,8 +56,8 @@
7756
</DropdownMenu>
7857
</Dropdown>
7958
}
80-
else // guid or string
59+
else
8160
{
82-
<input class="form-control" style="@filterStyle" type="text" value="@filterValue" @oninput="@(async args => await OnFilterValueChangedAsync(args))" />
61+
@InputFilterTemplate
8362
}
8463
</div>

blazorbootstrap/Components/Grid/GridColumnFilter.razor.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,62 @@ or StringConstants.PropertyTypeNameDecimal
7272
}
7373
}
7474

75+
private RenderFragment InputFilterTemplate => builder =>
76+
{
77+
string inputType;
78+
string inputClass;
79+
80+
switch (PropertyTypeName)
81+
{
82+
case StringConstants.PropertyTypeNameInt16:
83+
case StringConstants.PropertyTypeNameInt32:
84+
case StringConstants.PropertyTypeNameInt64:
85+
case StringConstants.PropertyTypeNameSingle:
86+
case StringConstants.PropertyTypeNameDecimal:
87+
case StringConstants.PropertyTypeNameDouble:
88+
inputType = "number";
89+
inputClass = "form-control";
90+
break;
91+
case StringConstants.PropertyTypeNameDateOnly:
92+
inputType = "date";
93+
inputClass = "form-control";
94+
break;
95+
case StringConstants.PropertyTypeNameDateTime:
96+
inputType = "datetime-local";
97+
inputClass = "form-control";
98+
break;
99+
case StringConstants.PropertyTypeNameBoolean:
100+
inputType = "checkbox";
101+
inputClass = "form-check-input";
102+
break;
103+
default:
104+
inputType = "text";
105+
inputClass = "form-control";
106+
break;
107+
}
108+
109+
builder.OpenElement(100, "input");
110+
builder.AddAttribute(101, "class", inputClass);
111+
112+
builder.AddAttribute(102, "type", inputType);
113+
builder.AddAttribute(103, "value", filterValue);
114+
115+
if (PropertyTypeName == StringConstants.PropertyTypeNameBoolean)
116+
{
117+
if (bool.TryParse(filterValue, out bool isChecked))
118+
builder.AddAttribute(104, "checked", "checked");
119+
120+
builder.AddAttribute(106, "onchange", async (ChangeEventArgs args) => await OnFilterValueChangedAsync(args));
121+
}
122+
else
123+
{
124+
builder.AddAttribute(105, "style", filterStyle);
125+
builder.AddAttribute(106, "oninput", async (ChangeEventArgs args) => await OnFilterValueChangedAsync(args));
126+
}
127+
128+
builder.CloseElement();
129+
};
130+
75131
private async Task<IEnumerable<FilterOperatorInfo>> GetFilterOperatorsAsync(string propertyTypeName)
76132
{
77133
if (FiltersTranslationProvider is null)

blazorbootstrap/Components/Sidebar/Sidebar.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
<div class="bb-sidebar-top-row navbar">
99
<div class="container-fluid ps-3">
10-
<a class="navbar-brand d-flex align-items-center" href="@Href">
10+
<a class="navbar-brand d-flex align-items-center" href="@Href" @onclick=HideNavMenuOnMobile>
1111
@if (!string.IsNullOrWhiteSpace(ImageSrc))
1212
{
1313
<span class="navbar-brand-image me-2">

blazorbootstrap/Components/Sidebar/Sidebar.razor.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,10 @@ public void ToggleSidebar()
8989
internal void HideNavMenuOnMobile()
9090
{
9191
if (isMobile && !collapseNavMenu)
92+
{
9293
collapseNavMenu = true;
94+
StateHasChanged();
95+
}
9396
}
9497

9598
private string GetNavMenuCssClass()

blazorbootstrap/Components/Sidebar2/Sidebar2.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<aside @ref="@Element" id="@Id" class="@ClassNames" style="@StyleNames" role="navigation" @attributes="@AdditionalAttributes">
77
<div class="bb-sidebar2-top-row navbar">
88
<div class="container-fluid ps-3">
9-
<a class="navbar-brand d-flex align-items-center" href="@Href">
9+
<a class="navbar-brand d-flex align-items-center" href="@Href" @onclick=HideNavMenuOnMobile>
1010
@if (!string.IsNullOrWhiteSpace(ImageSrc))
1111
{
1212
<span class="navbar-brand-image me-2">

blazorbootstrap/Components/Sidebar2/Sidebar2.razor.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,10 @@ public void ToggleSidebar()
9090
internal void HideNavMenuOnMobile()
9191
{
9292
if (isMobile && !collapseNavMenu)
93+
{
9394
collapseNavMenu = true;
95+
StateHasChanged();
96+
}
9497
}
9598

9699
private string GetNavMenuCssClass()

0 commit comments

Comments
 (0)