It sounds like a simple question, but I've been strugling with it this entire afternoon. I'm trying to put a grid in a PartialView with pagination, sorting and everything. My first problem was the pager links: they did not hold my filter options, since it was not on the pages query string. That's how I solved it:
public class PaginationContainer
{
public IPagination PaginatedResult { get; set; }
public RouteValueDictionary RouteValueDictionary { get; set; }
}
I created this class, which is then used by my pager:
@using MvcContrib.UI.Pager
@model AqxWeb.Models.PaginationContainer
@{
string action = ViewContext.Controller.ValueProvider.GetValue("action").RawValue.ToString();
string controller = ViewContext.Controller.ValueProvider.GetValue("controller").RawValue.ToString();
}
@functions
{
public RouteValueDictionary GetRoute(int page)
{
var routeValues = new RouteValueDictionary();
foreach (string key in Model.RouteValueDictionary.Keys)
{
routeValues[key] = Model.RouteValueDictionary[key];
}
routeValues["page"] = page;
return routeValues;
}
}
<p />
<div class='pagination'>
<span class='paginationLeft'>Mostrando @Model.PaginatedResult.FirstItem - @Model.PaginatedResult.LastItem
de @Model.PaginatedResult.TotalItems</span> <span class='paginationRight'>
@{
if (Model.PaginatedResult.HasPreviousPage)
{<text> @Html.ActionLink("Primeira", action, controller, GetRoute(1), new Dictionary<string, object> { { "class", "paging" } })
| </text>}
else
{<text> Primeira | </text>}
if (Model.PaginatedResult.HasPreviousPage)
{<text>@Html.ActionLink("Anterior", action, controller, GetRoute(Model.PaginatedResult.PageNumber - 1), new Dictionary<string, object> { { "class", "paging" } })
| </text>}
else
{<text>Anterior | </text>}
if (Model.PaginatedResult.HasNextPage)
{<text>@Html.ActionLink("Próxima", action, controller, GetRoute(Model.PaginatedResult.PageNumber + 1), new Dictionary<string, object> { { "class", "paging" } })
| </text>}
else
{<text>Próxima | </text>}
if (Model.PaginatedResult.HasNextPage)
{<text>@Html.ActionLink("Última", action, controller, GetRoute(Model.PaginatedResult.TotalPages), new Dictionary<string, object> { { "class", "paging" } })</text>}
else
{<text>Última</text>}
}
</span>
</div>
All I have to do is to fill this dictionary, something I do on the ActionMethod.
Now I need a similar solution for sorting ... I need to override the table headers created by MVCContrib to add this filter options and to add a class attribute called "paging", which is what I use to make the ajax calls. The only exposed method that could help is .Header(string) for IGridColumn<>, and, honestly, it sucks (I'll have to do so much stuff by hand in order to achieve my goal). So I was trying to create an extension method to cope with this, which proved quite difficult, since the .Header(string) is not exposed:
(Please overlook the bad naming)
public static IGridColumn<T> Ajaxify(this IGridColumn<T> column, string columnName, string className, RouteValueDictionary routeValueDictionary)
{
string newDecoration = "<td> <a href="+GetRoute(routeValueDictionary)+"class=\""+className+"\">"+ columnName + "</a></td>";
return column.Header(newDecoration);
}
I think my intention here is quite clean, but this method wouldn't work, because somehow I can't access the .Header(string) method. Any ideas?