diff --git a/PrimeNG.TableFilter.Test/PrimeNG.TableFilter.Test.csproj b/PrimeNG.TableFilter.Test/PrimeNG.TableFilter.Test.csproj
index 4e5942b..58e58e1 100644
--- a/PrimeNG.TableFilter.Test/PrimeNG.TableFilter.Test.csproj
+++ b/PrimeNG.TableFilter.Test/PrimeNG.TableFilter.Test.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/PrimeNG.TableFilter/Core/ITableFilterManager.cs b/PrimeNG.TableFilter/Core/ITableFilterManager.cs
index 88c9980..c42b92a 100644
--- a/PrimeNG.TableFilter/Core/ITableFilterManager.cs
+++ b/PrimeNG.TableFilter/Core/ITableFilterManager.cs
@@ -9,6 +9,7 @@ public interface ITableFilterManager
void MultipleOrderDataSet(TableFilterModel tableFilterPayload);
void SingleOrderDataSet(TableFilterModel tableFilterPayload);
void FilterDataSet(string key, TableFilterContext value);
+ void FilterDataSet(string key, TableFilterContext value, OperatorEnumeration opMode);
void FiltersDataSet(string key, IEnumerable values);
void ExecuteFilter();
IQueryable GetResult();
diff --git a/PrimeNG.TableFilter/Core/LinqOperator.cs b/PrimeNG.TableFilter/Core/LinqOperator.cs
index 742cc0d..bbb9e6d 100644
--- a/PrimeNG.TableFilter/Core/LinqOperator.cs
+++ b/PrimeNG.TableFilter/Core/LinqOperator.cs
@@ -49,17 +49,64 @@ public void AddFilterProperty(
OperatorEnumeration operatorAction,
bool isNegation = false)
{
- var property = _context.DataSetType.GetProperty(propertyName);
+ PropertyInfo property = null;
+ foreach (var item in propertyName.Split('.'))
+ {
+ if (property == null)
+ property = _context.DataSetType.GetProperty(item.FirstCharToUpper());
+ else
+ property = property.PropertyType.GetProperty(item.FirstCharToUpper());
+ }
var propertyType = property?.PropertyType;
if (propertyType == null)
return;
- if (!IsPropertyTypeAndFilterMatchModeValid(propertyType, extensionMethod))
+ if (propertyType != typeof(string) && extensionMethod == LinqOperatorConstants.ConstantContains)
+ {
+ if (propertyType == typeof(DateTime) || propertyType == typeof(DateTime?))
+ {
+ extensionMethod = LinqOperatorConstants.ConstantDateIs;
+ if (DateTime.TryParse(propertyValue.ToString(), out var currentDate))
+ propertyValue = currentDate;
+ else
+ return;
+ }
+ else if (propertyType == typeof(bool) || propertyType == typeof(bool?))
+ {
+ extensionMethod = LinqOperatorConstants.ConstantEquals;
+ if (bool.TryParse(propertyValue.ToString(),out var currentBoolean))
+ propertyValue = currentBoolean;
+ else
+ return;
+ }
+ else if (IsNumericType(propertyType))
+ {
+ extensionMethod = LinqOperatorConstants.ConstantEquals;
+ if ((propertyType == typeof(short) || propertyType == typeof(short?)) && short.TryParse(propertyValue.ToString(), out var currentShort))
+ propertyValue = currentShort;
+ else if ((propertyType == typeof(int) || propertyType == typeof(int?)) && int.TryParse(propertyValue.ToString(), out var currentInt))
+ propertyValue = currentInt;
+ else if ((propertyType == typeof(long) || propertyType == typeof(long?)) && long.TryParse(propertyValue.ToString(), out var currentLong))
+ propertyValue = currentLong;
+ else if ((propertyType == typeof(float) || propertyType == typeof(float?)) && float.TryParse(propertyValue.ToString(), out var currentFloat))
+ propertyValue = currentFloat;
+ else if ((propertyType == typeof(double) || propertyType == typeof(double?)) && double.TryParse(propertyValue.ToString(), out var currentDouble))
+ propertyValue = currentDouble;
+ else if ((propertyType == typeof(decimal) || propertyType == typeof(decimal?)) && decimal.TryParse(propertyValue.ToString(), out var currentDecimal))
+ propertyValue = currentDecimal;
+ else if ((propertyType.IsEnum || (Nullable.GetUnderlyingType(propertyType)?.IsEnum == true)) && int.TryParse(propertyValue.ToString(), out var currentEnum))
+ propertyValue = currentEnum;
+ else
+ return;
+ }
+ }
+
+ if (!IsPropertyTypeAndFilterMatchModeValid(propertyType, extensionMethod))
throw new ArgumentException($"Property ${propertyName} not support method ${extensionMethod}");
var castValue = ObjectCasterUtil.CastPropertiesType(property, propertyValue);
- var propertyConstant = Expression.Constant(castValue, propertyType);
+ var propertyConstant = propertyType.IsEnum ? Expression.Constant(castValue, typeof(int)) : Expression.Constant(castValue, propertyType);
if (IsNullableType(propertyType))
{
@@ -90,8 +137,14 @@ public void AddFilterProperty(
return;
case string _:
{
- var propertyAccess = Expression.MakeMemberAccess(_context.ParameterExpression,
- property ?? throw new InvalidOperationException());
+ MemberExpression propertyAccess = null;
+ foreach (var item in propertyName.Split('.'))
+ {
+ if (propertyAccess == null)
+ propertyAccess = Expression.PropertyOrField(_context.ParameterExpression, item.FirstCharToUpper());
+ else
+ propertyAccess = Expression.PropertyOrField(propertyAccess, item.FirstCharToUpper());
+ }
var methodInfo = propertyType.GetMethod(extensionMethod, new[] { propertyType });
if (isNegation)
@@ -193,13 +246,31 @@ public void ThenByDescending(string orderProperty) =>
private void BaseOrderExecute(string command, string orderByProperty)
{
- var property = _context.DataSetType.GetProperty(orderByProperty);
- var propertyAccess =
- Expression.MakeMemberAccess(_context.ParameterExpression,
- property ?? throw new InvalidOperationException());
+ PropertyInfo property = null;
+ foreach (var item in orderByProperty.Split('.'))
+ {
+ if (property == null)
+ property = _context.DataSetType.GetProperty(item.FirstCharToUpper());
+ else
+ property = property.PropertyType.GetProperty(item.FirstCharToUpper());
+ }
+ var propertyType = property?.PropertyType;
+
+ if (propertyType == null)
+ return;
+
+ MemberExpression propertyAccess = null;
+ foreach (var item in orderByProperty.Split('.'))
+ {
+ if (propertyAccess == null)
+ propertyAccess = Expression.PropertyOrField(_context.ParameterExpression, item);
+ else
+ propertyAccess = Expression.PropertyOrField(propertyAccess, item);
+ }
+
var orderByExpression = Expression.Lambda(propertyAccess, _context.ParameterExpression);
var resultExpression = Expression.Call(typeof(Queryable), command,
- new[] { _context.DataSetType, property.PropertyType },
+ new[] { _context.DataSetType, propertyType },
_context.DataSet.Expression, Expression.Quote(orderByExpression));
_context.DataSet = _context.DataSet.Provider.CreateQuery(resultExpression);
}
@@ -220,8 +291,13 @@ private static bool IsNullableType(Type propertyType)
/// True
if nullable, otherwise False
private static bool IsNumericType(Type propertyType)
{
- return (propertyType == typeof(short) || propertyType == typeof(short?) || propertyType == typeof(int) || propertyType == typeof(int?) || propertyType == typeof(long) || propertyType == typeof(long?)
- || propertyType == typeof(float) || propertyType == typeof(float?) || propertyType == typeof(double) || propertyType == typeof(double?) || propertyType == typeof(decimal) || propertyType == typeof(decimal?));
+ return ((propertyType == typeof(short) || propertyType == typeof(short?)) ||
+ (propertyType == typeof(int) || propertyType == typeof(int?)) ||
+ (propertyType == typeof(long) || propertyType == typeof(long?)) ||
+ (propertyType == typeof(float) || propertyType == typeof(float?)) ||
+ (propertyType == typeof(double) || propertyType == typeof(double?)) ||
+ (propertyType == typeof(decimal) || propertyType == typeof(decimal?)) ||
+ (propertyType.IsEnum || (Nullable.GetUnderlyingType(propertyType)?.IsEnum == true)));
}
///
/// Checks if for provided , is valid
diff --git a/PrimeNG.TableFilter/Core/TableFilterManager.cs b/PrimeNG.TableFilter/Core/TableFilterManager.cs
index c335295..a846a4e 100644
--- a/PrimeNG.TableFilter/Core/TableFilterManager.cs
+++ b/PrimeNG.TableFilter/Core/TableFilterManager.cs
@@ -49,16 +49,16 @@ public void MultipleOrderDataSet(TableFilterModel tableFilterPayload)
{
case (int)SortingEnumeration.OrderByAsc:
if (o.i == 0)
- _linqOperator.OrderBy(o.value.Field.FirstCharToUpper());
+ _linqOperator.OrderBy(o.value.Field);
else
- _linqOperator.ThenBy(o.value.Field.FirstCharToUpper());
+ _linqOperator.ThenBy(o.value.Field);
break;
case (int)SortingEnumeration.OrderByDesc:
if (o.i == 0)
- _linqOperator.OrderByDescending(o.value.Field.FirstCharToUpper());
+ _linqOperator.OrderByDescending(o.value.Field);
else
- _linqOperator.ThenByDescending(o.value.Field.FirstCharToUpper());
+ _linqOperator.ThenByDescending(o.value.Field);
break;
default:
@@ -77,11 +77,11 @@ public void SingleOrderDataSet(TableFilterModel tableFilterPayload)
switch (tableFilterPayload.SortOrder)
{
case (int)SortingEnumeration.OrderByAsc:
- _linqOperator.OrderBy(tableFilterPayload.SortField.FirstCharToUpper());
+ _linqOperator.OrderBy(tableFilterPayload.SortField);
break;
case (int)SortingEnumeration.OrderByDesc:
- _linqOperator.OrderByDescending(tableFilterPayload.SortField.FirstCharToUpper());
+ _linqOperator.OrderByDescending(tableFilterPayload.SortField);
break;
default:
@@ -97,6 +97,15 @@ public void SingleOrderDataSet(TableFilterModel tableFilterPayload)
public void FilterDataSet(string key, TableFilterContext value)
=> BaseFilterDataSet(key, value, OperatorEnumeration.None);
+ ///
+ /// Set filter condition data to LINQ Operation context
+ ///
+ /// Name of property
+ /// PrimeNG filter context
+ /// PrimeNG filter connection operator
+ public void FilterDataSet(string key, TableFilterContext value, OperatorEnumeration filterOperator)
+ => BaseFilterDataSet(key, value, filterOperator);
+
///
/// The base method for set filter condition data to LINQ Operation context
///
@@ -112,87 +121,85 @@ private void BaseFilterDataSet(string key, TableFilterContext value, OperatorEnu
switch (value.MatchMode)
{
case ConstantTypeMatchModeStartsWith:
- _linqOperator.AddFilterProperty(key.FirstCharToUpper(), value.Value,
+ _linqOperator.AddFilterProperty(key, value.Value,
LinqOperatorConstants.ConstantStartsWith
, operatorAction);
break;
case ConstantTypeMatchModeContains:
- _linqOperator.AddFilterProperty(key.FirstCharToUpper(), value.Value,
+ _linqOperator.AddFilterProperty(key, value.Value,
LinqOperatorConstants.ConstantContains
, operatorAction);
break;
case ConstantTypeMatchModeIn:
- _linqOperator.AddFilterListProperty(key.FirstCharToUpper(), value.Value
+ _linqOperator.AddFilterListProperty(key, value.Value
, operatorAction);
break;
case ConstantTypeMatchModeEndsWith:
- _linqOperator.AddFilterProperty(key.FirstCharToUpper(), value.Value,
+ _linqOperator.AddFilterProperty(key, value.Value,
LinqOperatorConstants.ConstantEndsWith
, OperatorEnumeration.None);
break;
case ConstantTypeMatchModeEquals:
- _linqOperator.AddFilterProperty(key.FirstCharToUpper(), value.Value,
+ _linqOperator.AddFilterProperty(key, value.Value,
LinqOperatorConstants.ConstantEquals
, operatorAction);
break;
case ConstantTypeMatchModeNotContains:
- _linqOperator.AddFilterProperty(key.FirstCharToUpper(), value.Value,
+ _linqOperator.AddFilterProperty(key, value.Value,
LinqOperatorConstants.ConstantContains
, OperatorEnumeration.None, true);
break;
case ConstantTypeMatchModeNotEquals:
- _linqOperator.AddFilterProperty(key.FirstCharToUpper(), value.Value,
+ _linqOperator.AddFilterProperty(key, value.Value,
LinqOperatorConstants.ConstantEquals
, operatorAction, true);
break;
case ConstantTypeMatchModeDateIs:
- _linqOperator.AddFilterProperty(key.FirstCharToUpper(), value.Value,
+ _linqOperator.AddFilterProperty(key, value.Value,
LinqOperatorConstants.ConstantDateIs
, operatorAction);
break;
case ConstantTypeMatchModeDateIsNot:
- _linqOperator.AddFilterProperty(key.FirstCharToUpper(), value.Value,
+ _linqOperator.AddFilterProperty(key, value.Value,
LinqOperatorConstants.ConstantDateIs
, operatorAction, true);
break;
case ConstantTypeMatchModeDateBefore:
- _linqOperator.AddFilterProperty(key.FirstCharToUpper(), value.Value,
+ _linqOperator.AddFilterProperty(key, value.Value,
LinqOperatorConstants.ConstantBefore
, operatorAction);
break;
case ConstantTypeMatchModeDateAfter:
- _linqOperator.AddFilterProperty(key.FirstCharToUpper(), value.Value,
+ _linqOperator.AddFilterProperty(key, value.Value,
LinqOperatorConstants.ConstantAfter
, operatorAction);
break;
case ConstantTypeMatchModeLessThan:
- _linqOperator.AddFilterProperty(key.FirstCharToUpper(), value.Value,
+ _linqOperator.AddFilterProperty(key, value.Value,
LinqOperatorConstants.ConstantLessThan
, operatorAction);
break;
case ConstantTypeMatchModeLessOrEqualsThan:
- _linqOperator.AddFilterProperty(key.FirstCharToUpper(), value.Value,
+ _linqOperator.AddFilterProperty(key, value.Value,
LinqOperatorConstants.ConstantLessThanOrEqual
, operatorAction);
break;
case ConstantTypeMatchModeGreaterThan:
- _linqOperator.AddFilterProperty(key.FirstCharToUpper(), value.Value,
+ _linqOperator.AddFilterProperty(key, value.Value,
LinqOperatorConstants.ConstantGreaterThan
, operatorAction);
break;
case ConstantTypeMatchModeGreaterOrEqualsThan:
- _linqOperator.AddFilterProperty(key.FirstCharToUpper(), value.Value,
+ _linqOperator.AddFilterProperty(key, value.Value,
LinqOperatorConstants.ConstantGreaterThanOrEqual
, operatorAction);
break;
-
-
default:
throw new System.ArgumentException("Invalid Match mode!");
}
diff --git a/PrimeNG.TableFilter/Models/TableFilterModel.cs b/PrimeNG.TableFilter/Models/TableFilterModel.cs
index d5ff3c4..1fd0a3b 100644
--- a/PrimeNG.TableFilter/Models/TableFilterModel.cs
+++ b/PrimeNG.TableFilter/Models/TableFilterModel.cs
@@ -5,11 +5,11 @@ namespace PrimeNG.TableFilter.Models
{
public class TableFilterModel
{
- public Dictionary Filters { get; set; }
- public int First { get; set; }
- public int Rows { get; set; }
+ public Dictionary Filters { get; set; } = new Dictionary();
+ public int First { get; set; } = 0;
+ public int Rows { get; set; } = 10;
public string SortField { get; set; }
public int SortOrder { get; set; }
- public List MultiSortMeta { get; set; }
+ public List MultiSortMeta { get; set; } = new List();
}
}
diff --git a/PrimeNG.TableFilter/PrimeNG.TableFilter.csproj b/PrimeNG.TableFilter/PrimeNG.TableFilter.csproj
index 1f90658..de8d20c 100644
--- a/PrimeNG.TableFilter/PrimeNG.TableFilter.csproj
+++ b/PrimeNG.TableFilter/PrimeNG.TableFilter.csproj
@@ -9,7 +9,7 @@
https://github.com/Kusumoto/PrimeNG.TableFilter
2.1.2
2.1.2
- net462;netstandard2.1;net6.0;net5.0
+ net462;netstandard2.1;net6.0;net5.0;net7.0
false
LICENSE.md
2.1.2
@@ -21,8 +21,8 @@
-
-
+
+
diff --git a/PrimeNG.TableFilter/PrimeNGTableFilterExtension.cs b/PrimeNG.TableFilter/PrimeNGTableFilterExtension.cs
index 4419585..b126097 100644
--- a/PrimeNG.TableFilter/PrimeNGTableFilterExtension.cs
+++ b/PrimeNG.TableFilter/PrimeNGTableFilterExtension.cs
@@ -42,9 +42,25 @@ public static IQueryable PrimengTableFilter(this IQueryable dataSet,
{
ITableFilterManager tableFilterManager = new TableFilterManager(dataSet);
-
if (tableFilterPayload.Filters != null && tableFilterPayload.Filters.Any())
{
+ if (tableFilterPayload.Filters.ContainsKey("global"))
+ {
+ var filterPayload = tableFilterPayload.Filters["global"]?.ToString();
+ if (filterPayload != null)
+ {
+ var filterToken = JToken.Parse(filterPayload);
+ var filter = filterToken.ToObject();
+ if (filter != null)
+ {
+ foreach (var filterContext in tableFilterPayload.Filters)
+ {
+ tableFilterManager.FilterDataSet(filterContext.Key, filter, OperatorEnumeration.Or);
+ }
+ }
+ }
+ }
+
foreach (var filterContext in tableFilterPayload.Filters)
{
var filterPayload = filterContext.Value.ToString();
@@ -52,17 +68,17 @@ public static IQueryable PrimengTableFilter(this IQueryable dataSet,
switch (filterToken)
{
case JArray _:
- {
- var filters = filterToken.ToObject>();
- tableFilterManager.FiltersDataSet(filterContext.Key, filters);
- break;
- }
+ {
+ var filters = filterToken.ToObject>();
+ tableFilterManager.FiltersDataSet(filterContext.Key, filters);
+ break;
+ }
case JObject _:
- {
+ {
var filter = filterToken.ToObject();
tableFilterManager.FilterDataSet(filterContext.Key, filter);
- break;
- }
+ break;
+ }
}
}
tableFilterManager.ExecuteFilter();
diff --git a/PrimeNG.TableFilter/Properties/PublishProfiles/Net4.6.2.pubxml b/PrimeNG.TableFilter/Properties/PublishProfiles/Net4.6.2.pubxml
new file mode 100644
index 0000000..5c62fe3
--- /dev/null
+++ b/PrimeNG.TableFilter/Properties/PublishProfiles/Net4.6.2.pubxml
@@ -0,0 +1,14 @@
+
+
+
+
+ Release
+ Any CPU
+ bin\Release\net462\publish\
+ FileSystem
+ <_TargetId>Folder
+ net462
+
+
\ No newline at end of file
diff --git a/PrimeNG.TableFilter/Properties/PublishProfiles/Net5.0.pubxml b/PrimeNG.TableFilter/Properties/PublishProfiles/Net5.0.pubxml
new file mode 100644
index 0000000..2a5fe8e
--- /dev/null
+++ b/PrimeNG.TableFilter/Properties/PublishProfiles/Net5.0.pubxml
@@ -0,0 +1,15 @@
+
+
+
+
+ Release
+ Any CPU
+ bin\Release\net5.0\publish\
+ FileSystem
+ <_TargetId>Folder
+ net5.0
+ false
+
+
\ No newline at end of file
diff --git a/PrimeNG.TableFilter/Properties/PublishProfiles/Net6.0.pubxml b/PrimeNG.TableFilter/Properties/PublishProfiles/Net6.0.pubxml
new file mode 100644
index 0000000..95b2920
--- /dev/null
+++ b/PrimeNG.TableFilter/Properties/PublishProfiles/Net6.0.pubxml
@@ -0,0 +1,15 @@
+
+
+
+
+ Release
+ Any CPU
+ bin\Release\net6.0\publish\
+ FileSystem
+ <_TargetId>Folder
+ net6.0
+ false
+
+
\ No newline at end of file
diff --git a/PrimeNG.TableFilter/Properties/PublishProfiles/Net7.0.pubxml b/PrimeNG.TableFilter/Properties/PublishProfiles/Net7.0.pubxml
new file mode 100644
index 0000000..d348e50
--- /dev/null
+++ b/PrimeNG.TableFilter/Properties/PublishProfiles/Net7.0.pubxml
@@ -0,0 +1,15 @@
+
+
+
+
+ Release
+ Any CPU
+ bin\Release\net7.0\publish\
+ FileSystem
+ <_TargetId>Folder
+ net7.0
+ false
+
+
\ No newline at end of file
diff --git a/PrimeNG.TableFilter/Properties/PublishProfiles/NetStandard2.1.pubxml b/PrimeNG.TableFilter/Properties/PublishProfiles/NetStandard2.1.pubxml
new file mode 100644
index 0000000..a1ffed3
--- /dev/null
+++ b/PrimeNG.TableFilter/Properties/PublishProfiles/NetStandard2.1.pubxml
@@ -0,0 +1,14 @@
+
+
+
+
+ Release
+ Any CPU
+ bin\Release\netstandard2.1\publish\
+ FileSystem
+ <_TargetId>Folder
+ netstandard2.1
+
+
\ No newline at end of file
diff --git a/PrimeNG.TableFilter/Utils/ObjectCasterUtil.cs b/PrimeNG.TableFilter/Utils/ObjectCasterUtil.cs
index 4375141..1589681 100644
--- a/PrimeNG.TableFilter/Utils/ObjectCasterUtil.cs
+++ b/PrimeNG.TableFilter/Utils/ObjectCasterUtil.cs
@@ -42,7 +42,9 @@ public static object CastPropertiesTypeList(PropertyInfo property, object value)
if (property?.PropertyType == typeof(decimal))
return arrayCast.ToObject>();
if (property?.PropertyType == typeof(decimal?))
- return arrayCast.ToObject>();
+ return arrayCast.ToObject>();
+ if (Nullable.GetUnderlyingType(property?.PropertyType).IsEnum)
+ return arrayCast.ToObject>();
return arrayCast.ToObject>();
}
@@ -81,8 +83,9 @@ public static object CastPropertiesType(PropertyInfo property, object value)
if (property?.PropertyType == typeof(decimal))
return Convert.ToDecimal(value);
if (property?.PropertyType == typeof(decimal?))
- return Convert.ToDecimal(value);
-
+ return Convert.ToDecimal(value);
+ if (property?.PropertyType.IsEnum == true)
+ return Convert.ToInt32(value);
return value.ToString();
}
diff --git a/PrimeNG.TableFilter/Utils/StringUtil.cs b/PrimeNG.TableFilter/Utils/StringUtil.cs
index 88dd80d..52fb264 100644
--- a/PrimeNG.TableFilter/Utils/StringUtil.cs
+++ b/PrimeNG.TableFilter/Utils/StringUtil.cs
@@ -11,7 +11,7 @@ public static string FirstCharToUpper(this string input)
{
case null: throw new ArgumentNullException(nameof(input));
case "": throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input));
- default: return input.First().ToString().ToUpper() + input.Substring(1);
+ default: return input.First().ToString().ToUpperInvariant() + input.Substring(1);
}
}
}