Skip to content

Commit ee32e10

Browse files
committed
added sorteable aware action link
1 parent 7328db0 commit ee32e10

File tree

11 files changed

+194
-20
lines changed

11 files changed

+194
-20
lines changed

BookCollection/BookCollection.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@
212212
</Compile>
213213
<Compile Include="Helpers\BC.cs" />
214214
<Compile Include="Helpers\Converters.cs" />
215+
<Compile Include="Helpers\CustomHtmlHelper.cs" />
216+
<Compile Include="Helpers\CustomWebViewPage.cs" />
215217
<Compile Include="Helpers\DownloadFileActionResult.cs" />
216218
<Compile Include="Helpers\ImageResult.cs" />
217219
<Compile Include="Helpers\ImageUpload.cs" />

BookCollection/Controllers/BooksController.cs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,26 @@ public ActionResult Index(string sortOrder, string currentFilter, string bookCat
3333
ViewBag.CategorySortParm = String.IsNullOrEmpty(sortOrder) ? "category_desc" : "category";
3434
ViewBag.SerieSortParm = String.IsNullOrEmpty(sortOrder) ? "serie_desc" : "serie";
3535

36+
if (!String.IsNullOrEmpty(sortOrder) && sortOrder.Contains("_"))
37+
{
38+
string[] sort = sortOrder.ToLowerInvariant().Split(new [] { '_' });
39+
40+
if (sort[0].Equals("name")) {
41+
ViewBag.NameSortParm = sort[1].Equals("desc") ? "name_desc" : "name_asc";
42+
}
43+
/*
44+
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "name_asc";
45+
ViewBag.AuthorSortParm = String.IsNullOrEmpty(sortOrder) ? "author_desc" : "author";
46+
ViewBag.PublisherSortParm = String.IsNullOrEmpty(sortOrder) ? "publisher_desc" : "publisher";
47+
ViewBag.YearSortParm = String.IsNullOrEmpty(sortOrder) ? "year_desc" : "year";
48+
ViewBag.CategorySortParm = String.IsNullOrEmpty(sortOrder) ? "category_desc" : "category";
49+
ViewBag.SerieSortParm = String.IsNullOrEmpty(sortOrder) ? "serie_desc" : "serie";
50+
*/
51+
52+
}
53+
/*
54+
55+
*/
3656

3757

3858
if (searchString != null)
@@ -67,25 +87,25 @@ public ActionResult Index(string sortOrder, string currentFilter, string bookCat
6787
case "name_desc":
6888
books = books.OrderByDescending(s => s.Title);
6989
break;
70-
case "publisher":
90+
case "publisher_asc":
7191
books = books.OrderBy(s => s.Publisher.Name);
7292
break;
7393
case "publisher_desc":
7494
books = books.OrderByDescending(s => s.Publisher.Name);
7595
break;
76-
case "category":
96+
case "category_asc":
7797
books = books.OrderBy(s => s.Category.Title);
7898
break;
7999
case "category_desc":
80100
books = books.OrderByDescending(s => s.Category.Title);
81101
break;
82-
case "year":
102+
case "year_asc":
83103
books = books.OrderBy(s => s.ActualPrintYear);
84104
break;
85105
case "year_desc":
86106
books = books.OrderByDescending(s => s.ActualPrintYear);
87107
break;
88-
case "serie":
108+
case "serie_asc":
89109
books = books.OrderBy(s => s.Serie);
90110
break;
91111
case "serie_desc":

BookCollection/Helpers/BC.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ namespace BookCollection.Helpers
99
{
1010
public static class BC
1111
{
12+
private const string spanTemplate = "<span class=\"glyphicon glyphicon-{0}\" aria-hidden=\"true\"></span>";
13+
1214
public static MvcHtmlString BoolIcon(bool target, string toolTipTrue = "", string toolTipFalse = "")
1315
{
1416
string spanTemplate = "<span class=\"glyphicon glyphicon-{0}\" aria-hidden=\"true\" {1}></span>";
@@ -42,7 +44,7 @@ public static MvcHtmlString IconButton(string controller, string action, string
4244
//<a href="@Url.Action("Edit", new { id = item.BookID })" class="btn btn-primary btn-xs">
4345
//<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit</a>
4446

45-
string spanTemplate = "<span class=\"glyphicon glyphicon-{0}\" aria-hidden=\"true\"></span>";
47+
4648
string iconHtml = string.IsNullOrEmpty(iconname) ? "" : string.Format(spanTemplate, iconname);
4749

4850
var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Web;
5+
using System.Web.Mvc;
6+
using System.Web.Routing;
7+
8+
namespace BookCollection.Helpers
9+
{
10+
//http://stackoverflow.com/questions/15952240/how-do-you-override-html-actionlink
11+
12+
public class CustomHtmlHelper<T> : HtmlHelper<T>
13+
{
14+
public CustomHtmlHelper(ViewContext viewContext, IViewDataContainer viewDataContainer) :
15+
base(viewContext, viewDataContainer)
16+
{
17+
}
18+
19+
//Instance methods will always be called instead of extension methods when both exist with the same signature...
20+
21+
public MvcHtmlString ActionLink(string linkText, string actionName)
22+
{
23+
return ActionLink(linkText, actionName, null, new RouteValueDictionary(), new RouteValueDictionary());
24+
}
25+
26+
public MvcHtmlString ActionLink(string linkText, string actionName, object routeValues)
27+
{
28+
return ActionLink(linkText, actionName, null, new RouteValueDictionary(routeValues), new RouteValueDictionary());
29+
}
30+
31+
public MvcHtmlString ActionLink(string linkText, string actionName, string controllerName)
32+
{
33+
return ActionLink(linkText, actionName, controllerName, new RouteValueDictionary(), new RouteValueDictionary());
34+
}
35+
36+
public MvcHtmlString ActionLink(string linkText, string actionName, RouteValueDictionary routeValues)
37+
{
38+
return ActionLink(linkText, actionName, null, routeValues, new RouteValueDictionary());
39+
}
40+
41+
public MvcHtmlString ActionLink(string linkText, string actionName, object routeValues, object htmlAttributes)
42+
{
43+
return ActionLink(linkText, actionName, null, new RouteValueDictionary(routeValues), AnonymousObjectToHtmlAttributes(htmlAttributes));
44+
}
45+
46+
public MvcHtmlString ActionLink(string linkText, string actionName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes)
47+
{
48+
return ActionLink(linkText, actionName, null, routeValues, htmlAttributes);
49+
}
50+
51+
public MvcHtmlString ActionLink(string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes)
52+
{
53+
return ActionLink(linkText, actionName, controllerName, new RouteValueDictionary(routeValues), AnonymousObjectToHtmlAttributes(htmlAttributes));
54+
}
55+
56+
public MvcHtmlString ActionLink(string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes)
57+
{
58+
string sortIconHtml = "";
59+
routeValues = SetSortParam(routeValues, out sortIconHtml);
60+
string link = GenerateLink(ViewContext.RequestContext, RouteCollection, linkText, null, actionName, controllerName, routeValues, htmlAttributes);
61+
62+
return MvcHtmlString.Create(sortIconHtml + link);
63+
}
64+
65+
public MvcHtmlString ActionLink(string linkText, string actionName, string controllerName, string protocol, string hostName, string fragment, object routeValues, object htmlAttributes)
66+
{
67+
return ActionLink(linkText, actionName, controllerName, protocol, hostName, fragment, new RouteValueDictionary(routeValues), AnonymousObjectToHtmlAttributes(htmlAttributes));
68+
}
69+
70+
public MvcHtmlString ActionLink(string linkText, string actionName, string controllerName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes)
71+
{
72+
string sortIconHtml = "";
73+
routeValues = SetSortParam(routeValues, out sortIconHtml);
74+
string link = GenerateLink(ViewContext.RequestContext, RouteCollection, linkText, null, actionName, controllerName, protocol, hostName, fragment, routeValues, htmlAttributes);
75+
76+
return MvcHtmlString.Create(sortIconHtml + link);
77+
}
78+
79+
private const string spanTemplate = "<span class=\"glyphicon glyphicon-{0}\" aria-hidden=\"true\"></span>";
80+
public RouteValueDictionary SetSortParam(RouteValueDictionary rvd, out string sortPrefix)
81+
{
82+
sortPrefix = "";
83+
// Is sortable link?
84+
if (rvd != null && rvd.Keys.Contains("sortKey") && !string.IsNullOrWhiteSpace(rvd["sortKey"] as string) )
85+
{
86+
// prevent double keys
87+
if (rvd.ContainsKey("sortOrder"))
88+
{
89+
rvd.Remove("sortOrder");
90+
}
91+
92+
string sortKey = rvd["sortKey"] as string;
93+
// Has user specified a sort?
94+
if (rvd.Keys.Contains("currentSort") && !string.IsNullOrWhiteSpace(rvd["currentSort"] as string))
95+
{
96+
string[] currentSort = (rvd["currentSort"] as string).Split(new[] { '_' });
97+
if (currentSort.Length == 2)
98+
{
99+
// Is specified current sort matching the sort key for this link?
100+
if (sortKey.Equals(currentSort[0], StringComparison.InvariantCultureIgnoreCase))
101+
{
102+
103+
if (currentSort[1].Equals("desc", StringComparison.InvariantCultureIgnoreCase))
104+
{
105+
// set new sort direction and display icon ascending
106+
sortPrefix = string.Format(spanTemplate, "sort-by-attributes-alt");
107+
rvd.Add("sortOrder", sortKey + "_asc");
108+
}
109+
else
110+
{
111+
// set new sort direction and display icon descending
112+
sortPrefix = string.Format(spanTemplate, "sort-by-attributes");
113+
rvd.Add("sortOrder", sortKey + "_desc");
114+
}
115+
}
116+
else
117+
{
118+
rvd.Add("sortOrder", sortKey + "_asc");
119+
}
120+
}
121+
}
122+
else
123+
{
124+
// No used sort, set default first sort for this sort key
125+
rvd.Add("sortOrder", sortKey + "_asc");
126+
}
127+
}
128+
return rvd;
129+
}
130+
}
131+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Web;
5+
using System.Web.Mvc;
6+
7+
namespace BookCollection.Helpers
8+
{
9+
public abstract class CustomWebViewPage<T> : WebViewPage<T>
10+
{
11+
public new CustomHtmlHelper<T> Html { get; set; }
12+
13+
public override void InitHelpers()
14+
{
15+
Ajax = new AjaxHelper<T>(ViewContext, this);
16+
Url = new UrlHelper(ViewContext.RequestContext);
17+
18+
//Load Custom Html Helper instead of Default
19+
Html = new CustomHtmlHelper<T>(ViewContext, this);
20+
}
21+
}
22+
}

BookCollection/Views/Authors/Index.cshtml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
<table class="table table-hover">
2828
<tr>
2929
<th>
30-
@Html.ActionLink("Last name", "Index", new { sortOrder = ViewBag.NameSortParm, currentFilter = ViewBag.CurrentFilter })
30+
@Html.ActionLink("Last name", "Index", new { sortOrder = ViewBag.NameSortParm, currentFilter = ViewBag.CurrentFilter, currentSort = ViewBag.CurrentSort })
3131
</th>
3232
<th>
3333
First name
@@ -56,4 +56,4 @@
5656
Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount
5757

5858
@Html.PagedListPager(Model, page => Url.Action("Index",
59-
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
59+
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter, currentSort = ViewBag.CurrentSort }))

BookCollection/Views/Books/Index.cshtml

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,25 +31,22 @@
3131
<th>
3232
</th>
3333
<th>
34-
@Html.ActionLink("Title", "Index", new { sortOrder = ViewBag.NameSortParm, currentFilter = ViewBag.CurrentFilter })
35-
36-
37-
<span class="glyphicon glyphicon-sort-by-alphabet" aria-hidden="true"></span>
34+
@Html.ActionLink("Title", "Index", new { sortKey = "name", currentFilter = ViewBag.CurrentFilter, currentSort = ViewBag.CurrentSort })
3835
</th>
3936
<th>
40-
@Html.ActionLink("Author", "Index", new { sortOrder = ViewBag.AuthorSortParm, currentFilter = ViewBag.CurrentFilter })
37+
@Html.ActionLink("Author", "Index", new { sortOrder = ViewBag.AuthorSortParm, currentFilter = ViewBag.CurrentFilter, currentSort = ViewBag.CurrentSort })
4138
</th>
4239
<th>
43-
@Html.ActionLink("Publisher", "Index", new { sortOrder = ViewBag.PublisherSortParm, currentFilter = ViewBag.CurrentFilter })
40+
@Html.ActionLink("Publisher", "Index", new { sortOrder = ViewBag.PublisherSortParm, currentFilter = ViewBag.CurrentFilter, currentSort = ViewBag.CurrentSort })
4441
</th>
4542
<th>
46-
@Html.ActionLink("Year", "Index", new { sortOrder = ViewBag.YearSortParm, currentFilter = ViewBag.CurrentFilter })
43+
@Html.ActionLink("Year", "Index", new { sortOrder = ViewBag.YearSortParm, currentFilter = ViewBag.CurrentFilter, currentSort = ViewBag.CurrentSort })
4744
</th>
4845
<th>
49-
@Html.ActionLink("Category", "Index", new { sortOrder = ViewBag.CategorySortParm, currentFilter = ViewBag.CurrentFilter })
46+
@Html.ActionLink("Category", "Index", new { sortOrder = ViewBag.CategorySortParm, currentFilter = ViewBag.CurrentFilter, currentSort = ViewBag.CurrentSort })
5047
</th>
5148
<th>
52-
@Html.ActionLink("Serie", "Index", new { sortOrder = ViewBag.SerieSortParm, currentFilter = ViewBag.CurrentFilter })
49+
@Html.ActionLink("Serie", "Index", new { sortOrder = ViewBag.SerieSortParm, currentFilter = ViewBag.CurrentFilter, currentSort = ViewBag.CurrentSort })
5350
</th>
5451
<th></th>
5552
</tr>

BookCollection/Views/Categories/Index.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@
3939
Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount
4040

4141
@Html.PagedListPager(Model, page => Url.Action("Index",
42-
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
42+
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter, currentSort = ViewBag.CurrentSort }))

BookCollection/Views/Publishers/Index.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@
3939
Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount
4040

4141
@Html.PagedListPager(Model, page => Url.Action("Index",
42-
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
42+
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter, currentSort = ViewBag.CurrentSort }))

BookCollection/Views/Subjects/Index.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@
4040
Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount
4141

4242
@Html.PagedListPager(Model, page => Url.Action("Index",
43-
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
43+
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter, currentSort = ViewBag.CurrentSort }))

0 commit comments

Comments
 (0)