diff --git a/blazorbootstrap/Components/Grid/Grid.razor b/blazorbootstrap/Components/Grid/Grid.razor
index 61b311dc6..e6f7a82d4 100644
--- a/blazorbootstrap/Components/Grid/Grid.razor
+++ b/blazorbootstrap/Components/Grid/Grid.razor
@@ -68,21 +68,31 @@
}
- @if (column.Filterable)
+
+ @if (isColumnsLoading)
{
-
+
+
+
}
+ else
+ {
+ @if (column.Filterable)
+ {
+
+ }
+ }
|
}
diff --git a/blazorbootstrap/Components/Grid/Grid.razor.cs b/blazorbootstrap/Components/Grid/Grid.razor.cs
index e4ce77f84..1bd7c1271 100644
--- a/blazorbootstrap/Components/Grid/Grid.razor.cs
+++ b/blazorbootstrap/Components/Grid/Grid.razor.cs
@@ -43,6 +43,10 @@ public partial class Grid : BlazorBootstrapComponentBase
private int? totalCount = null;
+ private bool pendingPageSizeChanging = false;
+
+ private bool isColumnsLoading = false;
+
#endregion
#region Methods
@@ -68,10 +72,12 @@ protected override void OnInitialized()
pageSize = PageSize;
selectedItems = SelectedItems!;
+ isColumnsLoading = true;
+
base.OnInitialized();
}
- protected override Task OnParametersSetAsync()
+ protected override async Task OnParametersSetAsync()
{
if ((Data is null && DataProvider is null) || (Data is not null && DataProvider is not null))
throw new ArgumentException($"Grid requires either {nameof(Data)} or {nameof(DataProvider)}, but not both or neither.");
@@ -79,6 +85,12 @@ protected override Task OnParametersSetAsync()
if (AllowPaging && PageSize < 0)
throw new ArgumentException($"{nameof(PageSize)} must be greater than zero.");
+ if (pendingPageSizeChanging)
+ {
+ PageSize = pageSize;
+ return;
+ }
+
if (isFirstRenderComplete)
{
// Perform a re-query only if the data source or something else has changed
@@ -93,8 +105,8 @@ protected override Task OnParametersSetAsync()
{
mustRefreshData = true;
pageSize = PageSize;
- _ = ResetPageNumberAsync();
- SaveGridSettingsAsync();
+ await ResetPageNumberAsync();
+ await SaveGridSettingsAsync();
}
//if (!mustRefreshData && selectedItems != SelectedItems)
@@ -106,10 +118,11 @@ protected override Task OnParametersSetAsync()
// We want to trigger the first data load when we've collected the initial set of columns
// because they might perform some action, like setting the default sort order.
// It would be wasteful to have to re-query immediately.
- return columns.Count > 0 && mustRefreshData ? RefreshDataAsync(false) : Task.CompletedTask;
+ if (columns.Count > 0 && mustRefreshData)
+ await RefreshDataAsync(false);
}
- return base.OnParametersSetAsync();
+ await base.OnParametersSetAsync();
}
///
@@ -170,9 +183,9 @@ private string GetColumnSummaryValue(GridSummaryColumnType type, string property
///
public async ValueTask ResetPageNumber() => await ResetPageNumberAsync(true);
- public Task SelectAllItemsAsync() => SelectAllItemsInternalAsync(true);
+ public async Task SelectAllItemsAsync() => await SelectAllItemsInternalAsync(true);
- public Task UnSelectAllItemsAsync() => SelectAllItemsInternalAsync(false);
+ public async Task UnSelectAllItemsAsync() => await SelectAllItemsInternalAsync(false);
internal void AddColumn(GridColumn column) => columns.Add(column);
@@ -254,6 +267,9 @@ internal async Task RefreshDataAsync(bool firstRender = false, CancellationToken
await RefreshSelectionAsync();
}
+ if (firstRender)
+ isColumnsLoading = false;
+
requestInProgress = false;
await InvokeAsync(StateHasChanged);
@@ -476,10 +492,12 @@ private async Task OnPageChangedAsync(int newPageNumber)
private async Task OnPageSizeChangedAsync(int newPageSize)
{
+ pendingPageSizeChanging = true;
pageSize = PageSize = newPageSize;
await ResetPageNumberAsync();
await SaveGridSettingsAsync();
await RefreshDataAsync(false);
+ pendingPageSizeChanging = false;
}
private async Task OnRowCheckboxChanged(string id, TItem item, ChangeEventArgs args)
@@ -564,14 +582,14 @@ private async Task RowDoubleClick(TItem item, EventArgs args)
await OnRowDoubleClick.InvokeAsync(new GridRowEventArgs(item));
}
- private Task SaveGridSettingsAsync()
+ private async Task SaveGridSettingsAsync()
{
if (!GridSettingsChanged.HasDelegate)
- return Task.CompletedTask;
+ return;
var settings = new GridSettings { PageNumber = AllowPaging ? gridCurrentState.PageIndex : 0, PageSize = AllowPaging ? pageSize : 0, Filters = AllowFiltering ? GetFilters() : null };
- return GridSettingsChanged.InvokeAsync(settings);
+ await GridSettingsChanged.InvokeAsync(settings);
}
private async Task SelectAllItemsInternalAsync(bool selectAll)
@@ -595,11 +613,9 @@ private async Task SelectAllItemsInternalAsync(bool selectAll)
SelectedItems = selectedItems;
}
- private Task SetCheckboxStateAsync(string id, CheckboxState checkboxState)
+ private async Task SetCheckboxStateAsync(string id, CheckboxState checkboxState)
{
- queuedTasks.Enqueue(async () => await JSRuntime.InvokeVoidAsync("window.blazorBootstrap.grid.setSelectAllCheckboxState", id, (int)checkboxState));
-
- return Task.CompletedTask;
+ await JSRuntime.InvokeVoidAsync("window.blazorBootstrap.grid.setSelectAllCheckboxState", id, (int)checkboxState);
}
///
diff --git a/blazorbootstrap/Components/Grid/GridColumnFilter.razor b/blazorbootstrap/Components/Grid/GridColumnFilter.razor
index 72e883b1b..22bc06a88 100644
--- a/blazorbootstrap/Components/Grid/GridColumnFilter.razor
+++ b/blazorbootstrap/Components/Grid/GridColumnFilter.razor
@@ -31,28 +31,7 @@
}
- @if (PropertyTypeName == StringConstants.PropertyTypeNameInt16
- || PropertyTypeName == StringConstants.PropertyTypeNameInt32
- || PropertyTypeName == StringConstants.PropertyTypeNameInt64
- || PropertyTypeName == StringConstants.PropertyTypeNameSingle // float
- || PropertyTypeName == StringConstants.PropertyTypeNameDecimal
- || PropertyTypeName == StringConstants.PropertyTypeNameDouble)
- {
- await OnFilterValueChangedAsync(args))">
- }
- else if (PropertyTypeName == StringConstants.PropertyTypeNameDateOnly)
- {
- await OnFilterValueChangedAsync(args))" />
- }
- else if (PropertyTypeName == StringConstants.PropertyTypeNameDateTime)
- {
- await OnFilterValueChangedAsync(args))" />
- }
- else if (PropertyTypeName == StringConstants.PropertyTypeNameBoolean)
- {
- await OnFilterValueChangedAsync(args))" />
- }
- else if (PropertyTypeName == StringConstants.PropertyTypeNameEnum)
+ @if (PropertyTypeName == StringConstants.PropertyTypeNameEnum)
{
@@ -77,8 +56,8 @@
}
- else // guid or string
+ else
{
- await OnFilterValueChangedAsync(args))" />
+ @InputFilterTemplate
}
diff --git a/blazorbootstrap/Components/Grid/GridColumnFilter.razor.cs b/blazorbootstrap/Components/Grid/GridColumnFilter.razor.cs
index f7685aadd..7ade87d29 100644
--- a/blazorbootstrap/Components/Grid/GridColumnFilter.razor.cs
+++ b/blazorbootstrap/Components/Grid/GridColumnFilter.razor.cs
@@ -72,6 +72,62 @@ or StringConstants.PropertyTypeNameDecimal
}
}
+ private RenderFragment InputFilterTemplate => builder =>
+ {
+ string inputType;
+ string inputClass;
+
+ switch (PropertyTypeName)
+ {
+ case StringConstants.PropertyTypeNameInt16:
+ case StringConstants.PropertyTypeNameInt32:
+ case StringConstants.PropertyTypeNameInt64:
+ case StringConstants.PropertyTypeNameSingle:
+ case StringConstants.PropertyTypeNameDecimal:
+ case StringConstants.PropertyTypeNameDouble:
+ inputType = "number";
+ inputClass = "form-control";
+ break;
+ case StringConstants.PropertyTypeNameDateOnly:
+ inputType = "date";
+ inputClass = "form-control";
+ break;
+ case StringConstants.PropertyTypeNameDateTime:
+ inputType = "datetime-local";
+ inputClass = "form-control";
+ break;
+ case StringConstants.PropertyTypeNameBoolean:
+ inputType = "checkbox";
+ inputClass = "form-check-input";
+ break;
+ default:
+ inputType = "text";
+ inputClass = "form-control";
+ break;
+ }
+
+ builder.OpenElement(100, "input");
+ builder.AddAttribute(101, "class", inputClass);
+
+ builder.AddAttribute(102, "type", inputType);
+ builder.AddAttribute(103, "value", filterValue);
+
+ if (PropertyTypeName == StringConstants.PropertyTypeNameBoolean)
+ {
+ if ((bool.TryParse(filterValue, out bool isChecked)) && isChecked)
+ builder.AddAttribute(104, "checked", "checked");
+
+ builder.AddAttribute(106, "onchange", async (ChangeEventArgs args) => await OnFilterValueChangedAsync(args));
+ }
+ else
+ {
+ builder.AddAttribute(105, "style", filterStyle);
+ builder.AddAttribute(106, "oninput", async (ChangeEventArgs args) => await OnFilterValueChangedAsync(args));
+ }
+
+ builder.CloseElement();
+ };
+
private async Task> GetFilterOperatorsAsync(string propertyTypeName)
{
if (FiltersTranslationProvider is null)
diff --git a/blazorbootstrap/Components/Sidebar/Sidebar.razor b/blazorbootstrap/Components/Sidebar/Sidebar.razor
index 9d16f2902..7038e04ca 100644
--- a/blazorbootstrap/Components/Sidebar/Sidebar.razor
+++ b/blazorbootstrap/Components/Sidebar/Sidebar.razor
@@ -7,7 +7,7 @@