Skip to content

Commit 802893e

Browse files
committed
2 parents 907df26 + 5c59cc3 commit 802893e

File tree

10 files changed

+244
-27
lines changed

10 files changed

+244
-27
lines changed

Mvc.JQuery.Datatables/DataTableConfigVm.cs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,28 @@ public JToken SearchCols
7979

8080

8181

82+
private string _dom;
83+
8284
public string Dom
8385
{
84-
get {
85-
var sdom = "";
86-
if (ColVis) sdom += "C";
87-
if (TableTools) sdom += "T<\"clear\">";
88-
if (ShowPageSizes) sdom += "l";
89-
if (ShowSearch) sdom += "f";
90-
sdom += "tipr";
91-
return sdom;
86+
get
87+
{
88+
if (!string.IsNullOrEmpty(_dom))
89+
return _dom;
90+
91+
string str = "";
92+
if (this.ColVis)
93+
str += "C";
94+
if (this.TableTools)
95+
str += "T<\"clear\">";
96+
if (this.ShowPageSizes)
97+
str += "l";
98+
if (this.ShowSearch)
99+
str += "f";
100+
return str + "tipr";
92101
}
102+
103+
set { _dom = value; }
93104
}
94105

95106
public bool ColVis { get; set; }

Mvc.JQuery.Datatables/DataTablesFiltering.cs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,16 @@ public IQueryable<T> ApplyFiltersAndSort<T>(DataTablesParam dtParameters, IQuery
3131
var values = parts.Where(p => p != null);
3232
data = data.Where(string.Join(" or ", values), parameters.ToArray());
3333
}
34-
for (int i = 0; i < dtParameters.sSearchColumns.Count; i++)
34+
for (int i = 0; i < dtParameters.sSearchValues.Count; i++)
3535
{
3636
if (dtParameters.bSearchable[i])
3737
{
38-
var searchColumn = dtParameters.sSearchColumns[i];
38+
var searchColumn = dtParameters.sSearchValues[i];
3939
if (!string.IsNullOrWhiteSpace(searchColumn))
4040
{
41+
DataTablesPropertyInfo column = FindColumn(dtParameters, columns, i);
4142
var parameters = new List<object>();
42-
var filterClause = GetFilterClause(dtParameters.sSearchColumns[i], columns[i], parameters);
43+
var filterClause = GetFilterClause(searchColumn, column, parameters);
4344
if (string.IsNullOrWhiteSpace(filterClause) == false)
4445
{
4546
data = data.Where(filterClause, parameters.ToArray());
@@ -50,9 +51,9 @@ public IQueryable<T> ApplyFiltersAndSort<T>(DataTablesParam dtParameters, IQuery
5051
string sortString = "";
5152
for (int i = 0; i < dtParameters.iSortingCols; i++)
5253
{
53-
5454
int columnNumber = dtParameters.iSortCol[i];
55-
string columnName = columns[columnNumber].PropertyInfo.Name;
55+
DataTablesPropertyInfo column = FindColumn(dtParameters, columns, columnNumber);
56+
string columnName = column.PropertyInfo.Name;
5657
string sortDir = dtParameters.sSortDir[i];
5758
if (i != 0)
5859
sortString += ", ";
@@ -68,6 +69,18 @@ public IQueryable<T> ApplyFiltersAndSort<T>(DataTablesParam dtParameters, IQuery
6869
return data;
6970
}
7071

72+
private DataTablesPropertyInfo FindColumn(DataTablesParam dtParameters, DataTablesPropertyInfo[] columns, int i)
73+
{
74+
if (dtParameters.sColumnNames.Any())
75+
{
76+
return columns.First(x => x.PropertyInfo.Name == dtParameters.sColumnNames[i]);
77+
}
78+
else
79+
{
80+
return columns[i];
81+
}
82+
}
83+
7184
public delegate string ReturnedFilteredQueryForType(
7285
string query, string columnName, DataTablesPropertyInfo columnType, List<object> parametersForLinqQuery);
7386

Mvc.JQuery.Datatables/DataTablesModelBinder.cs

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Web.Mvc;
34

45
namespace Mvc.JQuery.Datatables
@@ -11,26 +12,83 @@ public class DataTablesModelBinder : IModelBinder
1112
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
1213
{
1314
var valueProvider = bindingContext.ValueProvider;
15+
int columns = GetValue<int>(valueProvider, "iColumns");
16+
if (columns == 0)
17+
{
18+
return BindV10Model(valueProvider);
19+
}
20+
else
21+
{
22+
return BindLegacyModel(valueProvider, columns);
23+
}
24+
}
1425

15-
DataTablesParam obj = new DataTablesParam(GetValue<int>(valueProvider, "iColumns"));
26+
private object BindV10Model(IValueProvider valueProvider)
27+
{
28+
DataTablesParam obj = new DataTablesParam();
29+
obj.iDisplayStart = GetValue<int>(valueProvider, "start");
30+
obj.iDisplayLength = GetValue<int>(valueProvider, "length");
31+
obj.sSearch = GetValue<string>(valueProvider, "search[value]");
32+
obj.bEscapeRegex = GetValue<bool>(valueProvider, "search[regex]");
33+
obj.sEcho = GetValue<int>(valueProvider, "draw");
34+
35+
int colIdx = 0;
36+
while (true)
37+
{
38+
string colPrefix = String.Format("columns[{0}]", colIdx);
39+
string colName = GetValue<string>(valueProvider, colPrefix+"[data]");
40+
if (String.IsNullOrWhiteSpace(colName)) {
41+
break;
42+
}
43+
obj.sColumnNames.Add(colName);
44+
obj.bSortable.Add(GetValue<bool>(valueProvider, colPrefix+"[orderable]"));
45+
obj.bSearchable.Add(GetValue<bool>(valueProvider, colPrefix+"[searchable]"));
46+
obj.sSearchValues.Add(GetValue<string>(valueProvider, colPrefix+"[search][value]"));
47+
obj.bEscapeRegexColumns.Add(GetValue<bool>(valueProvider, colPrefix+"[searchable][regex]"));
48+
colIdx++;
49+
}
50+
obj.iColumns = colIdx;
51+
colIdx = 0;
52+
while (true)
53+
{
54+
string colPrefix = String.Format("order[{0}]", colIdx);
55+
int? orderColumn = GetValue<int?>(valueProvider, colPrefix+"[column]");
56+
if (orderColumn.HasValue)
57+
{
58+
obj.iSortCol.Add(orderColumn.Value);
59+
obj.sSortDir.Add(GetValue<string>(valueProvider, colPrefix+"[dir]"));
60+
colIdx++;
61+
}
62+
else
63+
{
64+
break;
65+
}
66+
}
67+
obj.iSortingCols = colIdx;
68+
return obj;
69+
}
70+
71+
private DataTablesParam BindLegacyModel(IValueProvider valueProvider, int columns)
72+
{
73+
DataTablesParam obj = new DataTablesParam(columns);
1674

1775
obj.iDisplayStart = GetValue<int>(valueProvider, "iDisplayStart");
1876
obj.iDisplayLength = GetValue<int>(valueProvider, "iDisplayLength");
1977
obj.sSearch = GetValue<string>(valueProvider, "sSearch");
2078
obj.bEscapeRegex = GetValue<bool>(valueProvider, "bEscapeRegex");
2179
obj.iSortingCols = GetValue<int>(valueProvider, "iSortingCols");
2280
obj.sEcho = GetValue<int>(valueProvider, "sEcho");
23-
81+
2482
for (int i = 0; i < obj.iColumns; i++)
2583
{
2684
obj.bSortable.Add(GetValue<bool>(valueProvider, "bSortable_" + i));
2785
obj.bSearchable.Add(GetValue<bool>(valueProvider, "bSearchable_" + i));
28-
obj.sSearchColumns.Add(GetValue<string>(valueProvider, "sSearch_" + i));
86+
obj.sSearchValues.Add(GetValue<string>(valueProvider, "sSearch_" + i));
2987
obj.bEscapeRegexColumns.Add(GetValue<bool>(valueProvider, "bEscapeRegex_" + i));
3088
obj.iSortCol.Add(GetValue<int>(valueProvider, "iSortCol_" + i));
3189
obj.sSortDir.Add(GetValue<string>(valueProvider, "sSortDir_" + i));
3290
}
33-
return obj;
91+
return obj;
3492
}
3593

3694
private static T GetValue<T>(IValueProvider valueProvider, string key)

Mvc.JQuery.Datatables/DataTablesParam.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,20 @@ public class DataTablesParam
1515
public bool bEscapeRegex { get; set; }
1616
public int iSortingCols { get; set; }
1717
public int sEcho { get; set; }
18+
public List<string> sColumnNames { get; set; }
1819
public List<bool> bSortable { get; set; }
1920
public List<bool> bSearchable { get; set; }
20-
public List<string> sSearchColumns { get; set; }
21+
public List<string> sSearchValues { get; set; }
2122
public List<int> iSortCol { get; set; }
2223
public List<string> sSortDir { get; set; }
2324
public List<bool> bEscapeRegexColumns { get; set; }
2425

2526
public DataTablesParam()
2627
{
28+
sColumnNames = new List<string>();
2729
bSortable = new List<bool>();
2830
bSearchable = new List<bool>();
29-
sSearchColumns = new List<string>();
31+
sSearchValues = new List<string>();
3032
iSortCol = new List<int>();
3133
sSortDir = new List<string>();
3234
bEscapeRegexColumns = new List<bool>();
@@ -35,9 +37,10 @@ public DataTablesParam()
3537
public DataTablesParam(int iColumns)
3638
{
3739
this.iColumns = iColumns;
40+
sColumnNames = new List<string>(iColumns);
3841
bSortable = new List<bool>(iColumns);
3942
bSearchable = new List<bool>(iColumns);
40-
sSearchColumns = new List<string>(iColumns);
43+
sSearchValues = new List<string>(iColumns);
4144
iSortCol = new List<int>(iColumns);
4245
sSortDir = new List<string>(iColumns);
4346
bEscapeRegexColumns = new List<bool>(iColumns);

Mvc.JQuery.Datatables/DataTablesResult.cs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,37 +20,56 @@ public abstract class DataTablesResult : ActionResult
2020
/// <returns></returns>
2121
public static DataTablesResult<TSource> Create<TSource, TTransform>(IQueryable<TSource> q, DataTablesParam dataTableParam,
2222
Func<TSource, TTransform> transform, ArrayOutputType? arrayOutput = null)
23+
{
24+
return Create(q, dataTableParam, transform, new ResponseOptions<TSource>() { ArrayOutputType = arrayOutput });
25+
}
26+
27+
public static DataTablesResult<TSource> Create<TSource>(IQueryable<TSource> q, DataTablesParam dataTableParam,
28+
ArrayOutputType? arrayOutput = null)
29+
{
30+
return Create(q, dataTableParam, new ResponseOptions<TSource>() { ArrayOutputType = arrayOutput });
31+
}
32+
33+
/// <typeparam name="TSource"></typeparam>
34+
/// <typeparam name="TTransform"></typeparam>
35+
/// <param name="q">A queryable for the data. The properties of this can be marked up with [DataTablesAttribute] to control sorting/searchability/visibility</param>
36+
/// <param name="dataTableParam"></param>
37+
/// <param name="transform">//a transform for custom column rendering e.g. to do a custom date row => new { CreatedDate = row.CreatedDate.ToString("dd MM yy") } </param>
38+
/// <returns></returns>
39+
public static DataTablesResult<TSource> Create<TSource, TTransform>(IQueryable<TSource> q, DataTablesParam dataTableParam,
40+
Func<TSource, TTransform> transform, ResponseOptions<TSource> responseOptions = null)
2341
{
2442
var result = new DataTablesResult<TSource>(q, dataTableParam);
2543

2644
result.Data = result.Data
2745
.Transform<TSource, Dictionary<string, object>>(row => TransformTypeInfo.MergeTransformValuesIntoDictionary(transform, row))
2846
.Transform<Dictionary<string, object>, Dictionary<string, object>>(StringTransformers.StringifyValues);
2947

30-
result.Data = ApplyOutputRules(result.Data, arrayOutput);
48+
result.Data = ApplyOutputRules(result.Data, responseOptions);
3149

3250
return result;
3351
}
3452

3553
public static DataTablesResult<TSource> Create<TSource>(IQueryable<TSource> q, DataTablesParam dataTableParam,
36-
ArrayOutputType? arrayOutput = null)
54+
ResponseOptions<TSource> responseOptions = null)
3755
{
3856
var result = new DataTablesResult<TSource>(q, dataTableParam);
3957

58+
var dictionaryTransform = DataTablesTypeInfo<TSource>.ToDictionary(responseOptions);
4059
result.Data = result.Data
41-
.Transform<TSource, Dictionary<string, object>>(DataTablesTypeInfo<TSource>.ToDictionary)
60+
.Transform<TSource, Dictionary<string, object>>(dictionaryTransform)
4261
.Transform<Dictionary<string, object>, Dictionary<string, object>>(StringTransformers.StringifyValues);
4362

44-
result.Data = ApplyOutputRules(result.Data, arrayOutput);
63+
result.Data = ApplyOutputRules(result.Data, responseOptions);
4564

4665
return result;
4766
}
4867

49-
private static DataTablesData ApplyOutputRules(DataTablesData sourceData, ArrayOutputType? arrayOutput = null)
68+
private static DataTablesData ApplyOutputRules<TSource>(DataTablesData sourceData, ResponseOptions<TSource> responseOptions)
5069
{
5170
DataTablesData outputData = sourceData;
5271

53-
switch (arrayOutput)
72+
switch (responseOptions.ArrayOutputType)
5473
{
5574
case ArrayOutputType.ArrayOfObjects:
5675
// Nothing is needed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Reflection;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using Mvc.JQuery.Datatables.Models;
8+
9+
namespace Mvc.JQuery.Datatables
10+
{
11+
public class DataTablesRowIdAttribute : DataTablesAttributeBase
12+
{
13+
public bool EmitAsColumnName { get; set; }
14+
15+
public override void ApplyTo(ColDef colDef, PropertyInfo pi)
16+
{
17+
// This attribute does not affect rendering
18+
}
19+
20+
public DataTablesRowIdAttribute()
21+
{
22+
EmitAsColumnName = true;
23+
}
24+
}
25+
}

Mvc.JQuery.Datatables/Models/DataTablesData.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public class DataTablesData
1111
public object[] aaData { get; set; }
1212

1313

14-
public DataTablesData Transform<TData, TTransform>(Func<TData, TTransform> transformRow)
14+
public DataTablesData Transform<TData, TTransform>(Func<TData, TTransform> transformRow, ResponseOptions responseOptions = null)
1515
{
1616
var data = new DataTablesData
1717
{
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace Mvc.JQuery.Datatables.Models
8+
{
9+
public class ResponseOptions
10+
{
11+
public virtual ArrayOutputType? ArrayOutputType { get; set; }
12+
13+
public static ResponseOptions<TSource> For<TSource>(IQueryable<TSource> data,
14+
Action<ResponseOptions<TSource>> setOptions) where TSource : class
15+
{
16+
var responseOptions = new ResponseOptions<TSource>();
17+
setOptions(responseOptions);
18+
return responseOptions;
19+
}
20+
}
21+
22+
public class ResponseOptions<TSource> : ResponseOptions
23+
{
24+
public Func<TSource, object> DT_RowID
25+
{
26+
get
27+
{
28+
return dt_rowid;
29+
}
30+
set
31+
{
32+
dt_rowid = value;
33+
if (value != null)
34+
{
35+
ArrayOutputType = Models.ArrayOutputType.ArrayOfObjects;
36+
}
37+
}
38+
}
39+
private Func<TSource, object> dt_rowid;
40+
41+
public override ArrayOutputType? ArrayOutputType
42+
{
43+
get { return base.ArrayOutputType; }
44+
set
45+
{
46+
if (DT_RowID != null && value != Models.ArrayOutputType.ArrayOfObjects)
47+
{
48+
throw new ArgumentOutOfRangeException("ArrayOutputType", "ArrayOutputType must be ArrayOfObjects when DT_RowID is set");
49+
}
50+
base.ArrayOutputType = value;
51+
}
52+
}
53+
}
54+
}

Mvc.JQuery.Datatables/Mvc.JQuery.Datatables.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
<Compile Include="DataTablesExcludeAttribute.cs" />
8383
<Compile Include="DataTablesFiltering.cs" />
8484
<Compile Include="DataTablesFilterAttribute.cs" />
85+
<Compile Include="DataTablesRowIdAttribute.cs" />
8586
<Compile Include="LengthMenuVm.cs" />
8687
<Compile Include="Models\ArrayOutputType.cs" />
8788
<Compile Include="Models\ColDef.cs" />
@@ -105,6 +106,7 @@
105106
<Compile Include="DynamicLinq\Signature.cs" />
106107
<Compile Include="FilterDef.cs" />
107108
<Compile Include="Models\Language.cs" />
109+
<Compile Include="Models\ResponseOptions.cs" />
108110
<Compile Include="Reflection\DataTablesPropertyInfo.cs" />
109111
<Compile Include="Reflection\DataTablesTypeInfo.cs" />
110112
<Compile Include="Reflection\DataTablesTypeInfoHelper.cs" />

0 commit comments

Comments
 (0)