Skip to content

Commit

Permalink
Added Dynamic Sort
Browse files Browse the repository at this point in the history
  • Loading branch information
Mesut Talebi committed Feb 3, 2018
1 parent 387aaed commit 0e221d1
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 90 deletions.
2 changes: 1 addition & 1 deletion mesoft.gridview/Content/gridview/megridview.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
megridview v0.3.3
megridview v0.4.0
Developed By Mesut Talebi (mesut.talebi@yahoo.com)
Open Source And no licence :) free to use
*/
Expand Down
8 changes: 6 additions & 2 deletions mesoft.gridview/HtmlHelpers/GridviewHelper.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using System;
// megridview v0.4.0
// Developed By Mesut Talebi(mesut.talebi @yahoo.com)
// Open Source And no licence :) free to use

using System;
using System.Web.Mvc;

namespace MT.GridView.HtmlHelpers
Expand Down Expand Up @@ -53,7 +57,7 @@ public static MvcHtmlString GridView(this HtmlHelper html, string readUrl, strin
gridviewViewport.AddCssClass("gridview-viewport");
gridviewViewport.Attributes.Add("id", "viewport");
gridviewViewport.Attributes.Add("data-getdata-function", readUrl);
gridviewViewport.InnerHtml+= @"<div class=""gridview-canvas"" style=""min-height:400px;"">
gridviewViewport.InnerHtml+= @"<div class=""gridview-canvas table-responsive"" style=""min-height:400px;"">
</div>
<div class=""loading gridview-loader"">
<img src = ""/images/loading.gif"" />
Expand Down
2 changes: 1 addition & 1 deletion mesoft.gridview/Models/CustomersViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace MT.GridView.Models
{
public class CustomersViewModel
{
public IQueryable<Customer> Customers { get; set; }
public IEnumerable<Customer> Customers { get; set; }

public string JsonPagingInfo { get; set; }
}
Expand Down
52 changes: 12 additions & 40 deletions mesoft.gridview/Models/GridViewModelProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,19 @@ internal static CustomersViewModel GetCustomersViewModel(MyDbContext db, PagingI
return model;
}

private static IQueryable<Customer> GetData(IQueryable<Customer> Customers, PagingInfo PagingData, out int TotalItems)
private static IEnumerable<Customer> GetData(IQueryable<Customer> customers, PagingInfo pagingData, out int totalItems)
{
var customers = Customers;

//search
if (!string.IsNullOrEmpty(PagingData.SearchTerm))
if (!string.IsNullOrEmpty(pagingData.SearchTerm))
{
customers = customers.Where(x => (x.CompanyName.Contains(PagingData.SearchTerm) || x.ContactTitle.Contains(PagingData.SearchTerm)));
customers = customers.Where(x => (x.CompanyName.Contains(pagingData.SearchTerm)
|| x.ContactTitle.Contains(pagingData.SearchTerm)));
}

//filter
if (PagingData.Filters != null)
if (pagingData.Filters != null)
{
foreach (var filterObj in PagingData.Filters)
foreach (var filterObj in pagingData.Filters)
{
switch (filterObj.Column)
{
Expand All @@ -61,44 +60,17 @@ private static IQueryable<Customer> GetData(IQueryable<Customer> Customers, Pagi
}
}


TotalItems = customers.Count();
totalItems = customers.Count();

//sort
customers = customers.OrderBy(x => x.Id);
if (PagingData.Sort != null)
{
switch (PagingData.Sort.Direction)
{
case SortDirection.Ascending:
if (PagingData.Sort.SortColumn == "CompanyName")
{
customers = customers.OrderBy(x => x.CompanyName);
}
else if (PagingData.Sort.SortColumn == "ContactTitle")
{
customers = customers.OrderBy(x => x.ContactTitle);
}
break;
case SortDirection.Descending:
if (PagingData.Sort.SortColumn == "CompanyName")
{
customers = customers.OrderByDescending(x => x.CompanyName);
}
else if (PagingData.Sort.SortColumn == "ContactTitle")
{
customers = customers.OrderByDescending(x => x.ContactTitle);
}
break;
case SortDirection.NotSet:
default:
break;
}
}

customers = customers.Sort(pagingData.Sort);

customers = customers
.Skip((PagingData.CurrentPage - 1) * PagingData.ItemsPerPage).Take(PagingData.ItemsPerPage);
.Skip((pagingData.CurrentPage - 1) * pagingData.ItemsPerPage).Take(pagingData.ItemsPerPage);

return customers;
return customers.ToList();
}
}
}
139 changes: 119 additions & 20 deletions mesoft.gridview/Models/GridviewModel.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
/*
megridview v0.3.1
megridview v0.4.0
Developed By Mesut Talebi (mesut.talebi@yahoo.com)
Open Source And no licence :) free to use
*/


using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

namespace MT.GridView.Models
{
Expand All @@ -22,7 +25,7 @@ public class PagingInfo

public int TotalPages
{
get { return (int)Math.Ceiling((decimal)TotalItems / (ItemsPerPage != 0 ? ItemsPerPage : 1)); }
get { return (int)Math.Ceiling((decimal)TotalItems / ( ItemsPerPage != 0 ? ItemsPerPage : 1 )); }
}

public SortObject Sort { get; set; }
Expand All @@ -41,7 +44,7 @@ public class SortObject

public class FilterObject
{
public string Column { get; set; }
public string Column { get; set; }

public string Value { get; set; }

Expand Down Expand Up @@ -78,60 +81,156 @@ public enum FilterConjunction
Or
}

public class Extensions
public static class Extensions
{
private static LambdaExpression GetExpression<T>(string propertyName, string methodName, out Type type)
{
string[] props = propertyName.Split('.');
type = typeof(T);

ParameterExpression arg = Expression.Parameter(type, "x");
Expression expr = arg;

foreach (string prop in props)
{
// use reflection (not ComponentModel) to mirror LINQ
PropertyInfo pi = type.GetProperty(prop);
expr = Expression.Property(expr, pi);
type = pi.PropertyType;
}

Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), type);

return Expression.Lambda(delegateType, expr, arg);
}

private static IOrderedEnumerable<T> ApplyOrder<T>(
IEnumerable<T> source,
string propertyName,
string methodName)
{
Type type = typeof(T);
LambdaExpression lambda = GetExpression<T>(propertyName, methodName, out type);

object result = typeof(Queryable).GetMethods().Single(
method => method.Name == methodName
&& method.IsGenericMethodDefinition
&& method.GetGenericArguments().Length == 2
&& method.GetParameters().Length == 2)
.MakeGenericMethod(typeof(T), type)
.Invoke(null, new object[] { source, lambda });

return (IOrderedEnumerable<T>)result;
}


private static IOrderedQueryable<T> ApplyOrder<T>(
IQueryable<T> source,
string propertyName, string methodName)
{
Type type = typeof(T);
LambdaExpression lambda = GetExpression<T>(propertyName, methodName, out type);

object result = typeof(Queryable).GetMethods().Single(
method => method.Name == methodName
&& method.IsGenericMethodDefinition
&& method.GetGenericArguments().Length == 2
&& method.GetParameters().Length == 2)
.MakeGenericMethod(typeof(T), type)
.Invoke(null, new object[] { source, lambda });

return (IOrderedQueryable<T>)result;
}

// IQueryable Sort Extention
public static IOrderedQueryable<TSource> Sort<TSource>(this IQueryable<TSource> source, SortObject sortObject)
{
if (sortObject != null)
{
switch (sortObject.Direction)
{
case SortDirection.Ascending:
return ApplyOrder<TSource>(source, sortObject.SortColumn, "OrderBy");
case SortDirection.Descending:
return ApplyOrder<TSource>(source, sortObject.SortColumn, "OrderByDescending");
default:
break;
}
}

return source as IOrderedQueryable<TSource>;
}

public static IOrderedEnumerable<TSource> Sort<TSource>(this IEnumerable<TSource> source, SortObject sortObject)
{
if (sortObject != null)
{
switch (sortObject.Direction)
{
case SortDirection.Ascending:
return ApplyOrder<TSource>(source, sortObject.SortColumn, "OrderBy");
case SortDirection.Descending:
return ApplyOrder<TSource>(source, sortObject.SortColumn, "OrderByDescending");
default:
break;
}
}

return source as IOrderedEnumerable<TSource>;
}

public static string GetWhereClause(FilterObject filterObj, Type valueType)
{
{
string whereClause = "true";
if (valueType != typeof (DateTime))
if (valueType != typeof(DateTime))
{
switch (filterObj.Operator)
{
case FilterOperator.Contains:
if (valueType == typeof (string))
if (valueType == typeof(string))
whereClause += string.Format(" {0} {1}.Contains(\"{2}\")", filterObj.Conjunction,
filterObj.Column, filterObj.Value);
break;
case FilterOperator.GreaterThan:
if (valueType != typeof (string))
if (valueType != typeof(string))
whereClause += string.Format(" {0} {1} > {2}", filterObj.Conjunction, filterObj.Column,
filterObj.Value);
break;
case FilterOperator.GreaterThanOrEqual:
if (valueType != typeof (string))
if (valueType != typeof(string))
whereClause += string.Format(" {0} {1} >= {2}", filterObj.Conjunction, filterObj.Column,
filterObj.Value);
break;
case FilterOperator.LessThan:
if (valueType != typeof (string))
if (valueType != typeof(string))
whereClause += string.Format(" {0} {1} < {2}", filterObj.Conjunction, filterObj.Column,
filterObj.Value);
break;
case FilterOperator.LessThanOrEqual:
if (valueType != typeof (string))
if (valueType != typeof(string))
whereClause += string.Format(" {0} {1} <= {2}", filterObj.Conjunction, filterObj.Column,
filterObj.Value);
break;
case FilterOperator.StartsWith:
if (valueType != typeof (string))
if (valueType != typeof(string))
whereClause += string.Format(" {0} {1}.StartsWith(\"{2}\")", filterObj.Conjunction,
filterObj.Column, filterObj.Value);
break;
case FilterOperator.EndsWith:
if (valueType != typeof (string))
if (valueType != typeof(string))
whereClause += string.Format(" {0} {1}.EndsWith(\"{2}\")", filterObj.Conjunction,
filterObj.Column, filterObj.Value);
break;
case FilterOperator.Equals:

whereClause +=
string.Format(valueType == typeof (string) ? " {0} {1} == \"{2}\"" : " {0} {1} == {2}",
string.Format(valueType == typeof(string) ? " {0} {1} == \"{2}\"" : " {0} {1} == {2}",
filterObj.Conjunction, filterObj.Column, filterObj.Value);
break;
case FilterOperator.NotEqual:

whereClause +=
string.Format(valueType == typeof (string) ? " {0} {1} != \"{2}\"" : " {0} {1} != {2}",
string.Format(valueType == typeof(string) ? " {0} {1} != \"{2}\"" : " {0} {1} != {2}",
filterObj.Conjunction, filterObj.Column, filterObj.Value);
break;
default:
Expand All @@ -145,11 +244,11 @@ public static string GetWhereClause(FilterObject filterObj, Type valueType)

switch (filterObj.Operator)
{
case FilterOperator.Contains:
case FilterOperator.Contains:
break;
case FilterOperator.GreaterThan:
whereClause += string.Format(" {0} {1} > DateTime(\"{2}\")", filterObj.Conjunction, filterObj.Column, dt);

whereClause += string.Format(" {0} {1} > DateTime(\"{2}\")", filterObj.Conjunction, filterObj.Column, dt);
break;
case FilterOperator.GreaterThanOrEqual:

Expand All @@ -162,9 +261,9 @@ public static string GetWhereClause(FilterObject filterObj, Type valueType)
case FilterOperator.LessThanOrEqual:
whereClause += string.Format(" {0} {1} <= DateTime(\"{2}\")", filterObj.Conjunction, filterObj.Column, dt);
break;
case FilterOperator.StartsWith:
case FilterOperator.StartsWith:
break;
case FilterOperator.EndsWith:
case FilterOperator.EndsWith:
break;
case FilterOperator.Equals:
whereClause += string.Format(" {0} {1} == DateTime(\"{2}\")", filterObj.Conjunction, filterObj.Column, dt);
Expand Down
4 changes: 2 additions & 2 deletions mesoft.gridview/Scripts/gridview/megridview.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
megridview v0.3.3
megridview v0.4.0
Developed By Mesut Talebi (mesut.talebi@yahoo.com)
Open Source And no licence :) free to use
*/
Expand Down Expand Up @@ -348,7 +348,7 @@
$('th.sortable > span', obj).removeClass('fa-chevron-up').removeClass('fa-chevron-down');

//find sorted column
var sortableTh = $('th.sortable[data-sort=' + $gridviewObject.Sort.SortColumn + ']', obj);
var sortableTh = $('th.sortable[data-sort="' + $gridviewObject.Sort.SortColumn + '"]', obj);
console.log(sortableTh);

$(sortableTh).addClass('sorted');
Expand Down
32 changes: 8 additions & 24 deletions mesoft.gridview/Views/Home/_CustomersPartial.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,14 @@
<table class="table table-bordered table-striped">
<thead>
<tr class="gridview-list-header">
<th>
@(Html.DisplayNameFor(x => x.Customers.FirstOrDefault().Id))
</th>
<th class="sortable" data-sort="CompanyName">
@(Html.DisplayNameFor(x => x.Customers.FirstOrDefault().CompanyName))
</th>
<th class="sortable" data-sort="ContactTitle">
@(Html.DisplayNameFor(x => x.Customers.FirstOrDefault().ContactTitle))
</th>
<th>
@(Html.DisplayNameFor(x => x.Customers.FirstOrDefault().Country))
</th>
<th>
@(Html.DisplayNameFor(x => x.Customers.FirstOrDefault().City))
</th>
<th>
@(Html.DisplayNameFor(x => x.Customers.FirstOrDefault().Address))
</th>
<th>
@(Html.DisplayNameFor(x => x.Customers.FirstOrDefault().Phone))
</th>
<th>
@Html.DisplayNameFor(x=> x.Customers.FirstOrDefault().Founded)
</th>
<th>@(Html.DisplayNameFor(x => x.Customers.FirstOrDefault().Id))</th>
<th class="sortable" data-sort="CompanyName">@(Html.DisplayNameFor(x => x.Customers.FirstOrDefault().CompanyName))</th>
<th class="sortable" data-sort="ContactTitle">@(Html.DisplayNameFor(x => x.Customers.FirstOrDefault().ContactTitle))</th>
<th class="sortable" data-sort="Country">@(Html.DisplayNameFor(x => x.Customers.FirstOrDefault().Country))</th>
<th class="sortable" data-sort="City">@(Html.DisplayNameFor(x => x.Customers.FirstOrDefault().City))</th>
<th>@(Html.DisplayNameFor(x => x.Customers.FirstOrDefault().Address))</th>
<th>@(Html.DisplayNameFor(x => x.Customers.FirstOrDefault().Phone))</th>
<th class="sortable" data-sort="Founded">@Html.DisplayNameFor(x=> x.Customers.FirstOrDefault().Founded)</th>
</tr>
</thead>

Expand Down

0 comments on commit 0e221d1

Please sign in to comment.