PageRenderTime 61ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/src/MVCContrib/UI/LegacyGrid/Grid.cs

https://github.com/dalager/MvcContrib
C# | 359 lines | 256 code | 59 blank | 44 comment | 33 complexity | fdfe039002d6c176b12f10243cb9c7d9 MD5 | raw file
  1. using System.Collections.Specialized;
  2. using System.Linq;
  3. using System.Web.Mvc;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using System.IO;
  7. using System.Text;
  8. using System.Web;
  9. using MvcContrib.Pagination;
  10. namespace MvcContrib.UI.LegacyGrid
  11. {
  12. /// <summary>
  13. /// Implementation of the grid for rendering HTML in a gridview style.
  14. /// </summary>
  15. /// <typeparam name="T">Type of object to be rendered in each row.</typeparam>
  16. [System.Obsolete("The old version of the grid has been deprecated. Please switch to the version located in MvcContrib.UI.Grid")]
  17. public class Grid<T> : GridBase<T> where T : class
  18. {
  19. private const string Default_Css_Class = "grid";
  20. private const string Empty_Text_Key = "empty";
  21. private const string Pagination_Format_Text_Key = "paginationFormat";
  22. private const string Page_Query_Name_Text_Key = "page";
  23. private const string Pagination_Single_Format_Text_Key = "paginationSingleFormat";
  24. private const string Pagination_First_Text_Key = "first";
  25. private const string Pagination_Prev_Text_Key = "prev";
  26. private const string Pagination_Next_Text_Key = "next";
  27. private const string Pagination_Last_Text_Key = "last";
  28. private string _paginationFormat = "Showing {0} - {1} of {2} ";
  29. private string _paginationSingleFormat = "Showing {0} of {1} ";
  30. private string _paginationFirst = "first";
  31. private string _paginationPrev = "prev";
  32. private string _paginationNext = "next";
  33. private string _paginationLast = "last";
  34. private string _pageQueryName = "page";
  35. /// <summary>
  36. /// Custom HTML attributes.
  37. /// </summary>
  38. public IDictionary HtmlAttributes { get; private set; }
  39. /// <summary>
  40. /// The HTTP Context.
  41. /// </summary>
  42. public HttpContextBase Context { get; set; }
  43. /// <summary>
  44. /// Creates a new instance of the <see cref="Grid{T}"/> class using the specified viewDataKey to extract the data source from the viewdata.
  45. /// </summary>
  46. /// <param name="viewDataKey">Key to use to extract the </param>
  47. /// <param name="viewContext">The view context</param>
  48. /// <param name="columns">Columns</param>
  49. /// <param name="htmlAttributes">Custom html attributes and options</param>
  50. /// <param name="writer">Where to write the output</param>
  51. public Grid(string viewDataKey, ViewContext viewContext, GridColumnBuilder<T> columns, IDictionary htmlAttributes, TextWriter writer)
  52. : this(GetDataSourceFromViewData(viewDataKey, viewContext), columns, htmlAttributes, writer, viewContext.HttpContext)
  53. {
  54. }
  55. protected static IEnumerable<T> GetDataSourceFromViewData(string key, ViewContext context)
  56. {
  57. object items = key == null ? null : context.ViewData.Eval(key);
  58. IEnumerable<T> collection = null;
  59. if (items != null)
  60. {
  61. //First try as IEnumerable of T
  62. collection = items as IEnumerable<T>;
  63. //Otherwise try IEnumerable with a cast.
  64. //TODO: error handling?
  65. if (collection == null)
  66. {
  67. collection = (items as IEnumerable).Cast<T>();
  68. }
  69. }
  70. return collection;
  71. }
  72. /// <summary>
  73. /// Creates a new instance of the <see cref="Grid{T}"/> using the specified data source.
  74. /// </summary>
  75. /// <param name="items">Data source</param>
  76. /// <param name="columns">Columns</param>
  77. /// <param name="htmlAttributes">Custom attributes and options</param>
  78. /// <param name="writer">Where to write the output</param>
  79. /// <param name="context">HTTP Context</param>
  80. public Grid(IEnumerable<T> items, GridColumnBuilder<T> columns, IDictionary htmlAttributes, TextWriter writer, HttpContextBase context)
  81. : base(items, columns, writer)
  82. {
  83. Context = context;
  84. HtmlAttributes = htmlAttributes ?? Hash.Empty;
  85. if (!HtmlAttributes.Contains("class"))
  86. {
  87. HtmlAttributes["class"] = Default_Css_Class;
  88. }
  89. if (HtmlAttributes.Contains(Empty_Text_Key))
  90. {
  91. EmptyMessageText = HtmlAttributes[Empty_Text_Key] as string;
  92. HtmlAttributes.Remove(Empty_Text_Key);
  93. }
  94. if (HtmlAttributes.Contains(Pagination_Format_Text_Key))
  95. {
  96. _paginationFormat = HtmlAttributes[Pagination_Format_Text_Key] as string;
  97. HtmlAttributes.Remove(Pagination_Format_Text_Key);
  98. }
  99. if (HtmlAttributes.Contains(Pagination_Single_Format_Text_Key))
  100. {
  101. _paginationSingleFormat = HtmlAttributes[Pagination_Single_Format_Text_Key] as string;
  102. HtmlAttributes.Remove(Pagination_Single_Format_Text_Key);
  103. }
  104. if (HtmlAttributes.Contains(Pagination_First_Text_Key))
  105. {
  106. _paginationFirst = HtmlAttributes[Pagination_First_Text_Key] as string;
  107. HtmlAttributes.Remove(Pagination_First_Text_Key);
  108. }
  109. if (HtmlAttributes.Contains(Pagination_Prev_Text_Key))
  110. {
  111. _paginationPrev = HtmlAttributes[Pagination_Prev_Text_Key] as string;
  112. HtmlAttributes.Remove(Pagination_Prev_Text_Key);
  113. }
  114. if (HtmlAttributes.Contains(Pagination_Next_Text_Key))
  115. {
  116. _paginationNext = HtmlAttributes[Pagination_Next_Text_Key] as string;
  117. HtmlAttributes.Remove(Pagination_Next_Text_Key);
  118. }
  119. if (HtmlAttributes.Contains(Pagination_Last_Text_Key))
  120. {
  121. _paginationLast = HtmlAttributes[Pagination_Last_Text_Key] as string;
  122. HtmlAttributes.Remove(Pagination_Last_Text_Key);
  123. }
  124. if (HtmlAttributes.Contains(Page_Query_Name_Text_Key))
  125. {
  126. _pageQueryName = HtmlAttributes[Page_Query_Name_Text_Key] as string;
  127. HtmlAttributes.Remove(Page_Query_Name_Text_Key);
  128. }
  129. }
  130. protected override void RenderHeaderCellEnd()
  131. {
  132. RenderText("</th>");
  133. }
  134. protected override void RenderHeaderCellStart(GridColumn<T> column)
  135. {
  136. string attrs = BuildHtmlAttributes(column.HeaderAttributes);
  137. if (attrs.Length > 0)
  138. attrs = " " + attrs;
  139. RenderText(string.Format("<th{0}>", attrs));
  140. }
  141. protected override void RenderRowStart(bool isAlternate)
  142. {
  143. if(isAlternate)
  144. {
  145. RenderText("<tr class=\"gridrow_alternate\">");
  146. }
  147. else
  148. {
  149. RenderText("<tr class=\"gridrow\">");
  150. }
  151. }
  152. protected override void RenderRowEnd()
  153. {
  154. RenderText("</tr>");
  155. }
  156. protected override void RenderEndCell()
  157. {
  158. RenderText("</td>");
  159. }
  160. protected override void RenderStartCell(GridColumn<T> column)
  161. {
  162. RenderText("<td>");
  163. }
  164. protected override void RenderHeadStart()
  165. {
  166. RenderText("<thead><tr>");
  167. }
  168. protected override void RenderHeadEnd()
  169. {
  170. RenderText("</tr></thead>");
  171. }
  172. protected override void RenderGridStart()
  173. {
  174. string attrs = BuildHtmlAttributes(this.HtmlAttributes);
  175. if (attrs.Length > 0)
  176. attrs = " " + attrs;
  177. RenderText(string.Format("<table{0}>", attrs));
  178. }
  179. protected override void RenderGridEnd(bool isEmpty)
  180. {
  181. RenderText("</table>");
  182. if(!isEmpty)
  183. {
  184. var pagination = Items as IPagination;
  185. if (pagination != null) {
  186. RenderPagination(pagination);
  187. }
  188. }
  189. }
  190. /// <summary>
  191. /// Renders the pagination section of the grid.
  192. /// Eg "Showing 1 - 10 of 20 | last, prev, next, last"
  193. /// </summary>
  194. /// <param name="pagedList"></param>
  195. protected virtual void RenderPagination(IPagination pagedList)
  196. {
  197. var builder = new StringBuilder();
  198. builder.Append("<div class='pagination'>");
  199. builder.Append("<span class='paginationLeft'>");
  200. if (pagedList.PageSize == 1)
  201. {
  202. builder.AppendFormat(_paginationSingleFormat, pagedList.FirstItem, pagedList.TotalItems);
  203. }
  204. else
  205. {
  206. builder.AppendFormat(_paginationFormat, pagedList.FirstItem, pagedList.LastItem, pagedList.TotalItems);
  207. }
  208. builder.Append("</span>");
  209. builder.Append("<span class='paginationRight'>");
  210. if (pagedList.PageNumber == 1)
  211. {
  212. builder.Append(_paginationFirst);
  213. }
  214. else
  215. {
  216. builder.Append(CreatePageLink(1, _paginationFirst));
  217. }
  218. builder.Append(" | ");
  219. if (pagedList.HasPreviousPage)
  220. {
  221. builder.Append(CreatePageLink(pagedList.PageNumber - 1, _paginationPrev));
  222. }
  223. else
  224. {
  225. builder.Append(_paginationPrev);
  226. }
  227. builder.Append(" | ");
  228. if (pagedList.HasNextPage)
  229. {
  230. builder.Append(CreatePageLink(pagedList.PageNumber + 1, _paginationNext));
  231. }
  232. else
  233. {
  234. builder.Append(_paginationNext);
  235. }
  236. builder.Append(" | ");
  237. int lastPage = pagedList.TotalPages;
  238. if (pagedList.PageNumber < lastPage)
  239. {
  240. builder.Append(CreatePageLink(lastPage, _paginationLast));
  241. }
  242. else
  243. {
  244. builder.Append(_paginationLast);
  245. }
  246. builder.Append(@"</span></div>");
  247. RenderText(builder.ToString());
  248. }
  249. /// <summary>
  250. /// Creates a pagination link and includes and curren
  251. /// </summary>
  252. /// <param name="pageNumber"></param>
  253. /// <param name="text"></param>
  254. /// <returns></returns>
  255. protected virtual string CreatePageLink(int pageNumber, string text)
  256. {
  257. string queryString = CreateQueryString(Context.Request.QueryString);
  258. string filePath = Context.Request.FilePath;
  259. return string.Format("<a href=\"{0}?{1}={2}{3}\">{4}</a>", filePath, _pageQueryName, pageNumber, queryString, text);
  260. }
  261. protected virtual string CreateQueryString(NameValueCollection values)
  262. {
  263. var builder = new StringBuilder();
  264. foreach(string key in values.Keys)
  265. {
  266. if(key == "page") //Don't re-add any existing 'page' variable to the querystring - this will be handled in CreatePageLink.
  267. {
  268. continue;
  269. }
  270. foreach(var value in values.GetValues(key))
  271. {
  272. builder.AppendFormat("&amp;{0}={1}", key, HttpUtility.HtmlEncode(value));
  273. }
  274. }
  275. return builder.ToString();
  276. }
  277. protected override void RenderEmpty()
  278. {
  279. RenderText("<tr><td>" + EmptyMessageText + "</td></tr>");
  280. }
  281. /// <summary>
  282. /// Converts the specified attributes dictionary of key-value pairs into a string of HTML attributes.
  283. /// </summary>
  284. /// <returns></returns>
  285. private static string BuildHtmlAttributes(IDictionary attributes)
  286. {
  287. if (attributes == null || attributes.Count == 0)
  288. {
  289. return string.Empty;
  290. }
  291. var attributeSB = new StringBuilder();
  292. foreach (DictionaryEntry entry in attributes)
  293. {
  294. attributeSB.AppendFormat("{0}=\"{1}\"", entry.Key, entry.Value);
  295. attributeSB.Append(' ');
  296. }
  297. return attributeSB.ToString().Trim();
  298. }
  299. }
  300. }