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) - { - - } - else if (PropertyTypeName == StringConstants.PropertyTypeNameDateOnly) - { - - } - else if (PropertyTypeName == StringConstants.PropertyTypeNameDateTime) - { - - } - else if (PropertyTypeName == StringConstants.PropertyTypeNameBoolean) - { - - } - else if (PropertyTypeName == StringConstants.PropertyTypeNameEnum) + @if (PropertyTypeName == StringConstants.PropertyTypeNameEnum) { @@ -77,8 +56,8 @@ } - else // guid or string + else { - + @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 @@