DataGrid LoadColumnFilterData event added to load column filter data for DataGrid FilterMode.CheckBoxList filter mode (#1600)

* DataGrid LoadColumnFilterData event added

* CheckBoxList with OData support added
This commit is contained in:
Vladimir Enchev
2024-07-17 10:58:55 +03:00
committed by GitHub
parent 397fe2a0c8
commit cfe2424cff
9 changed files with 182 additions and 48 deletions

View File

@@ -2471,6 +2471,30 @@ namespace Radzen
internal IEnumerable<T> Data { get; set; }
}
/// <summary>
/// Supplies information about a <see cref="RadzenDataGrid{TItem}.LoadColumnFilterData" /> event that is being raised.
/// </summary>
public class DataGridLoadColumnFilterDataEventArgs<T>
{
/// <summary>
/// Gets or sets the data.
/// </summary>
/// <value>The data.</value>
public IEnumerable Data { get; set; }
/// <summary>
/// Gets or sets the total data count.
/// </summary>
/// <value>The total data count.</value>
public int Count { get; set; }
/// <summary>
/// Gets the column.
/// </summary>
/// <value>The column.</value>
public RadzenDataGridColumn<T> Column { get; internal set; }
}
/// <summary>
/// Supplies information about a <see cref="RadzenPager.PageChanged" /> event that is being raised.
/// </summary>

View File

@@ -231,9 +231,10 @@ namespace Radzen
/// <param name="orderby">The orderby.</param>
/// <param name="expand">The expand.</param>
/// <param name="select">The select.</param>
/// <param name="apply">The apply.</param>
/// <param name="count">if set to <c>true</c> [count].</param>
/// <returns>Uri.</returns>
public static Uri GetODataUri(this Uri uri, string filter = null, int? top = null, int? skip = null, string orderby = null, string expand = null, string select = null, bool? count = null)
public static Uri GetODataUri(this Uri uri, string filter = null, int? top = null, int? skip = null, string orderby = null, string expand = null, string select = null, string apply = null, bool? count = null)
{
var uriBuilder = new UriBuilder(uri);
var queryString = HttpUtility.ParseQueryString(uriBuilder.Query);
@@ -268,6 +269,11 @@ namespace Radzen
queryString["$select"] = $"{select}";
}
if (!string.IsNullOrEmpty(apply))
{
queryString["$apply"] = $"{apply}";
}
if (count != null)
{
queryString["$count"] = $"{count}".ToLower();

View File

@@ -271,6 +271,14 @@ namespace Radzen.Blazor
}
}
/// <summary>
/// Gets or sets the callback used to load column filter data for DataGrid FilterMode.CheckBoxList filter mode.
/// </summary>
/// <value>The load filter data event callback.</value>
[Parameter]
public EventCallback<DataGridLoadColumnFilterDataEventArgs<TItem>> LoadColumnFilterData { get; set; }
/// <summary>
/// Gets or sets the load child data callback.
/// </summary>

View File

@@ -974,32 +974,12 @@ namespace Radzen.Blazor
return filterValue ?? FilterValue;
}
IEnumerable filterValues;
internal IEnumerable GetFilterValues()
{
if (filterValues == null && Grid.Data != null && !string.IsNullOrEmpty(GetFilterProperty()))
{
var property = GetFilterProperty();
var propertyType = PropertyAccess.GetPropertyType(typeof(TItem), GetFilterProperty());
if (property.IndexOf(".") != -1)
{
property = $"np({property})";
}
if (propertyType == typeof(string))
{
property = $@"({property} == null ? """" : {property})";
}
filterValues = Grid.Data.AsQueryable().Where<TItem>(Grid.allColumns.Where(c => c != this)).Select(DynamicLinqCustomTypeProvider.ParsingConfig, property).Distinct().Cast(propertyType ?? typeof(object));
}
return filterValues;
}
internal void ClearFilterValues()
{
filterValues = null;
if (headerCell != null)
{
headerCell.filterValues = null;
}
}
/// <summary>

View File

@@ -146,9 +146,9 @@
}
else
{
<RadzenListBox AllowVirtualization="true" AllowClear="true" Multiple="true" Style="height: 300px"
TValue="IEnumerable<object>" Data=@Column.GetFilterValues() Value=@Column.GetFilterValue()
Change="@ListBoxChange"
<RadzenListBox AllowVirtualization="true" AllowClear="true" Multiple="true" Style="height: 300px"
TValue="IEnumerable<object>" Value=@Column.GetFilterValue() Change="@ListBoxChange"
Data=@filterValues Count=@filterValuesCount LoadData="@LoadFilterValues"
AllowFiltering="@(!string.IsNullOrEmpty(Column.GetFilterProperty()) && PropertyAccess.GetPropertyType(typeof(TItem), Column.GetFilterProperty()) == typeof(string))"
Disabled="@(!Column.CanSetFilterValue())" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive"
InputAttributes="@(new Dictionary<string,object>(){ { "aria-label", Column.Title + Grid.FilterValueArialLabel + Column.GetFilterValue() }})">
@@ -193,6 +193,40 @@ else
Radzen.Blazor.Rendering.Popup popup;
ElementReference filterButton;
int filterValuesCount;
internal IEnumerable filterValues;
async Task LoadFilterValues()
{
var property = Column.GetFilterProperty();
var propertyType = PropertyAccess.GetPropertyType(typeof(TItem), property);
if (property.IndexOf(".") != -1)
{
property = $"np({property})";
}
if (propertyType == typeof(string))
{
property = $@"({property} == null ? """" : {property})";
}
if (Column.Grid.LoadColumnFilterData.HasDelegate)
{
var args = new DataGridLoadColumnFilterDataEventArgs<TItem>() { Column = Column };
await Column.Grid.LoadColumnFilterData.InvokeAsync(args);
filterValues = args.Data.AsQueryable().Select(DynamicLinqCustomTypeProvider.ParsingConfig, property).Distinct().Cast(propertyType ?? typeof(object));
filterValuesCount = args.Count;
}
else if(filterValues == null && Column.Grid.Data != null && !string.IsNullOrEmpty(property))
{
var query = Column.Grid.Data.AsQueryable().Where<TItem>(Column.Grid.allColumns.Where(c => c != Column)).Select(DynamicLinqCustomTypeProvider.ParsingConfig, property).Distinct().Cast(propertyType ?? typeof(object));
filterValues = query;
filterValuesCount = query.Count();
}
}
void ListBoxChange(object args)
{
var enumerable = args as IEnumerable;

View File

@@ -0,0 +1,64 @@
@using System.Linq.Dynamic.Core
@using RadzenBlazorDemos.Data
@using RadzenBlazorDemos.Models.Northwind
@using Microsoft.EntityFrameworkCore
@inherits DbContextPage
<RadzenDataGrid AllowFiltering="true" AllowColumnResize="true" IsLoading="@isLoading" TItem="Order"
FilterMode="FilterMode.CheckBoxList" FilterPopupRenderMode="PopupRenderMode.OnDemand" PageSize="5" AllowPaging="true" AllowSorting="true"
Data="@orders" Count="@count" LoadData="@LoadData" LoadColumnFilterData="@LoadColumnFilterData" ColumnWidth="300px">
<Columns>
<RadzenDataGridColumn Property="OrderID" Title="Order ID" />
<RadzenDataGridColumn Property="Customer.CompanyName" Title="Customer" />
<RadzenDataGridColumn Property="Employee.LastName" Title="Employee">
<Template Context="order">
<RadzenImage Path="@order.Employee?.Photo" style="width: 32px; height: 32px; border-radius: 16px; margin-right: 6px;" AlternateText="@(order.Employee?.FirstName + " " + order.Employee?.LastName)" />
@order.Employee?.FirstName @order.Employee?.LastName
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn Property="@nameof(Order.OrderDate)" Title="Order Date" FormatString="{0:d}" />
<RadzenDataGridColumn Property="@nameof(Order.RequiredDate)" Title="Required Date" FormatString="{0:d}" />
<RadzenDataGridColumn Property="@nameof(Order.ShippedDate)" Title="Shipped Date" FormatString="{0:d}" />
<RadzenDataGridColumn Property="@nameof(Order.ShipName)" Title="Ship Name" />
<RadzenDataGridColumn Property="@nameof(Order.ShipCountry)" Title="Ship Country" />
</Columns>
</RadzenDataGrid>
@code {
NorthwindODataService service = new NorthwindODataService("https://services.radzen.com/odata/Northwind/");
IEnumerable<Order> orders;
int count;
bool isLoading;
async Task LoadData(LoadDataArgs args)
{
isLoading = true;
var result = await service.GetOrders(filter: args.Filter, top: args.Top, skip: args.Skip, orderby: args.OrderBy, count: true, expand: "Customer,Employee");
orders = result.Value.AsODataEnumerable();
count = result.Count;
isLoading = false;
}
async Task LoadColumnFilterData(DataGridLoadColumnFilterDataEventArgs<Order> args)
{
// Get the property name in OData format. Sub-properties are separated by /.
var property = args.Column.GetFilterProperty().Replace(".","/");
// Get the distinct values for the property in OData format for the current column.
var result = await service.GetOrders(count: true, apply: $"groupby(({property}))", expand: GetODataExpand(property));
args.Count = result.Count;
args.Data = result.Value;
}
string GetODataExpand(string property)
{
var properties = property.Split("/");
return properties.Count() > 1 ? $"{string.Join("/", properties.Take(properties.Length - 1))}($select={properties.LastOrDefault()})" : null;
}
}

View File

@@ -0,0 +1,9 @@
@page "/datagrid-checkboxlist-filter-odata"
<RadzenText TextStyle="TextStyle.H2" TagName="TagName.H1" class="rz-pt-8">
DataGrid <strong>CheckBox list (Excel like) Filter</strong>
</RadzenText>
<RadzenExample ComponentName="DataGrid" Example="DataGridCheckBoxListFilterOData">
<DataGridCheckBoxListFilterOData />
</RadzenExample>

View File

@@ -349,6 +349,15 @@ namespace RadzenBlazorDemos
Tags = new [] { "filter", "excel", "grid", "datagrid", "table", "menu", "checkbox", "list" }
},
new Example
{
New = true,
Name = "CheckBoxList with OData",
Path = "datagrid-checkboxlist-filter-odata",
Title = "Blazor DataGrid Component - Excel like filtering with OData | Free UI Components by Radzen",
Description = "RadzenDataGrid Excel like filtering with OData.",
Tags = new [] { "filter", "excel", "grid", "datagrid", "table", "menu", "checkbox", "list", "odata" }
},
new Example
{
New = true,
Name = "Enum filtering",

View File

@@ -24,10 +24,10 @@ namespace RadzenBlazorDemos
this.baseUri = new Uri(url);
}
partial void OnGetCategories(HttpRequestMessage requestMessage);
public async Task<ODataServiceResult<Category>> GetCategories(string filter = default(string), int? top = default(int?), int? skip = default(int?), string orderby = default(string), string expand = default(string), string select = default(string), bool? count = default(bool?))
public async Task<ODataServiceResult<Category>> GetCategories(string filter = default(string), int? top = default(int?), int? skip = default(int?), string orderby = default(string), string expand = default(string), string select = default(string), string apply = default(string), bool? count = default(bool?))
{
var uri = new Uri(baseUri, $"Categories");
uri = uri.GetODataUri(filter:filter, top:top, skip:skip, orderby:orderby, expand:expand, select:select, count:count);
uri = uri.GetODataUri(filter:filter, top:top, skip:skip, orderby:orderby, expand:expand, select:select, apply:apply, count:count);
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
@@ -91,10 +91,10 @@ namespace RadzenBlazorDemos
return await response.ReadAsync<Category>();
}
partial void OnGetCustomerDemographics(HttpRequestMessage requestMessage);
public async Task<ODataServiceResult<CustomerDemographic>> GetCustomerDemographics(string filter = default(string), int? top = default(int?), int? skip = default(int?), string orderby = default(string), string expand = default(string), string select = default(string), bool? count = default(bool?))
public async Task<ODataServiceResult<CustomerDemographic>> GetCustomerDemographics(string filter = default(string), int? top = default(int?), int? skip = default(int?), string orderby = default(string), string expand = default(string), string select = default(string), string apply = default(string), bool? count = default(bool?))
{
var uri = new Uri(baseUri, $"CustomerDemographics");
uri = uri.GetODataUri(filter:filter, top:top, skip:skip, orderby:orderby, expand:expand, select:select, count:count);
uri = uri.GetODataUri(filter:filter, top:top, skip:skip, orderby:orderby, expand:expand, select:select, apply:apply, count:count);
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
@@ -158,10 +158,10 @@ namespace RadzenBlazorDemos
return await response.ReadAsync<CustomerDemographic>();
}
partial void OnGetCustomers(HttpRequestMessage requestMessage);
public async Task<ODataServiceResult<Customer>> GetCustomers(string filter = default(string), int? top = default(int?), int? skip = default(int?), string orderby = default(string), string expand = default(string), string select = default(string), bool? count = default(bool?))
public async Task<ODataServiceResult<Customer>> GetCustomers(string filter = default(string), int? top = default(int?), int? skip = default(int?), string orderby = default(string), string expand = default(string), string select = default(string), string apply = default(string), bool? count = default(bool?))
{
var uri = new Uri(baseUri, $"Customers");
uri = uri.GetODataUri(filter:filter, top:top, skip:skip, orderby:orderby, expand:expand, select:select, count:count);
uri = uri.GetODataUri(filter:filter, top:top, skip:skip, orderby:orderby, expand:expand, select:select, apply:apply, count:count);
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
@@ -225,10 +225,10 @@ namespace RadzenBlazorDemos
return await response.ReadAsync<Customer>();
}
partial void OnGetEmployees(HttpRequestMessage requestMessage);
public async Task<ODataServiceResult<Employee>> GetEmployees(string filter = default(string), int? top = default(int?), int? skip = default(int?), string orderby = default(string), string expand = default(string), string select = default(string), bool? count = default(bool?))
public async Task<ODataServiceResult<Employee>> GetEmployees(string filter = default(string), int? top = default(int?), int? skip = default(int?), string orderby = default(string), string expand = default(string), string select = default(string), string apply = default(string), bool? count = default(bool?))
{
var uri = new Uri(baseUri, $"Employees");
uri = uri.GetODataUri(filter:filter, top:top, skip:skip, orderby:orderby, expand:expand, select:select, count:count);
uri = uri.GetODataUri(filter:filter, top:top, skip:skip, orderby:orderby, expand:expand, select:select, apply:apply, count:count);
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
@@ -292,10 +292,10 @@ namespace RadzenBlazorDemos
return await response.ReadAsync<Employee>();
}
partial void OnGetOrderDetails(HttpRequestMessage requestMessage);
public async Task<ODataServiceResult<OrderDetail>> GetOrderDetails(string filter = default(string), int? top = default(int?), int? skip = default(int?), string orderby = default(string), string expand = default(string), string select = default(string), bool? count = default(bool?))
public async Task<ODataServiceResult<OrderDetail>> GetOrderDetails(string filter = default(string), int? top = default(int?), int? skip = default(int?), string orderby = default(string), string expand = default(string), string select = default(string), string apply = default(string), bool? count = default(bool?))
{
var uri = new Uri(baseUri, $"NorthwindOrderDetails");
uri = uri.GetODataUri(filter:filter, top:top, skip:skip, orderby:orderby, expand:expand, select:select, count:count);
uri = uri.GetODataUri(filter:filter, top:top, skip:skip, orderby:orderby, expand:expand, select:select, apply:apply, count:count);
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
@@ -359,10 +359,10 @@ namespace RadzenBlazorDemos
return await response.ReadAsync<OrderDetail>();
}
partial void OnGetOrders(HttpRequestMessage requestMessage);
public async Task<ODataServiceResult<Order>> GetOrders(string filter = default(string), int? top = default(int?), int? skip = default(int?), string orderby = default(string), string expand = default(string), string select = default(string), bool? count = default(bool?))
public async Task<ODataServiceResult<Order>> GetOrders(string filter = default(string), int? top = default(int?), int? skip = default(int?), string orderby = default(string), string expand = default(string), string select = default(string), string apply = default(string), bool? count = default(bool?))
{
var uri = new Uri(baseUri, $"NorthwindOrders");
uri = uri.GetODataUri(filter:filter, top:top, skip:skip, orderby:orderby, expand:expand, select:select, count:count);
uri = uri.GetODataUri(filter:filter, top:top, skip:skip, orderby:orderby, expand:expand, select:select, apply:apply, count:count);
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
@@ -426,10 +426,10 @@ namespace RadzenBlazorDemos
return await response.ReadAsync<Order>();
}
partial void OnGetProducts(HttpRequestMessage requestMessage);
public async Task<ODataServiceResult<Product>> GetProducts(string filter = default(string), int? top = default(int?), int? skip = default(int?), string orderby = default(string), string expand = default(string), string select = default(string), bool? count = default(bool?))
public async Task<ODataServiceResult<Product>> GetProducts(string filter = default(string), int? top = default(int?), int? skip = default(int?), string orderby = default(string), string expand = default(string), string select = default(string), string apply = default(string), bool? count = default(bool?))
{
var uri = new Uri(baseUri, $"NorthwindProducts");
uri = uri.GetODataUri(filter:filter, top:top, skip:skip, orderby:orderby, expand:expand, select:select, count:count);
uri = uri.GetODataUri(filter:filter, top:top, skip:skip, orderby:orderby, expand:expand, select:select, apply:apply, count:count);
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
@@ -493,10 +493,10 @@ namespace RadzenBlazorDemos
return await response.ReadAsync<Product>();
}
partial void OnGetRegions(HttpRequestMessage requestMessage);
public async Task<ODataServiceResult<Region>> GetRegions(string filter = default(string), int? top = default(int?), int? skip = default(int?), string orderby = default(string), string expand = default(string), string select = default(string), bool? count = default(bool?))
public async Task<ODataServiceResult<Region>> GetRegions(string filter = default(string), int? top = default(int?), int? skip = default(int?), string orderby = default(string), string expand = default(string), string select = default(string), string apply = default(string), bool? count = default(bool?))
{
var uri = new Uri(baseUri, $"Regions");
uri = uri.GetODataUri(filter:filter, top:top, skip:skip, orderby:orderby, expand:expand, select:select, count:count);
uri = uri.GetODataUri(filter:filter, top:top, skip:skip, orderby:orderby, expand:expand, select:select, apply:apply, count:count);
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
@@ -560,10 +560,10 @@ namespace RadzenBlazorDemos
return await response.ReadAsync<Region>();
}
partial void OnGetSuppliers(HttpRequestMessage requestMessage);
public async Task<ODataServiceResult<Supplier>> GetSuppliers(string filter = default(string), int? top = default(int?), int? skip = default(int?), string orderby = default(string), string expand = default(string), string select = default(string), bool? count = default(bool?))
public async Task<ODataServiceResult<Supplier>> GetSuppliers(string filter = default(string), int? top = default(int?), int? skip = default(int?), string orderby = default(string), string expand = default(string), string select = default(string), string apply = default(string), bool? count = default(bool?))
{
var uri = new Uri(baseUri, $"Suppliers");
uri = uri.GetODataUri(filter:filter, top:top, skip:skip, orderby:orderby, expand:expand, select:select, count:count);
uri = uri.GetODataUri(filter:filter, top:top, skip:skip, orderby:orderby, expand:expand, select:select, apply:apply, count:count);
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
@@ -627,10 +627,10 @@ namespace RadzenBlazorDemos
return await response.ReadAsync<Supplier>();
}
partial void OnGetTerritories(HttpRequestMessage requestMessage);
public async Task<ODataServiceResult<Territory>> GetTerritories(string filter = default(string), int? top = default(int?), int? skip = default(int?), string orderby = default(string), string expand = default(string), string select = default(string), bool? count = default(bool?))
public async Task<ODataServiceResult<Territory>> GetTerritories(string filter = default(string), int? top = default(int?), int? skip = default(int?), string orderby = default(string), string expand = default(string), string select = default(string), string apply = default(string), bool? count = default(bool?))
{
var uri = new Uri(baseUri, $"Territories");
uri = uri.GetODataUri(filter:filter, top:top, skip:skip, orderby:orderby, expand:expand, select:select, count:count);
uri = uri.GetODataUri(filter:filter, top:top, skip:skip, orderby:orderby, expand:expand, select:select, apply:apply, count:count);
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri);