Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 23 additions & 13 deletions blazorbootstrap/Components/Grid/Grid.razor
Original file line number Diff line number Diff line change
Expand Up @@ -68,21 +68,31 @@
}

<th class="@string.Join(" ", columnClassList)" style="@string.Join(";", columnStyleList)">
@if (column.Filterable)

@if (isColumnsLoading)
{
<GridColumnFilter EnumFilterSelectText="@EnumFilterSelectText"
FilterButtonColor="@column.FilterButtonColor"
FilterButtonCSSClass="@column.FilterButtonCSSClass"
FilterOperator="@column.FilterOperator"
FilterValue="@column.FilterValue"
FilterWidth="@column.FilterTextboxWidth"
FiltersTranslationProvider="GridFiltersTranslationProviderAsync!"
FixedHeader="@FixedHeader"
GridColumnFilterChanged="async args => await column.OnFilterChangedAsync(args, column)"
PropertyType="@column.GetPropertyType()"
PropertyTypeName="@column.GetPropertyTypeName()"
Unit="@column.FilterTextboxWidthUnit" />
<PlaceholderContainer Animation="PlaceholderAnimation.Glow">
<Placeholder Width="PlaceholderWidth.Col12" />
</PlaceholderContainer>
}
else
{
@if (column.Filterable)
{
<GridColumnFilter EnumFilterSelectText="@EnumFilterSelectText"
FilterButtonColor="@column.FilterButtonColor"
FilterButtonCSSClass="@column.FilterButtonCSSClass"
FilterOperator="@column.FilterOperator"
FilterValue="@column.FilterValue"
FilterWidth="@column.FilterTextboxWidth"
FiltersTranslationProvider="GridFiltersTranslationProviderAsync!"
FixedHeader="@FixedHeader"
GridColumnFilterChanged="async args => await column.OnFilterChangedAsync(args, column)"
PropertyType="@column.GetPropertyType()"
PropertyTypeName="@column.GetPropertyTypeName()"
Unit="@column.FilterTextboxWidthUnit" />
}
}
</th>
}
</tr>
Expand Down
44 changes: 30 additions & 14 deletions blazorbootstrap/Components/Grid/Grid.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ public partial class Grid<TItem> : BlazorBootstrapComponentBase

private int? totalCount = null;

private bool pendingPageSizeChanging = false;

private bool isColumnsLoading = false;

#endregion

#region Methods
Expand All @@ -68,17 +72,25 @@ 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.");

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
Expand All @@ -93,8 +105,8 @@ protected override Task OnParametersSetAsync()
{
mustRefreshData = true;
pageSize = PageSize;
_ = ResetPageNumberAsync();
SaveGridSettingsAsync();
await ResetPageNumberAsync();
await SaveGridSettingsAsync();
}

//if (!mustRefreshData && selectedItems != SelectedItems)
Expand All @@ -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();
}

/// <summary>
Expand Down Expand Up @@ -170,9 +183,9 @@ private string GetColumnSummaryValue(GridSummaryColumnType type, string property
/// </summary>
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<TItem> column) => columns.Add(column);

Expand Down Expand Up @@ -254,6 +267,9 @@ internal async Task RefreshDataAsync(bool firstRender = false, CancellationToken
await RefreshSelectionAsync();
}

if (firstRender)
isColumnsLoading = false;

requestInProgress = false;

await InvokeAsync(StateHasChanged);
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -564,14 +582,14 @@ private async Task RowDoubleClick(TItem item, EventArgs args)
await OnRowDoubleClick.InvokeAsync(new GridRowEventArgs<TItem>(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)
Expand All @@ -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);
}

/// <summary>
Expand Down
27 changes: 3 additions & 24 deletions blazorbootstrap/Components/Grid/GridColumnFilter.razor
Original file line number Diff line number Diff line change
Expand Up @@ -31,28 +31,7 @@
}
</ul>

@if (PropertyTypeName == StringConstants.PropertyTypeNameInt16
|| PropertyTypeName == StringConstants.PropertyTypeNameInt32
|| PropertyTypeName == StringConstants.PropertyTypeNameInt64
|| PropertyTypeName == StringConstants.PropertyTypeNameSingle // float
|| PropertyTypeName == StringConstants.PropertyTypeNameDecimal
|| PropertyTypeName == StringConstants.PropertyTypeNameDouble)
{
<input class="form-control" style="@filterStyle" type="number" value="@filterValue" @oninput="@(async args => await OnFilterValueChangedAsync(args))">
}
else if (PropertyTypeName == StringConstants.PropertyTypeNameDateOnly)
{
<input class="form-control" style="@filterStyle" type="date" value="@filterValue" @oninput="@(async args => await OnFilterValueChangedAsync(args))" />
}
else if (PropertyTypeName == StringConstants.PropertyTypeNameDateTime)
{
<input class="form-control" style="@filterStyle" type="datetime-local" value="@filterValue" @oninput="@(async args => await OnFilterValueChangedAsync(args))" />
}
else if (PropertyTypeName == StringConstants.PropertyTypeNameBoolean)
{
<input class="form-check-input" type="checkbox" value="@filterValue" @onchange="@(async args => await OnFilterValueChangedAsync(args))" />
}
else if (PropertyTypeName == StringConstants.PropertyTypeNameEnum)
@if (PropertyTypeName == StringConstants.PropertyTypeNameEnum)
{
<Dropdown Color="DropdownColor.Light">
<DropdownToggleButton Class="px-1" Style="@filterStyle">
Expand All @@ -77,8 +56,8 @@
</DropdownMenu>
</Dropdown>
}
else // guid or string
else
{
<input class="form-control" style="@filterStyle" type="text" value="@filterValue" @oninput="@(async args => await OnFilterValueChangedAsync(args))" />
@InputFilterTemplate
}
</div>
56 changes: 56 additions & 0 deletions blazorbootstrap/Components/Grid/GridColumnFilter.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<IEnumerable<FilterOperatorInfo>> GetFilterOperatorsAsync(string propertyTypeName)
{
if (FiltersTranslationProvider is null)
Expand Down
2 changes: 1 addition & 1 deletion blazorbootstrap/Components/Sidebar/Sidebar.razor
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<div class="bb-sidebar-top-row navbar">
<div class="container-fluid ps-3">
<a class="navbar-brand d-flex align-items-center" href="@Href">
<a class="navbar-brand d-flex align-items-center" href="@Href" @onclick=HideNavMenuOnMobile>
@if (!string.IsNullOrWhiteSpace(ImageSrc))
{
<span class="navbar-brand-image me-2">
Expand Down
3 changes: 3 additions & 0 deletions blazorbootstrap/Components/Sidebar/Sidebar.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,10 @@ public void ToggleSidebar()
internal void HideNavMenuOnMobile()
{
if (isMobile && !collapseNavMenu)
{
collapseNavMenu = true;
StateHasChanged();
}
}

private string GetNavMenuCssClass()
Expand Down
2 changes: 1 addition & 1 deletion blazorbootstrap/Components/Sidebar2/Sidebar2.razor
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<aside @ref="@Element" id="@Id" class="@ClassNames" style="@StyleNames" role="navigation" @attributes="@AdditionalAttributes">
<div class="bb-sidebar2-top-row navbar">
<div class="container-fluid ps-3">
<a class="navbar-brand d-flex align-items-center" href="@Href">
<a class="navbar-brand d-flex align-items-center" href="@Href" @onclick=HideNavMenuOnMobile>
@if (!string.IsNullOrWhiteSpace(ImageSrc))
{
<span class="navbar-brand-image me-2">
Expand Down
3 changes: 3 additions & 0 deletions blazorbootstrap/Components/Sidebar2/Sidebar2.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@ public void ToggleSidebar()
internal void HideNavMenuOnMobile()
{
if (isMobile && !collapseNavMenu)
{
collapseNavMenu = true;
StateHasChanged();
}
}

private string GetNavMenuCssClass()
Expand Down