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
135 changes: 67 additions & 68 deletions Mvc.JQuery.Datatables/DataTablesHelper.cs
Original file line number Diff line number Diff line change
@@ -1,69 +1,68 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;

namespace Mvc.JQuery.Datatables
{
public static class DataTablesHelper
{

public static IHtmlString DataTableIncludes(this HtmlHelper helper, bool jqueryUi = false, bool filters = true, bool tableTools = true)
{
StringBuilder output = new StringBuilder();
Action<string> addJs = s => output.AppendLine(@"<script src=""" + s + @""" type=""text/javascript""></script>");
Action<string> addCss = s => output.AppendLine(@"<link type=""text/css"" href=""" + s + @""" rel=""stylesheet""/>");

addCss("/Content/DataTables/media/css/" + (jqueryUi ? ("jquery.dataTables_themeroller.css") : "jquery.dataTables.css"));
addJs("/Content/DataTables/media/js/jquery.dataTables.js");
if (filters) addJs("/Content/jquery.dataTables.columnFilter.js");
if (tableTools)
{
addJs("/Content/DataTables/extras/TableTools/media/js/ZeroClipboard.js");
addJs("/Content/DataTables/extras/TableTools/media/js/TableTools.js");
addCss("/Content/DataTables/extras/TableTools/media/css/TableTools.css");
}
return helper.Raw(output.ToString());

}

public static DataTableVm DataTableVm<TController, TResult>(this HtmlHelper html, string id, Expression<Func<TController, DataTablesResult<TResult>>> exp, IEnumerable<ColDef> columns = null)
{
if (columns == null || !columns.Any())
{
var propInfos = typeof (TResult).GetProperties().Where(p => p.GetGetMethod() != null).ToList();
var columnList = new List<ColDef>();
foreach (var propertyInfo in propInfos)
{
var displayNameAttribute = (DisplayNameAttribute) propertyInfo.GetCustomAttributes(typeof (DisplayNameAttribute), false).FirstOrDefault();
var displayName = displayNameAttribute == null ? propertyInfo.Name : displayNameAttribute.DisplayName;
columnList.Add(new ColDef()
{
Name = propertyInfo.Name,
DisplayName = displayName,
Type = propertyInfo.PropertyType
});
}
columns = columnList.ToArray();
}

var mi = exp.MethodInfo();
var controllerName = typeof(TController).Name;
controllerName = controllerName.Substring(0, controllerName.LastIndexOf("Controller"));
var urlHelper = new UrlHelper(html.ViewContext.RequestContext);
var ajaxUrl = urlHelper.Action(mi.Name, controllerName);
return new DataTableVm(id, ajaxUrl, columns);
}

public static DataTableVm DataTableVm(this HtmlHelper html, string id, string ajaxUrl, params string[] columns)
{
return new DataTableVm(id, ajaxUrl, columns.Select(c => ColDef.Create(c, (string)null, typeof(string))));
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;

namespace Mvc.JQuery.Datatables
{
public static class DataTablesHelper
{
public static IHtmlString DataTableIncludes(this HtmlHelper helper, bool jqueryUi = false, bool filters = true, bool tableTools = true)
{
StringBuilder output = new StringBuilder();
Action<string> addJs = s => output.AppendLine(@"<script src=""" + s + @""" type=""text/javascript""></script>");
Action<string> addCss = s => output.AppendLine(@"<link type=""text/css"" href=""" + s + @""" rel=""stylesheet""/>");

addCss("/Content/DataTables/media/css/" + (jqueryUi ? ("jquery.dataTables_themeroller.css") : "jquery.dataTables.css"));
addJs("/Content/DataTables/media/js/jquery.dataTables.js");
if (filters) addJs("/Content/jquery.dataTables.columnFilter.js");
if (tableTools)
{
addJs("/Content/DataTables/extras/TableTools/media/js/ZeroClipboard.js");
addJs("/Content/DataTables/extras/TableTools/media/js/TableTools.js");
addCss("/Content/DataTables/extras/TableTools/media/css/TableTools.css");
}
return helper.Raw(output.ToString());
}

public static DataTableVm DataTableVm<TController, TResult>(this HtmlHelper html, string id, Expression<Func<TController, DataTablesResult<TResult>>> exp, IEnumerable<ColDef> columns = null)
{
if (columns == null || !columns.Any())
{
//var propInfos = typeof (TResult).GetProperties().Where(p => p.GetGetMethod() != null).ToList();
var propInfos = TypeExtensions.GetSortedProperties<TResult>();
var columnList = new List<ColDef>();
foreach (var propertyInfo in propInfos)
{
var displayNameAttribute = (DisplayNameAttribute)propertyInfo.GetCustomAttributes(typeof(DisplayNameAttribute), false).FirstOrDefault();
var displayName = displayNameAttribute == null ? propertyInfo.Name : displayNameAttribute.DisplayName;
columnList.Add(new ColDef()
{
Name = propertyInfo.Name,
DisplayName = displayName,
Type = propertyInfo.PropertyType
});
}
columns = columnList.ToArray();
}

var mi = exp.MethodInfo();
var controllerName = typeof(TController).Name;
controllerName = controllerName.Substring(0, controllerName.LastIndexOf("Controller"));
var urlHelper = new UrlHelper(html.ViewContext.RequestContext);
var ajaxUrl = urlHelper.Action(mi.Name, controllerName);
return new DataTableVm(id, ajaxUrl, columns);
}

public static DataTableVm DataTableVm(this HtmlHelper html, string id, string ajaxUrl, params string[] columns)
{
return new DataTableVm(id, ajaxUrl, columns.Select(c => ColDef.Create(c, (string)null, typeof(string))));
}
}
}
73 changes: 38 additions & 35 deletions Mvc.JQuery.Datatables/DataTablesResult.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using Mvc.JQuery.Datatables.DynamicLinq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
using Mvc.JQuery.Datatables.DynamicLinq;

namespace Mvc.JQuery.Datatables
{
Expand All @@ -14,85 +15,85 @@ public static DataTablesResult<TRes> Create<T, TRes>(IQueryable<T> q, DataTables
{
return new DataTablesResult<T, TRes>(q, dataTableParam, transform);
}

public static DataTablesResult<T> Create<T>(IQueryable<T> q, DataTablesParam dataTableParam)
{
return new DataTablesResult<T, T>(q, dataTableParam, t => t);
}

public static DataTablesResult<T> CreateResultUsingEnumerable<T>(IEnumerable<T> q, DataTablesParam dataTableParam)
{
return new DataTablesResult<T, T>(q.AsQueryable(), dataTableParam, t => t);
}

public static DataTablesResult Create(object queryable, DataTablesParam dataTableParam)
{
queryable = ((IEnumerable) queryable).AsQueryable();
queryable = ((IEnumerable)queryable).AsQueryable();
var s = "Create";

var openCreateMethod =
typeof (DataTablesResult).GetMethods().Single(x => x.Name == s && x.GetGenericArguments().Count() == 1);
typeof(DataTablesResult).GetMethods().Single(x => x.Name == s && x.GetGenericArguments().Count() == 1);
var queryableType = queryable.GetType().GetGenericArguments()[0];
var closedCreateMethod = openCreateMethod.MakeGenericMethod(queryableType);
return (DataTablesResult) closedCreateMethod.Invoke(null, new[] {queryable, dataTableParam});
return (DataTablesResult)closedCreateMethod.Invoke(null, new[] { queryable, dataTableParam });
}

public static DataTablesResult<T> CreateResultUsingEnumerable<T>(IEnumerable<T> q, DataTablesParam dataTableParam)
{
return new DataTablesResult<T, T>(q.AsQueryable(), dataTableParam, t => t);
}
}

public class DataTablesResult<T> : DataTablesResult
{

}



public class DataTablesResult<T, TRes> : DataTablesResult<TRes>
{
private static readonly List<PropertyTransformer> PropertyTransformers = new List<PropertyTransformer>()
{
Guard<DateTimeOffset>(dateTimeOffset => dateTimeOffset.ToLocalTime().ToString("g")),
Guard<DateTime>(dateTime => dateTime.ToLocalTime().ToString("g")),
Guard<IHtmlString>(s => s.ToHtmlString()),
Guard<object>(o => (o ?? "").ToString())
};

private readonly Func<T, TRes> _transform;

public DataTablesResult(IQueryable<T> q, DataTablesParam dataTableParam, Func<T, TRes> transform)
{

_transform = transform;
var properties = typeof(TRes).GetProperties();

//var properties = typeof(TRes).GetProperties();
var properties = TypeExtensions.GetSortedProperties<TRes>();

var content = GetResults(q, dataTableParam, properties.Select(p => Tuple.Create(p.Name, (string)null, p.PropertyType)).ToArray());
this.Data = content;
this.JsonRequestBehavior = JsonRequestBehavior.DenyGet;
}

static readonly List<PropertyTransformer> PropertyTransformers = new List<PropertyTransformer>()
{
Guard<DateTimeOffset>(dateTimeOffset => dateTimeOffset.ToLocalTime().ToString("g")),
Guard<DateTime>(dateTime => dateTime.ToLocalTime().ToString("g")),
Guard<IHtmlString>(s => s.ToHtmlString()),
Guard<object>(o => (o ?? "").ToString())
};
public delegate object GuardedValueTransformer<TVal>(TVal value);

public delegate object PropertyTransformer(Type type, object value);
public delegate object GuardedValueTransformer<TVal>(TVal value);

static PropertyTransformer Guard<TVal>(GuardedValueTransformer<TVal> transformer)
public static void RegisterFilter<TVal>(GuardedValueTransformer<TVal> filter)
{
PropertyTransformers.Add(Guard<TVal>(filter));
}

private static PropertyTransformer Guard<TVal>(GuardedValueTransformer<TVal> transformer)
{
return (t, v) =>
{
if (!typeof(TVal).IsAssignableFrom(t))
{
return null;
}
return transformer((TVal) v);
return transformer((TVal)v);
};
}
public static void RegisterFilter<TVal>(GuardedValueTransformer<TVal> filter)
{
PropertyTransformers.Add(Guard<TVal>(filter));
}

private DataTablesData GetResults(IQueryable<T> data, DataTablesParam param, Tuple<string, string, Type>[] searchColumns)
{

int totalRecords = data.Count(); //annoying this, as it causes an extra evaluation..

var filters = new DataTablesFilter();


var filteredData = data.Select(_transform).AsQueryable();
filteredData = filters.FilterPagingSortingSearch(param, filteredData, searchColumns).Cast<TRes>();

Expand All @@ -102,13 +103,15 @@ private DataTablesData GetResults(IQueryable<T> data, DataTablesParam param, Tup
page = page.Take(param.iDisplayLength);
}

var type = typeof(TRes);
var properties = type.GetProperties();
//var type = typeof(TRes);
//var propertiesOriginal = type.GetProperties();

var properties = TypeExtensions.GetSortedProperties<TRes>();

var transformedPage = from i in page
let pairs = properties.Select(p => new {p.PropertyType, Value = (p.GetGetMethod().Invoke(i, null))})
let values = pairs.Select(p => GetTransformedValue(p.PropertyType, p.Value))
select values;
let pairs = properties.Select(p => new { p.PropertyType, Value = (p.GetGetMethod().Invoke(i, null)) })
let values = pairs.Select(p => GetTransformedValue(p.PropertyType, p.Value))
select values;

var result = new DataTablesData
{
Expand Down
2 changes: 2 additions & 0 deletions Mvc.JQuery.Datatables/Mvc.JQuery.Datatables.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
Expand All @@ -59,6 +60,7 @@
<Compile Include="DynamicLinq\DynamicLinq.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="StaticReflectionHelper.cs" />
<Compile Include="TypeExtensions.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="..\Mvc.JQuery.Datatables.Templates\Views\Shared\DataTable.cshtml">
Expand Down
22 changes: 22 additions & 0 deletions Mvc.JQuery.Datatables/TypeExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;

public static class TypeExtensions
{
public static IEnumerable<PropertyInfo> GetSortedProperties(this Type t)
{
return from pi in t.GetProperties()
let da = (DisplayAttribute)pi.GetCustomAttributes(typeof(DisplayAttribute), false).SingleOrDefault()
let order = ((da != null && da.Order != 0) ? da.Order : int.MaxValue)
orderby order
select pi;
}

public static IEnumerable<PropertyInfo> GetSortedProperties<T>()
{
return TypeExtensions.GetSortedProperties(typeof(T));
}
}