Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
Use Blazor Bootstrap grid component to display tabular data from the data source. And it supports client-side and server-side filtering, paging & sorting.
</div>

<CarbonAds />
@* <CarbonAds />

<SectionHeading Size="HeadingSize.H2" Text="Client side filtering" PageUrl="@pageUrl" HashTagName="client-side-filtering" />
<div>For filtering, <code>AllowFiltering</code> and <code>PropertyName</code> parameters are required.</div>
Expand Down Expand Up @@ -207,7 +207,10 @@
<Demo Type="typeof(Grid_Demo_34_AutoHide_Paging)" Tabs="true" />

<SectionHeading Size="HeadingSize.H2" Text="Filter with enum" PageUrl="@pageUrl" HashTagName="filter-with-enum" />
<Demo Type="typeof(Grid_Demo_35_Enum_Filters)" Tabs="true" />
<Demo Type="typeof(Grid_Demo_35_Enum_Filters)" Tabs="true" /> *@

<SectionHeading Size="HeadingSize.H2" Text="Filter with guid" PageUrl="@pageUrl" HashTagName="filter-with-guid" />
<Demo Type="typeof(Grid_Demo_36_Guid_Filters)" Tabs="true" />

@code {
private string pageUrl = "/grid";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<Grid @ref="grid"
TItem="User"
Class="table table-hover table-bordered table-striped"
DataProvider="UsersDataProvider"
AllowFiltering="true"
Responsive="true">

<GridColumn TItem="User" HeaderText="Oid" PropertyName="Oid">
@context.Oid
</GridColumn>
<GridColumn TItem="User" HeaderText="Id" PropertyName="Id">
@context.Id
</GridColumn>
<GridColumn TItem="User" HeaderText="User Name" PropertyName="Name">
@context.Name
</GridColumn>
<GridColumn TItem="User" HeaderText="DOB" PropertyName="DOB">
@context.DOB
</GridColumn>
<GridColumn TItem="User" HeaderText="Status" PropertyName="Status">
@context.Status
</GridColumn>

</Grid>

@code {
BlazorBootstrap.Grid<User> grid = default!;
private IEnumerable<User> users = default!;

protected override async Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);
}

private async Task<GridDataProviderResult<User>> UsersDataProvider(GridDataProviderRequest<User> request)
{
if (users is null) // pull employees only one time for client-side filtering, sorting, and paging
users = GetUsers(); // call a service or an API to pull the employees

return await Task.FromResult(request.ApplyTo(users));
}

private IEnumerable<User> GetUsers()
{
return new List<User>
{
new User { Oid = Guid.NewGuid(), Id = 107, Name = "Alice", DOB = new DateOnly(1998, 11, 17), Status = UserStatus.Registered },
new User { Oid = Guid.NewGuid(), Id = null, Name = "Bob", DOB = new DateOnly(1985, 1, 5), Status = UserStatus.Verified },
new User { Oid = Guid.NewGuid(), Id = 106, Name = "John", DOB = new DateOnly(1995, 4, 17), Status = UserStatus.Registered },
new User { Oid = Guid.NewGuid(), Id = 104, Name = "Pop", DOB = new DateOnly(1985, 6, 8), Status = UserStatus.Registered },
new User { Oid = Guid.NewGuid(), Id = 105, Name = "Ronald", DOB = new DateOnly(1991, 8, 23), Status = UserStatus.VerificationPending },
new User { Oid = Guid.NewGuid(), Id = 102, Name = "Line", DOB = new DateOnly(1977, 1, 12), Status = UserStatus.VerificationPending },
new User { Oid = Guid.NewGuid(), Id = 101, Name = "Daniel", DOB = new DateOnly(1977, 1, 12), Status = UserStatus.Registered },
new User { Oid = Guid.NewGuid(), Id = 108, Name = "Zayne", DOB = new DateOnly(1991, 1, 1), Status = UserStatus.Verified },
new User { Oid = Guid.NewGuid(), Id = 109, Name = "Isha", DOB = null, Status = UserStatus.Verified },
new User { Oid = Guid.NewGuid(), Id = 110, Name = "Vijay", DOB = new DateOnly(1990, 7, 1), Status = UserStatus.Verified },
};
}

public record class User
{
public Guid Oid { get; set; }
public int? Id { get; set; }
public string? Name { get; set; }
public DateOnly? DOB { get; set; }
public UserStatus Status { get; set; }
}

public enum UserStatus
{
Registered,
VerificationPending,
Verified
}
}
5 changes: 5 additions & 0 deletions blazorbootstrap/Components/Grid/GridColumn.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ or StringConstants.PropertyTypeNameDecimal
if (filterOperator == FilterOperator.None)
FilterOperator = filterOperator = FilterOperator.Equals;
}
else if (propertyTypeName == StringConstants.PropertyTypeNameGuid)
{
if (filterOperator == FilterOperator.None)
FilterOperator = filterOperator = FilterOperator.Equals;
}
}

internal void SetFilterOperator(FilterOperator filterOperator) => FilterOperator = this.filterOperator = filterOperator;
Expand Down
2 changes: 1 addition & 1 deletion blazorbootstrap/Components/Grid/GridColumnFilter.razor
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
</DropdownMenu>
</Dropdown>
}
else // string
else // guid or string
{
<input class="form-control" style="@filterStyle" type="text" value="@filterValue" @oninput="@(async args => await OnFilterValueChangedAsync(args))" />
}
Expand Down
6 changes: 6 additions & 0 deletions blazorbootstrap/Components/Grid/GridColumnFilter.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ or StringConstants.PropertyTypeNameDecimal
if (filterOperator is FilterOperator.None or FilterOperator.Clear)
filterOperator = FilterOperator.Equals;
}
else if (PropertyTypeName == StringConstants.PropertyTypeNameGuid)
{
if (filterOperator is FilterOperator.None or FilterOperator.Clear)
filterOperator = FilterOperator.Equals;
}
}

private async Task<IEnumerable<FilterOperatorInfo>> GetFilterOperatorsAsync(string propertyTypeName)
Expand Down Expand Up @@ -135,6 +140,7 @@ or StringConstants.PropertyTypeNameDecimal
selectedFilterSymbol = filterOperators?.FirstOrDefault(x => x.FilterOperator == filterOperator)?.Symbol;
else if (PropertyTypeName == StringConstants.PropertyTypeNameBoolean) selectedFilterSymbol = filterOperators?.FirstOrDefault(x => x.FilterOperator == filterOperator)?.Symbol;
else if (PropertyTypeName == StringConstants.PropertyTypeNameEnum) selectedFilterSymbol = filterOperators?.FirstOrDefault(x => x.FilterOperator == filterOperator)?.Symbol;
else if (PropertyTypeName == StringConstants.PropertyTypeNameGuid) selectedFilterSymbol = filterOperators?.FirstOrDefault(x => x.FilterOperator == filterOperator)?.Symbol;
}

#endregion
Expand Down
109 changes: 74 additions & 35 deletions blazorbootstrap/Extensions/ExpressionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ public static ConstantExpression GetEnumConstantExpression<TItem>(FilterItem fil
{
ConstantExpression? value = null;

if(propertyType is not null && propertyType.IsEnum)
if (propertyType is not null && propertyType.IsEnum)
{
_ = Enum.TryParse(propertyType, filterItem.Value, out object filterValue);
value = Expression.Constant(filterValue);
Expand All @@ -335,6 +335,36 @@ public static Expression<Func<TItem, bool>> GetEnumNotEqualExpressionDelegate<TI

#endregion Enum

#region Guid

public static ConstantExpression GetGuidConstantExpression<TItem>(FilterItem filterItem, string propertyTypeName)
{
ConstantExpression? value = null;

_ = Guid.TryParse(filterItem.Value, out Guid filterValue);
value = Expression.Constant(filterValue);

return value!;
}

public static Expression<Func<TItem, bool>> GetGuidEqualExpressionDelegate<TItem>(ParameterExpression parameterExpression, FilterItem filterItem, string propertyTypeName)
{
var property = Expression.Property(parameterExpression, filterItem.PropertyName);
var expression = Expression.Equal(property, GetGuidConstantExpression<TItem>(filterItem, propertyTypeName));

return Expression.Lambda<Func<TItem, bool>>(expression, parameterExpression);
}

public static Expression<Func<TItem, bool>> GetGuidNotEqualExpressionDelegate<TItem>(ParameterExpression parameterExpression, FilterItem filterItem, string propertyTypeName)
{
var property = Expression.Property(parameterExpression, filterItem.PropertyName);
var expression = Expression.NotEqual(property, GetGuidConstantExpression<TItem>(filterItem, propertyTypeName));

return Expression.Lambda<Func<TItem, bool>>(expression, parameterExpression);
}

#endregion Guid

public static Expression<Func<TItem, bool>>? GetExpressionDelegate<TItem>(ParameterExpression parameterExpression, FilterItem filterItem)
{
var propertyType = typeof(TItem).GetPropertyType(filterItem.PropertyName);
Expand All @@ -347,56 +377,65 @@ or StringConstants.PropertyTypeNameSingle
or StringConstants.PropertyTypeNameDecimal
or StringConstants.PropertyTypeNameDouble)
return filterItem.Operator switch
{
FilterOperator.Equals => GetNumberEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.NotEquals => GetNumberNotEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.LessThan => GetNumberLessThanExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.LessThanOrEquals => GetNumberLessThanOrEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.GreaterThan => GetNumberGreaterThanExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.GreaterThanOrEquals => GetNumberGreaterThanOrEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
_ => GetNumberEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName)
};
{
FilterOperator.Equals => GetNumberEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.NotEquals => GetNumberNotEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.LessThan => GetNumberLessThanExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.LessThanOrEquals => GetNumberLessThanOrEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.GreaterThan => GetNumberGreaterThanExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.GreaterThanOrEquals => GetNumberGreaterThanOrEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
_ => GetNumberEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName)
};

if (propertyTypeName is StringConstants.PropertyTypeNameString
or StringConstants.PropertyTypeNameChar)
return filterItem.Operator switch
{
FilterOperator.Contains => GetStringContainsExpressionDelegate<TItem>(parameterExpression, filterItem),
FilterOperator.StartsWith => GetStringStartsWithExpressionDelegate<TItem>(parameterExpression, filterItem),
FilterOperator.EndsWith => GetStringEndsWithExpressionDelegate<TItem>(parameterExpression, filterItem),
FilterOperator.Equals => GetStringEqualsExpressionDelegate<TItem>(parameterExpression, filterItem),
FilterOperator.NotEquals => GetStringNotEqualsExpressionDelegate<TItem>(parameterExpression, filterItem),
_ => GetStringContainsExpressionDelegate<TItem>(parameterExpression, filterItem)
};
{
FilterOperator.Contains => GetStringContainsExpressionDelegate<TItem>(parameterExpression, filterItem),
FilterOperator.StartsWith => GetStringStartsWithExpressionDelegate<TItem>(parameterExpression, filterItem),
FilterOperator.EndsWith => GetStringEndsWithExpressionDelegate<TItem>(parameterExpression, filterItem),
FilterOperator.Equals => GetStringEqualsExpressionDelegate<TItem>(parameterExpression, filterItem),
FilterOperator.NotEquals => GetStringNotEqualsExpressionDelegate<TItem>(parameterExpression, filterItem),
_ => GetStringContainsExpressionDelegate<TItem>(parameterExpression, filterItem)
};

if (propertyTypeName is StringConstants.PropertyTypeNameDateOnly
or StringConstants.PropertyTypeNameDateTime)
return filterItem.Operator switch
{
FilterOperator.Equals => GetDateEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.NotEquals => GetDateNotEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.LessThan => GetDateLessThanExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.LessThanOrEquals => GetDateLessThanOrEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.GreaterThan => GetDateGreaterThanExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.GreaterThanOrEquals => GetDateGreaterThanOrEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
_ => GetDateEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName)
};
{
FilterOperator.Equals => GetDateEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.NotEquals => GetDateNotEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.LessThan => GetDateLessThanExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.LessThanOrEquals => GetDateLessThanOrEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.GreaterThan => GetDateGreaterThanExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.GreaterThanOrEquals => GetDateGreaterThanOrEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
_ => GetDateEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName)
};

if (propertyTypeName == StringConstants.PropertyTypeNameBoolean)
return filterItem.Operator switch
{
FilterOperator.Equals => GetBooleanEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.NotEquals => GetBooleanNotEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
_ => GetBooleanEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName)
};
{
FilterOperator.Equals => GetBooleanEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.NotEquals => GetBooleanNotEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
_ => GetBooleanEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName)
};

// Enum
if (propertyTypeName == StringConstants.PropertyTypeNameEnum)
return filterItem.Operator switch
{
FilterOperator.Equals => GetEnumEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyType, propertyTypeName),
FilterOperator.NotEquals => GetEnumNotEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyType, propertyTypeName),
_ => GetEnumEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyType, propertyTypeName)
FilterOperator.Equals => GetEnumEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyType!, propertyTypeName),
FilterOperator.NotEquals => GetEnumNotEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyType!, propertyTypeName),
_ => GetEnumEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyType!, propertyTypeName)
};

// Guid
if (propertyTypeName == StringConstants.PropertyTypeNameGuid)
return filterItem.Operator switch
{
FilterOperator.Equals => GetGuidEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
FilterOperator.NotEquals => GetGuidNotEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName),
_ => GetGuidEqualExpressionDelegate<TItem>(parameterExpression, filterItem, propertyTypeName)
};

return null;
Expand Down
3 changes: 3 additions & 0 deletions blazorbootstrap/Extensions/TypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ public static string GetPropertyTypeName(this Type type, string propertyName)
if (propertyType!.IsEnum)
return StringConstants.PropertyTypeNameEnum;

if (propertyTypeName.Contains(StringConstants.PropertyTypeNameGuid, StringComparison.InvariantCulture))
return StringConstants.PropertyTypeNameGuid;

return string.Empty;
}

Expand Down
1 change: 1 addition & 0 deletions blazorbootstrap/Models/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ internal class StringConstants
public const string PropertyTypeNameDateTime = "DateTime";
public const string PropertyTypeNameBoolean = "Boolean";
public const string PropertyTypeNameEnum = "Enum";
public const string PropertyTypeNameGuid = "Guid";

public const string DataBootstrapToggle = "data-bs-toggle";

Expand Down
14 changes: 14 additions & 0 deletions blazorbootstrap/Utilities/FilterOperatorHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,23 @@ or StringConstants.PropertyTypeNameDecimal

if (propertyTypeName == StringConstants.PropertyTypeNameEnum) return GetEnumFilterOperators();

if (propertyTypeName == StringConstants.PropertyTypeNameGuid) return GetEnumFilterOperators();

return new List<FilterOperatorInfo>();
}

public static IEnumerable<FilterOperatorInfo> GetGuidFilterOperators()
{
List<FilterOperatorInfo> result = new()
{
new FilterOperatorInfo("=", "Equals", FilterOperator.Equals),
new FilterOperatorInfo("!=", "Not equals", FilterOperator.NotEquals),
new FilterOperatorInfo("x", "Clear", FilterOperator.Clear)
};

return result;
}

public static IEnumerable<FilterOperatorInfo> GetNumberFilterOperators()
{
List<FilterOperatorInfo> result = new()
Expand Down