diff --git a/.gitignore b/.gitignore index 70dc36a..16c6e0e 100644 --- a/.gitignore +++ b/.gitignore @@ -187,4 +187,5 @@ FakesAssemblies/ # LightSwitch generated files GeneratedArtifacts/ _Pvt_Extensions/ -ModelManifest.xml \ No newline at end of file +ModelManifest.xml +project.lock.json diff --git a/FlexLabs.Web.TablePager.sln b/FlexLabs.Util.Web.sln similarity index 59% rename from FlexLabs.Web.TablePager.sln rename to FlexLabs.Util.Web.sln index c93941f..e6549fd 100644 --- a/FlexLabs.Web.TablePager.sln +++ b/FlexLabs.Util.Web.sln @@ -5,12 +5,17 @@ VisualStudioVersion = 14.0.24720.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{A2875F06-7319-47E7-910E-02AFDB0926A8}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{A1A76EFD-F496-4950-9519-3121D04D6938}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E685C7B6-1D8A-4969-8C53-AF238F7300F8}" ProjectSection(SolutionItems) = preProject global.json = global.json + README.md = README.md EndProjectSection EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "FlexLabs.Web.TablePager", "src\FlexLabs.Web.TablePager\FlexLabs.Web.TablePager.xproj", "{819C9A3B-C8FA-42D2-9E4E-209355ED8443}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "FlexLabs.Util.Web", "src\FlexLabs.Util.Web\FlexLabs.Util.Web.xproj", "{819C9A3B-C8FA-42D2-9E4E-209355ED8443}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "FlexLabs.Util.Web.Tests", "test\FlexLabs.Util.Web.Tests\FlexLabs.Util.Web.Tests.xproj", "{7EA2A423-79BD-4F18-8E5C-F3681A682EF0}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -22,11 +27,16 @@ Global {819C9A3B-C8FA-42D2-9E4E-209355ED8443}.Debug|Any CPU.Build.0 = Debug|Any CPU {819C9A3B-C8FA-42D2-9E4E-209355ED8443}.Release|Any CPU.ActiveCfg = Release|Any CPU {819C9A3B-C8FA-42D2-9E4E-209355ED8443}.Release|Any CPU.Build.0 = Release|Any CPU + {7EA2A423-79BD-4F18-8E5C-F3681A682EF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7EA2A423-79BD-4F18-8E5C-F3681A682EF0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7EA2A423-79BD-4F18-8E5C-F3681A682EF0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7EA2A423-79BD-4F18-8E5C-F3681A682EF0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {819C9A3B-C8FA-42D2-9E4E-209355ED8443} = {A2875F06-7319-47E7-910E-02AFDB0926A8} + {7EA2A423-79BD-4F18-8E5C-F3681A682EF0} = {A1A76EFD-F496-4950-9519-3121D04D6938} EndGlobalSection EndGlobal diff --git a/README.md b/README.md index 42e068e..0159620 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ -TablePager +FlexLabs.Util.Web ========== -A NuGet extension that helps automate and simplify paging for MVC sites +A NuGet extension that helps automate and simplify some common tasks in MVC projects. + +Contains the TablePager and some new html editor extensions --- diff --git a/src/FlexLabs.Util.Web/AutoDropDownListAttribute.cs b/src/FlexLabs.Util.Web/AutoDropDownListAttribute.cs new file mode 100644 index 0000000..2c0a3a6 --- /dev/null +++ b/src/FlexLabs.Util.Web/AutoDropDownListAttribute.cs @@ -0,0 +1,19 @@ +using System; + +namespace FlexLabs.Web +{ + public sealed class AutoDropDownListAttribute : Attribute + { + /// + /// Defines the settings to initialise the DropDownList with + /// + /// The field in the model class that contains the IEnumerable<SelectListItem> + public AutoDropDownListAttribute(String optionsFieldName) + { + OptionsFieldName = optionsFieldName; + } + + public String OptionsFieldName { get; private set; } + public String OptionsLabel { get; set; } + } +} diff --git a/src/FlexLabs.Util.Web/AutoTextBoxAttribute.cs b/src/FlexLabs.Util.Web/AutoTextBoxAttribute.cs new file mode 100644 index 0000000..ec964fd --- /dev/null +++ b/src/FlexLabs.Util.Web/AutoTextBoxAttribute.cs @@ -0,0 +1,13 @@ +using System; + +namespace FlexLabs.Web +{ + public sealed class AutoTextBoxAttribute : Attribute + { + /// + /// A string that is used to format the input + /// + public String Format { get; set; } + public String Type { get; set; } + } +} diff --git a/src/FlexLabs.Util.Web/ExpressionHelper.cs b/src/FlexLabs.Util.Web/ExpressionHelper.cs new file mode 100644 index 0000000..b2fa058 --- /dev/null +++ b/src/FlexLabs.Util.Web/ExpressionHelper.cs @@ -0,0 +1,42 @@ +using System; +using System.Linq.Expressions; +using System.Reflection; + +namespace FlexLabs.Web.Html +{ + internal static class ExpressionHelper + { + public static MemberInfo GetMemberInfo(Expression expression) + { + if (expression == null) + return null; + + if (expression is LambdaExpression) + return GetMemberInfo((expression as LambdaExpression).Body); + + switch (expression.NodeType) + { + case ExpressionType.ArrayIndex: + var binaryExpression = expression as BinaryExpression; + return GetMemberInfo(binaryExpression.Left); + + case ExpressionType.MemberAccess: + var memberExpression = expression as MemberExpression; + return memberExpression.Member; + + default: + return null; + } + } + + public static TAttribute GetAttribute(MemberInfo memberInfo) + where TAttribute: Attribute + { + var attributes = memberInfo.GetCustomAttributes(typeof(TAttribute), false); + if (attributes.Length > 0) + return attributes[0] as TAttribute; + + return null; + } + } +} diff --git a/src/FlexLabs.Web.TablePager/FlexLabs.Web.TablePager.xproj b/src/FlexLabs.Util.Web/FlexLabs.Util.Web.xproj similarity index 88% rename from src/FlexLabs.Web.TablePager/FlexLabs.Web.TablePager.xproj rename to src/FlexLabs.Util.Web/FlexLabs.Util.Web.xproj index d5baa55..a63ac44 100644 --- a/src/FlexLabs.Web.TablePager/FlexLabs.Web.TablePager.xproj +++ b/src/FlexLabs.Util.Web/FlexLabs.Util.Web.xproj @@ -7,15 +7,13 @@ 819c9a3b-c8fa-42d2-9e4e-209355ed8443 - FlexLabs.TablePager + FlexLabs.Web ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ + True 2.0 - - True - \ No newline at end of file diff --git a/src/FlexLabs.Util.Web/Html/EditorExtensions.cs b/src/FlexLabs.Util.Web/Html/EditorExtensions.cs new file mode 100644 index 0000000..5e57261 --- /dev/null +++ b/src/FlexLabs.Util.Web/Html/EditorExtensions.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Web.Mvc; +using System.Web.Mvc.Html; + +namespace FlexLabs.Web.Html +{ + public static class EditorHelpers + { + public static MvcHtmlString AutoEditorFieldFor(this HtmlHelper html, Expression> expression, String templateName = null, Object additionalViewData = null) + { + var label = html.LabelFor(expression); + var validation = html.ValidationMessageFor(expression); + + MvcHtmlString editor = null; + var member = ExpressionHelper.GetMemberInfo(expression); + + if (editor == null && ExpressionHelper.GetAttribute(member) != null) + editor = html.AutoDropDownListFor(expression); + if (editor == null && ExpressionHelper.GetAttribute(member) != null) + editor = html.AutoTextBoxFor(expression); + if (editor == null) + editor = html.EditorFor(expression, templateName, additionalViewData); + + return MvcHtmlString.Create(label.ToString() + editor.ToString() + validation.ToString()); + } + + public static MvcHtmlString AutoDropDownListFor(this HtmlHelper html, Expression> expression, Object htmlAttributes = null) + { + var member = ExpressionHelper.GetMemberInfo(expression); + var attr = ExpressionHelper.GetAttribute(member); + if (attr == null) + throw new InvalidOperationException("Missing AutoDropDownListAttribute on property"); + + var field = member.DeclaringType.GetField(attr.OptionsFieldName); + if (field == null) + throw new MissingFieldException($"Could not find field {attr.OptionsFieldName} on type {member.DeclaringType}"); + if (!typeof(IEnumerable).IsAssignableFrom(field.FieldType)) + throw new Exception($"Field {attr.OptionsFieldName} is not of type IEnumerable"); + + var model = html.ViewData.Model; + var options = field.GetValue(model) as IEnumerable; + return html.DropDownListFor(expression, options, attr.OptionsLabel, htmlAttributes); + } + + public static MvcHtmlString AutoTextBoxFor(this HtmlHelper html, Expression> expression, Object htmlAttributes = null) + { + var member = ExpressionHelper.GetMemberInfo(expression); + var attr = ExpressionHelper.GetAttribute(member); + if (attr == null) + throw new InvalidOperationException("Missing AutoTextBoxAttribute on property"); + + var attributes = htmlAttributes != null + ? (IDictionary)HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes) + : new Dictionary(StringComparer.OrdinalIgnoreCase); + + if (attr.Type != null && !attributes.ContainsKey("type")) + attributes["type"] = attr.Type; + + return html.TextBoxFor(expression, attr.Format, attributes); + } + } +} diff --git a/src/FlexLabs.Util.Web/Html/PagingExtensions.cs b/src/FlexLabs.Util.Web/Html/PagingExtensions.cs new file mode 100644 index 0000000..4404bf7 --- /dev/null +++ b/src/FlexLabs.Util.Web/Html/PagingExtensions.cs @@ -0,0 +1,101 @@ +using FlexLabs.Web.TablePager; +using System; +using System.Web.Mvc; +using System.Web.Mvc.Html; + +namespace FlexLabs.Web.Html +{ + public static class PagingExtensions + { + public static MvcHtmlString EnableFormSorting(this HtmlHelper html) + where TModel : ITableModel + { + var model = html.ViewData.Model; + String result = String.Empty; + + if (model.SortBy != null) + { + var sortBy = new TagBuilder("input"); + sortBy.MergeAttribute("type", "hidden"); + sortBy.MergeAttribute("name", "SortBy"); + sortBy.MergeAttribute("value", model.SortBy.ToString()); + result += sortBy.ToString(TagRenderMode.SelfClosing); + } + + if (model.SortAsc != null) + { + var sortAsc = new TagBuilder("input"); + sortAsc.MergeAttribute("type", "hidden"); + sortAsc.MergeAttribute("name", "SortAsc"); + sortAsc.MergeAttribute("value", model.SortAsc.ToString()); + result += sortAsc.ToString(TagRenderMode.SelfClosing); + } + + if (model.FirstItemID != null) + { + var firstItemID = new TagBuilder("input"); + firstItemID.MergeAttribute("type", "hidden"); + firstItemID.MergeAttribute("name", "FirstItemID"); + firstItemID.MergeAttribute("value", model.FirstItemID.ToString()); + result += firstItemID.ToString(TagRenderMode.SelfClosing); + } + + return MvcHtmlString.Create(result); + } + + public static MvcHtmlString PageSizer(this HtmlHelper html, String lavel = "Page Size: ", Int32[] pageSizes = null, Int32? currentSize = null) + where TModel : ITableModel + { + var label = html.LabelFor(m => m.PageSize); + var editor = html.DropDownListFor(m => m.PageSize, TableModel.GetPageSizes(pageSizes, currentSize), new { onchange = "$(this).closest('form').submit();" }); + var validation = html.ValidationMessageFor(m => m.PageSize); + + return MvcHtmlString.Create(label.ToString() + editor.ToString() + validation.ToString()); + } + + public static MvcHtmlString Pager(this HtmlHelper html, PagedListData pageData, String label = "Page: ") + where TModel : ITableModel + { + var labelTag = new TagBuilder("label"); + labelTag.SetInnerText(label); + + var ulTag = new TagBuilder("ul"); + + if (!pageData.CanSeeFirstPage()) + ulTag.InnerHtml += PagerLink(1); + + foreach (var page in pageData.PageRange) + { + if (page == pageData.PageNumber) + ulTag.InnerHtml += $"
  • {page}
  • "; + else + ulTag.InnerHtml += PagerLink(page); + } + + if (!pageData.CanSeeLastPage()) + ulTag.InnerHtml += PagerLink(pageData.PageCount); + + var divTag = new TagBuilder("div"); + divTag.AddCssClass("table-pager"); + divTag.InnerHtml += labelTag.ToString(); + divTag.InnerHtml += ulTag; + return MvcHtmlString.Create(divTag.ToString()); + } + + private static String PagerLink(Int32 pageNumber) + { + return $"
  • "; + } + + public static MvcHtmlString Pager(this HtmlHelper html, String label = "Page: ") + where TModel : ITableModel + { + if (html.ViewData.Model?.PageItems?.PageCount == 0) + return null; + + var pageItems = html.ViewData.Model.PageItems; + var pageData = new PagedListData(pageItems.PageNumber, pageItems.PageSize, pageItems.PageCount, pageItems.TotalItemCount); + return Pager(html, pageData, label); + } + } +} diff --git a/src/FlexLabs.Util.Web/Html/TableExtensions.cs b/src/FlexLabs.Util.Web/Html/TableExtensions.cs new file mode 100644 index 0000000..adef07e --- /dev/null +++ b/src/FlexLabs.Util.Web/Html/TableExtensions.cs @@ -0,0 +1,70 @@ +using FlexLabs.Web.TablePager; +using System.Collections.Generic; +using System.Web.Mvc; + +namespace FlexLabs.Web.Html +{ + public static class TableExtensions + { + public static MvcHtmlString TableHeader(this HtmlHelper html, IEnumerable headers) + { + return TableHeader(html, new[] { headers }); + } + + public static MvcHtmlString TableHeader(this HtmlHelper html, IEnumerable> headersSet) + { + var theadTag = new TagBuilder("thead"); + + foreach (var headers in headersSet) + { + var rowTag = new TagBuilder("tr"); + foreach (var iheader in headers) + { + var thTag = new TagBuilder("th"); + if (iheader.CssClass != null) + thTag.AddCssClass(iheader.CssClass); + if (iheader.ColSpan.HasValue) + thTag.MergeAttribute("colspan", iheader.ColSpan.ToString()); + if (iheader.RowSpan.HasValue) + thTag.MergeAttribute("rowspan", iheader.RowSpan.ToString()); + + if (iheader is CustomTableHeader) + { + thTag.InnerHtml = (iheader as CustomTableHeader).Content(html.ViewData.Model).ToString(); + } + else + { + var header = iheader as TableHeader; + if (header.Value != null) + { + var buttonTag = new TagBuilder("button"); + buttonTag.MergeAttribute("type", "submit"); + buttonTag.MergeAttribute("name", "changeSort"); + buttonTag.MergeAttribute("value", header.Value.ToString()); + if (header.ToolTip != null) + buttonTag.MergeAttribute("title", header.ToolTip); + buttonTag.SetInnerText(header.Title); + thTag.InnerHtml = buttonTag.ToString(); + } + else if (header.ToolTip != null) + { + var span = new TagBuilder("span"); + span.MergeAttribute("title", header.ToolTip); + span.SetInnerText(header.Title); + thTag.InnerHtml = span.ToString(); + } + else + { + thTag.SetInnerText(header.Title); + } + } + + rowTag.InnerHtml += thTag.ToString(); + } + theadTag.InnerHtml += rowTag.ToString(); + } + + return MvcHtmlString.Create(theadTag.ToString()); + } + } +} diff --git a/src/FlexLabs.Web.TablePager/CustomTableHeader.cs b/src/FlexLabs.Util.Web/TablePager/CustomTableHeader.cs similarity index 100% rename from src/FlexLabs.Web.TablePager/CustomTableHeader.cs rename to src/FlexLabs.Util.Web/TablePager/CustomTableHeader.cs diff --git a/src/FlexLabs.Web.TablePager/ITableHeader.cs b/src/FlexLabs.Util.Web/TablePager/ITableHeader.cs similarity index 100% rename from src/FlexLabs.Web.TablePager/ITableHeader.cs rename to src/FlexLabs.Util.Web/TablePager/ITableHeader.cs diff --git a/src/FlexLabs.Web.TablePager/ITableModel.cs b/src/FlexLabs.Util.Web/TablePager/ITableModel.cs similarity index 67% rename from src/FlexLabs.Web.TablePager/ITableModel.cs rename to src/FlexLabs.Util.Web/TablePager/ITableModel.cs index 7c09967..1c6e837 100644 --- a/src/FlexLabs.Web.TablePager/ITableModel.cs +++ b/src/FlexLabs.Util.Web/TablePager/ITableModel.cs @@ -1,4 +1,5 @@ -using System; +using PagedList; +using System; namespace FlexLabs.Web.TablePager { @@ -8,5 +9,8 @@ public interface ITableModel Object SortBy { get; set; } Boolean? SortAsc { get; set; } Int64? FirstItemID { get; set; } + Int32? PageSize { get; set; } + + IPagedList PageItems { get; } } } diff --git a/src/FlexLabs.Web.TablePager/PagedListData.cs b/src/FlexLabs.Util.Web/TablePager/PagedListData.cs similarity index 100% rename from src/FlexLabs.Web.TablePager/PagedListData.cs rename to src/FlexLabs.Util.Web/TablePager/PagedListData.cs diff --git a/src/FlexLabs.Web.TablePager/TableHeader.cs b/src/FlexLabs.Util.Web/TablePager/TableHeader.cs similarity index 100% rename from src/FlexLabs.Web.TablePager/TableHeader.cs rename to src/FlexLabs.Util.Web/TablePager/TableHeader.cs diff --git a/src/FlexLabs.Util.Web/TablePager/TableHeaderCollection.cs b/src/FlexLabs.Util.Web/TablePager/TableHeaderCollection.cs new file mode 100644 index 0000000..a4fc195 --- /dev/null +++ b/src/FlexLabs.Util.Web/TablePager/TableHeaderCollection.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace FlexLabs.Web.TablePager +{ + public class TableHeaderCollection : ICollection + { + private readonly IList _headers = new List(); + + public int Count { get { return _headers.Count; } } + + public bool IsReadOnly { get { return false; } } + + public void Add(ITableHeader item) + { + _headers.Add(item); + } + + public void Add(String title, Object value = null, String tooltip = null) + { + _headers.Add(new TableHeader { Title = title, Value = value, ToolTip = tooltip }); + } + + public void Clear() + { + _headers.Clear(); + } + + public bool Contains(ITableHeader item) + { + return _headers.Contains(item); + } + + public void CopyTo(ITableHeader[] array, int arrayIndex) + { + _headers.CopyTo(array, arrayIndex); + } + + public IEnumerator GetEnumerator() + { + return _headers.GetEnumerator(); + } + + public bool Remove(ITableHeader item) + { + return _headers.Remove(item); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _headers.GetEnumerator(); + } + } +} diff --git a/src/FlexLabs.Web.TablePager/TableModel.cs b/src/FlexLabs.Util.Web/TablePager/TableModel.cs similarity index 98% rename from src/FlexLabs.Web.TablePager/TableModel.cs rename to src/FlexLabs.Util.Web/TablePager/TableModel.cs index f3a6fbb..01faa88 100644 --- a/src/FlexLabs.Web.TablePager/TableModel.cs +++ b/src/FlexLabs.Util.Web/TablePager/TableModel.cs @@ -59,6 +59,7 @@ public TableModel(TSorter defaultSorter, Boolean defaultAscending, Boolean pagin object ITableModel.SortBy { get { return SortBy; } set { SortBy = (TSorter?)value; } } public IPagedList PageItems; + IPagedList ITableModel.PageItems { get { return PageItems; } } public abstract TModel TranslateItem(TSource item); diff --git a/src/FlexLabs.Web.TablePager/TableModelBinder.cs b/src/FlexLabs.Util.Web/TablePager/TableModelBinder.cs similarity index 100% rename from src/FlexLabs.Web.TablePager/TableModelBinder.cs rename to src/FlexLabs.Util.Web/TablePager/TableModelBinder.cs diff --git a/src/FlexLabs.Web.TablePager/TablePager.generated.cs b/src/FlexLabs.Util.Web/TablePager/TablePager.generated.cs similarity index 97% rename from src/FlexLabs.Web.TablePager/TablePager.generated.cs rename to src/FlexLabs.Util.Web/TablePager/TablePager.generated.cs index 5ae07aa..6ba8ebc 100644 --- a/src/FlexLabs.Web.TablePager/TablePager.generated.cs +++ b/src/FlexLabs.Util.Web/TablePager/TablePager.generated.cs @@ -49,6 +49,7 @@ public class TablePager : System.Web.WebPages.HelperPage #line 7 "..\..\TablePager.cshtml" + [Obsolete("This method is obsolete. Use Html.Pager() instead")] public static HelperResult Pager(IPagedList pagedList, String label = "Page: ") { if (pagedList.PageCount == 0) @@ -62,6 +63,7 @@ public static HelperResult Pager(IPagedList pagedList, String label = "Pag #line default #line hidden + [Obsolete("This method is obsolete. Use Html.Pager() instead")] #line 17 "..\..\TablePager.cshtml" public static System.Web.WebPages.HelperResult Pager(PagedListData model, String label) { @@ -246,6 +248,7 @@ public static System.Web.WebPages.HelperResult Pager(PagedListData model, String #line default #line hidden + [Obsolete("This method is obsolete. Use Html.PageSizer() instead")] #line 40 "..\..\TablePager.cshtml" public static System.Web.WebPages.HelperResult PageSizer(System.Web.Mvc.HtmlHelper html, String label = "Page Size:", Int32[] pageSizes = null, Int32? currentSize = null) { @@ -308,6 +311,7 @@ public static System.Web.WebPages.HelperResult PageSizer(System.Web.Mvc.HtmlHelp #line default #line hidden + [Obsolete("This method is obsolete. Use Html.Header() instead")] #line 46 "..\..\TablePager.cshtml" public static System.Web.WebPages.HelperResult Header(IEnumerable headers) { @@ -342,6 +346,7 @@ public static System.Web.WebPages.HelperResult Header(IEnumerable #line default #line hidden + [Obsolete("This method is obsolete. Use Html.Header() instead")] #line 49 "..\..\TablePager.cshtml" public static System.Web.WebPages.HelperResult Header(IEnumerable[] headersSet) { @@ -542,6 +547,7 @@ public static System.Web.WebPages.HelperResult Header(IEnumerable[ #line default #line hidden + [Obsolete("This method is obsolete. Use Html.EnableFormSorting() instead")] #line 72 "..\..\TablePager.cshtml" public static System.Web.WebPages.HelperResult FormHidden(ITableModel model) { diff --git a/src/FlexLabs.Web.TablePager/project.json b/src/FlexLabs.Util.Web/project.json similarity index 77% rename from src/FlexLabs.Web.TablePager/project.json rename to src/FlexLabs.Util.Web/project.json index b382104..50c278f 100644 --- a/src/FlexLabs.Web.TablePager/project.json +++ b/src/FlexLabs.Util.Web/project.json @@ -1,15 +1,12 @@ { - "version": "2.0.5-*", - "title": "FlexLabs Table Pager", - "description": "Helps manage paging and page sorting in a ASP.NET MVC project. Works best when used in conjunction with FlexLabs.Util", + "version": "2.0.6-*", + "title": "FlexLabs Util Web", + "description": "Building on the same principle as FlexLabs.Util, adds helper methods for MVC enabled projects!", "authors": [ "Artiom Chilaru" ], "tags": [ "" ], - "projectUrl": "https://github.com/artiomchi/TablePager", + "projectUrl": "https://github.com/artiomchi/FlexLabs.Util.Web", "licenseUrl": "", - "dependencies": { - }, - "frameworks": { "dnx451": { "frameworkAssemblies": { diff --git a/src/FlexLabs.Web.TablePager/TablePager.cshtml b/src/FlexLabs.Web.TablePager/TablePager.cshtml deleted file mode 100644 index 77c7d0d..0000000 --- a/src/FlexLabs.Web.TablePager/TablePager.cshtml +++ /dev/null @@ -1,77 +0,0 @@ -@* Generator: MvcHelper *@ -@using PagedList -@using System.Web.Mvc -@using System.Web.Mvc.Html -@functions { - public static HelperResult Pager(IPagedList pagedList, String label = "Page: ") - { - if (pagedList.PageCount == 0) { - return null; - } - var model = new PagedListData(pagedList.PageNumber, pagedList.PageSize, pagedList.PageCount, pagedList.TotalItemCount); - return Pager(model, label); - } -} -@helper Pager(PagedListData model, String label) { -
    - -
      - @if (!model.CanSeeFirstPage()) { -
    • - . -
    • - } - @foreach (var page in model.PageRange) { - if (page == model.PageNumber) { -
    • @page
    • - } else { -
    • - } - } - @if (!model.CanSeeLastPage()) { -
    • - } -
    -
    -} - -@helper PageSizer(System.Web.Mvc.HtmlHelper html, String label = "Page Size:", Int32[] pageSizes = null, Int32? currentSize = null) { - @html.Label("PageSize", label) - @html.DropDownList("PageSize", TableModel.GetPageSizes(pageSizes, currentSize), new { onchange = "$(this).closest('form').submit();" }) - @html.ValidationMessage("PageSize") -} - -@helper Header(IEnumerable headers) { -@Header(new[] { headers }) -} -@helper Header(IEnumerable[] headersSet) { - - @foreach (var headers in headersSet) { - - @foreach (var iheader in headers) { - @{ - var header = iheader as TableHeader; - if (iheader is CustomTableHeader) { - @((iheader as CustomTableHeader).Content(null)) - } else { - if(header.Value != null) - {} - else { - @header.Title - } - } - } - } - - } - -} - -@helper FormHidden(ITableModel model) { - @* Mvc Seems to prioritise the values from the request model, over the values changed in the code, so I have to go a bit "manual" here :) [Artiom] *@ - - - if (model.FirstItemID.HasValue) { - - } -} diff --git a/src/FlexLabs.Web.TablePager/project.lock.json b/src/FlexLabs.Web.TablePager/project.lock.json deleted file mode 100644 index ff3cdaf..0000000 --- a/src/FlexLabs.Web.TablePager/project.lock.json +++ /dev/null @@ -1,447 +0,0 @@ -{ - "locked": false, - "version": 2, - "targets": { - "DNX,Version=v4.5.1": { - "Microsoft.AspNet.Mvc/4.0.20505": { - "type": "package", - "dependencies": { - "Microsoft.AspNet.Razor": "2.0.20505", - "Microsoft.AspNet.WebPages": "2.0.20505" - }, - "compile": { - "lib/net40/System.Web.Mvc.dll": {} - }, - "runtime": { - "lib/net40/System.Web.Mvc.dll": {} - } - }, - "Microsoft.AspNet.Razor/2.0.20505": { - "type": "package", - "compile": { - "lib/net40/System.Web.Razor.dll": {} - }, - "runtime": { - "lib/net40/System.Web.Razor.dll": {} - } - }, - "Microsoft.AspNet.WebPages/2.0.20505": { - "type": "package", - "dependencies": { - "Microsoft.AspNet.Razor": "2.0.20505", - "Microsoft.Web.Infrastructure": "1.0.0" - }, - "compile": { - "lib/net40/System.Web.Helpers.dll": {}, - "lib/net40/System.Web.WebPages.Deployment.dll": {}, - "lib/net40/System.Web.WebPages.dll": {}, - "lib/net40/System.Web.WebPages.Razor.dll": {} - }, - "runtime": { - "lib/net40/System.Web.Helpers.dll": {}, - "lib/net40/System.Web.WebPages.Deployment.dll": {}, - "lib/net40/System.Web.WebPages.dll": {}, - "lib/net40/System.Web.WebPages.Razor.dll": {} - } - }, - "Microsoft.Web.Infrastructure/1.0.0": { - "type": "package", - "compile": { - "lib/net40/Microsoft.Web.Infrastructure.dll": {} - }, - "runtime": { - "lib/net40/Microsoft.Web.Infrastructure.dll": {} - } - }, - "PagedList/1.15.0": { - "type": "package", - "compile": { - "lib/net40/PagedList.dll": {} - }, - "runtime": { - "lib/net40/PagedList.dll": {} - } - } - }, - ".NETFramework,Version=v4.5": { - "Microsoft.AspNet.Mvc/4.0.20505": { - "type": "package", - "dependencies": { - "Microsoft.AspNet.Razor": "2.0.20505", - "Microsoft.AspNet.WebPages": "2.0.20505" - }, - "compile": { - "lib/net40/System.Web.Mvc.dll": {} - }, - "runtime": { - "lib/net40/System.Web.Mvc.dll": {} - } - }, - "Microsoft.AspNet.Razor/2.0.20505": { - "type": "package", - "compile": { - "lib/net40/System.Web.Razor.dll": {} - }, - "runtime": { - "lib/net40/System.Web.Razor.dll": {} - } - }, - "Microsoft.AspNet.WebPages/2.0.20505": { - "type": "package", - "dependencies": { - "Microsoft.AspNet.Razor": "2.0.20505", - "Microsoft.Web.Infrastructure": "1.0.0" - }, - "compile": { - "lib/net40/System.Web.Helpers.dll": {}, - "lib/net40/System.Web.WebPages.Deployment.dll": {}, - "lib/net40/System.Web.WebPages.dll": {}, - "lib/net40/System.Web.WebPages.Razor.dll": {} - }, - "runtime": { - "lib/net40/System.Web.Helpers.dll": {}, - "lib/net40/System.Web.WebPages.Deployment.dll": {}, - "lib/net40/System.Web.WebPages.dll": {}, - "lib/net40/System.Web.WebPages.Razor.dll": {} - } - }, - "Microsoft.Web.Infrastructure/1.0.0": { - "type": "package", - "compile": { - "lib/net40/Microsoft.Web.Infrastructure.dll": {} - }, - "runtime": { - "lib/net40/Microsoft.Web.Infrastructure.dll": {} - } - }, - "PagedList/1.15.0": { - "type": "package", - "compile": { - "lib/net40/PagedList.dll": {} - }, - "runtime": { - "lib/net40/PagedList.dll": {} - } - } - }, - "DNX,Version=v4.5.1/win7-x86": { - "Microsoft.AspNet.Mvc/4.0.20505": { - "type": "package", - "dependencies": { - "Microsoft.AspNet.Razor": "2.0.20505", - "Microsoft.AspNet.WebPages": "2.0.20505" - }, - "compile": { - "lib/net40/System.Web.Mvc.dll": {} - }, - "runtime": { - "lib/net40/System.Web.Mvc.dll": {} - } - }, - "Microsoft.AspNet.Razor/2.0.20505": { - "type": "package", - "compile": { - "lib/net40/System.Web.Razor.dll": {} - }, - "runtime": { - "lib/net40/System.Web.Razor.dll": {} - } - }, - "Microsoft.AspNet.WebPages/2.0.20505": { - "type": "package", - "dependencies": { - "Microsoft.AspNet.Razor": "2.0.20505", - "Microsoft.Web.Infrastructure": "1.0.0" - }, - "compile": { - "lib/net40/System.Web.Helpers.dll": {}, - "lib/net40/System.Web.WebPages.Deployment.dll": {}, - "lib/net40/System.Web.WebPages.dll": {}, - "lib/net40/System.Web.WebPages.Razor.dll": {} - }, - "runtime": { - "lib/net40/System.Web.Helpers.dll": {}, - "lib/net40/System.Web.WebPages.Deployment.dll": {}, - "lib/net40/System.Web.WebPages.dll": {}, - "lib/net40/System.Web.WebPages.Razor.dll": {} - } - }, - "Microsoft.Web.Infrastructure/1.0.0": { - "type": "package", - "compile": { - "lib/net40/Microsoft.Web.Infrastructure.dll": {} - }, - "runtime": { - "lib/net40/Microsoft.Web.Infrastructure.dll": {} - } - }, - "PagedList/1.15.0": { - "type": "package", - "compile": { - "lib/net40/PagedList.dll": {} - }, - "runtime": { - "lib/net40/PagedList.dll": {} - } - } - }, - "DNX,Version=v4.5.1/win7-x64": { - "Microsoft.AspNet.Mvc/4.0.20505": { - "type": "package", - "dependencies": { - "Microsoft.AspNet.Razor": "2.0.20505", - "Microsoft.AspNet.WebPages": "2.0.20505" - }, - "compile": { - "lib/net40/System.Web.Mvc.dll": {} - }, - "runtime": { - "lib/net40/System.Web.Mvc.dll": {} - } - }, - "Microsoft.AspNet.Razor/2.0.20505": { - "type": "package", - "compile": { - "lib/net40/System.Web.Razor.dll": {} - }, - "runtime": { - "lib/net40/System.Web.Razor.dll": {} - } - }, - "Microsoft.AspNet.WebPages/2.0.20505": { - "type": "package", - "dependencies": { - "Microsoft.AspNet.Razor": "2.0.20505", - "Microsoft.Web.Infrastructure": "1.0.0" - }, - "compile": { - "lib/net40/System.Web.Helpers.dll": {}, - "lib/net40/System.Web.WebPages.Deployment.dll": {}, - "lib/net40/System.Web.WebPages.dll": {}, - "lib/net40/System.Web.WebPages.Razor.dll": {} - }, - "runtime": { - "lib/net40/System.Web.Helpers.dll": {}, - "lib/net40/System.Web.WebPages.Deployment.dll": {}, - "lib/net40/System.Web.WebPages.dll": {}, - "lib/net40/System.Web.WebPages.Razor.dll": {} - } - }, - "Microsoft.Web.Infrastructure/1.0.0": { - "type": "package", - "compile": { - "lib/net40/Microsoft.Web.Infrastructure.dll": {} - }, - "runtime": { - "lib/net40/Microsoft.Web.Infrastructure.dll": {} - } - }, - "PagedList/1.15.0": { - "type": "package", - "compile": { - "lib/net40/PagedList.dll": {} - }, - "runtime": { - "lib/net40/PagedList.dll": {} - } - } - }, - ".NETFramework,Version=v4.5/win7-x86": { - "Microsoft.AspNet.Mvc/4.0.20505": { - "type": "package", - "dependencies": { - "Microsoft.AspNet.Razor": "2.0.20505", - "Microsoft.AspNet.WebPages": "2.0.20505" - }, - "compile": { - "lib/net40/System.Web.Mvc.dll": {} - }, - "runtime": { - "lib/net40/System.Web.Mvc.dll": {} - } - }, - "Microsoft.AspNet.Razor/2.0.20505": { - "type": "package", - "compile": { - "lib/net40/System.Web.Razor.dll": {} - }, - "runtime": { - "lib/net40/System.Web.Razor.dll": {} - } - }, - "Microsoft.AspNet.WebPages/2.0.20505": { - "type": "package", - "dependencies": { - "Microsoft.AspNet.Razor": "2.0.20505", - "Microsoft.Web.Infrastructure": "1.0.0" - }, - "compile": { - "lib/net40/System.Web.Helpers.dll": {}, - "lib/net40/System.Web.WebPages.Deployment.dll": {}, - "lib/net40/System.Web.WebPages.dll": {}, - "lib/net40/System.Web.WebPages.Razor.dll": {} - }, - "runtime": { - "lib/net40/System.Web.Helpers.dll": {}, - "lib/net40/System.Web.WebPages.Deployment.dll": {}, - "lib/net40/System.Web.WebPages.dll": {}, - "lib/net40/System.Web.WebPages.Razor.dll": {} - } - }, - "Microsoft.Web.Infrastructure/1.0.0": { - "type": "package", - "compile": { - "lib/net40/Microsoft.Web.Infrastructure.dll": {} - }, - "runtime": { - "lib/net40/Microsoft.Web.Infrastructure.dll": {} - } - }, - "PagedList/1.15.0": { - "type": "package", - "compile": { - "lib/net40/PagedList.dll": {} - }, - "runtime": { - "lib/net40/PagedList.dll": {} - } - } - }, - ".NETFramework,Version=v4.5/win7-x64": { - "Microsoft.AspNet.Mvc/4.0.20505": { - "type": "package", - "dependencies": { - "Microsoft.AspNet.Razor": "2.0.20505", - "Microsoft.AspNet.WebPages": "2.0.20505" - }, - "compile": { - "lib/net40/System.Web.Mvc.dll": {} - }, - "runtime": { - "lib/net40/System.Web.Mvc.dll": {} - } - }, - "Microsoft.AspNet.Razor/2.0.20505": { - "type": "package", - "compile": { - "lib/net40/System.Web.Razor.dll": {} - }, - "runtime": { - "lib/net40/System.Web.Razor.dll": {} - } - }, - "Microsoft.AspNet.WebPages/2.0.20505": { - "type": "package", - "dependencies": { - "Microsoft.AspNet.Razor": "2.0.20505", - "Microsoft.Web.Infrastructure": "1.0.0" - }, - "compile": { - "lib/net40/System.Web.Helpers.dll": {}, - "lib/net40/System.Web.WebPages.Deployment.dll": {}, - "lib/net40/System.Web.WebPages.dll": {}, - "lib/net40/System.Web.WebPages.Razor.dll": {} - }, - "runtime": { - "lib/net40/System.Web.Helpers.dll": {}, - "lib/net40/System.Web.WebPages.Deployment.dll": {}, - "lib/net40/System.Web.WebPages.dll": {}, - "lib/net40/System.Web.WebPages.Razor.dll": {} - } - }, - "Microsoft.Web.Infrastructure/1.0.0": { - "type": "package", - "compile": { - "lib/net40/Microsoft.Web.Infrastructure.dll": {} - }, - "runtime": { - "lib/net40/Microsoft.Web.Infrastructure.dll": {} - } - }, - "PagedList/1.15.0": { - "type": "package", - "compile": { - "lib/net40/PagedList.dll": {} - }, - "runtime": { - "lib/net40/PagedList.dll": {} - } - } - } - }, - "libraries": { - "Microsoft.AspNet.Mvc/4.0.20505": { - "type": "package", - "sha512": "V6zLs67Ns8wMQ4AkzP2iFn3hh/KkM4r+YxkjV2NgTnlVyo3jgiHDmdi0sM6Bl51sGcwg8BGhgRsLGDOzTqunzg==", - "files": [ - "lib/net40/System.Web.Mvc.dll", - "lib/net40/System.Web.Mvc.xml", - "Microsoft.AspNet.Mvc.4.0.20505.nupkg", - "Microsoft.AspNet.Mvc.4.0.20505.nupkg.sha512", - "Microsoft.AspNet.Mvc.nuspec" - ] - }, - "Microsoft.AspNet.Razor/2.0.20505": { - "type": "package", - "sha512": "Gk3ZVP/bwGsKx3fQf4EHoIzCApHU9LTIWOjmABa5VMT7axwyPDtUq3wGfW3LiHmlHjkh/SwnZzwCw1LnCTgmBQ==", - "files": [ - "lib/net40/System.Web.Razor.dll", - "lib/net40/System.Web.Razor.xml", - "Microsoft.AspNet.Razor.2.0.20505.nupkg", - "Microsoft.AspNet.Razor.2.0.20505.nupkg.sha512", - "Microsoft.AspNet.Razor.nuspec" - ] - }, - "Microsoft.AspNet.WebPages/2.0.20505": { - "type": "package", - "sha512": "/eILBjvoH9y3DqTZO3HX0HHyocyQPzdR125lVxSVHJUQq6NosyYS9BdcLlug9c7qYtVkDcUDxQRhHTBnDqC1VA==", - "files": [ - "lib/net40/System.Web.Helpers.dll", - "lib/net40/System.Web.Helpers.xml", - "lib/net40/System.Web.WebPages.Deployment.dll", - "lib/net40/System.Web.WebPages.Deployment.xml", - "lib/net40/System.Web.WebPages.dll", - "lib/net40/System.Web.WebPages.Razor.dll", - "lib/net40/System.Web.WebPages.Razor.xml", - "lib/net40/System.Web.WebPages.xml", - "Microsoft.AspNet.WebPages.2.0.20505.nupkg", - "Microsoft.AspNet.WebPages.2.0.20505.nupkg.sha512", - "Microsoft.AspNet.WebPages.nuspec" - ] - }, - "Microsoft.Web.Infrastructure/1.0.0": { - "type": "package", - "sha512": "FNmvLn5m2LTU/Rs2KWVo0SIIh9Ek+U0ojex7xeDaSHw/zgEP77A8vY5cVWgUtBGS8MJfDGNn8rpXJWEIQaPwTg==", - "files": [ - "lib/net40/Microsoft.Web.Infrastructure.dll", - "Microsoft.Web.Infrastructure.1.0.0.nupkg", - "Microsoft.Web.Infrastructure.1.0.0.nupkg.sha512", - "Microsoft.Web.Infrastructure.nuspec" - ] - }, - "PagedList/1.15.0": { - "type": "package", - "sha512": "9dsyyfnjBvW2lECdTzMZCqQ/+DRtCEmXPHllOC+ZEg4EMp7ADkpMgOYIUkM4pqvtAQw/rcRvjpCrwjIz6zDS/Q==", - "files": [ - "lib/net40/PagedList.dll", - "lib/net40/PagedList.xml", - "PagedList.1.15.0.nupkg", - "PagedList.1.15.0.nupkg.sha512", - "PagedList.nuspec" - ] - } - }, - "projectFileDependencyGroups": { - "": [], - "DNX,Version=v4.5.1": [ - "Microsoft.AspNet.Mvc >= 4.0.20505", - "PagedList >= 1.15.0", - "fx/System.Web " - ], - ".NETFramework,Version=v4.5": [ - "Microsoft.AspNet.Mvc >= 4.0.20505", - "PagedList >= 1.15.0", - "fx/System.Web " - ] - } -} \ No newline at end of file diff --git a/test/FlexLabs.Util.Web.Tests/FlexLabs.Util.Web.Tests.xproj b/test/FlexLabs.Util.Web.Tests/FlexLabs.Util.Web.Tests.xproj new file mode 100644 index 0000000..e48bc6d --- /dev/null +++ b/test/FlexLabs.Util.Web.Tests/FlexLabs.Util.Web.Tests.xproj @@ -0,0 +1,21 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 7ea2a423-79bd-4f18-8e5c-f3681a682ef0 + FlexLabs.Util.Web.Tests + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ + + + 2.0 + + + + + + \ No newline at end of file diff --git a/test/FlexLabs.Util.Web.Tests/Properties/AssemblyInfo.cs b/test/FlexLabs.Util.Web.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..36a4d5d --- /dev/null +++ b/test/FlexLabs.Util.Web.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,23 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("FlexLabs.Util.Web.Tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("FlexLabs.Util.Web.Tests")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("7ea2a423-79bd-4f18-8e5c-f3681a682ef0")] diff --git a/test/FlexLabs.Util.Web.Tests/TablePager/TableHeaderCollectionTests.cs b/test/FlexLabs.Util.Web.Tests/TablePager/TableHeaderCollectionTests.cs new file mode 100644 index 0000000..821e60e --- /dev/null +++ b/test/FlexLabs.Util.Web.Tests/TablePager/TableHeaderCollectionTests.cs @@ -0,0 +1,41 @@ +using FlexLabs.Web.TablePager; +using System; +using System.Linq; +using System.Web; +using Xunit; + +namespace FlexLabs.Util.Web.Tests.TablePager +{ + public class TableHeaderCollectionTests + { + [Fact] + public void TableHeaderCollection_InlineInit() + { + Func customContent = x => new HtmlString("hello"); + + var headers = new TableHeaderCollection + { + { "Header 1" }, + { "Header 2", 123 }, + { new TableHeader { Title = "Header 3", CssClass = "css" } }, + { new CustomTableHeader { Content = customContent } }, + }.ToList(); + + Assert.Equal(4, headers.Count); + + Assert.IsType(headers[0]); + Assert.Equal("Header 1", (headers[0] as TableHeader).Title); + + Assert.IsType(headers[1]); + Assert.Equal("Header 2", (headers[1] as TableHeader).Title); + Assert.Equal(123, (headers[1] as TableHeader).Value); + + Assert.IsType(headers[2]); + Assert.Equal("Header 3", (headers[2] as TableHeader).Title); + Assert.Equal("css", (headers[2] as TableHeader).CssClass); + + Assert.IsType(headers[3]); + Assert.Equal(customContent, (headers[3] as CustomTableHeader).Content); + } + } +} diff --git a/test/FlexLabs.Util.Web.Tests/project.json b/test/FlexLabs.Util.Web.Tests/project.json new file mode 100644 index 0000000..c3d9feb --- /dev/null +++ b/test/FlexLabs.Util.Web.Tests/project.json @@ -0,0 +1,23 @@ +{ + "version": "1.0.0-*", + "description": "FlexLabs.Util.Web.Tests Class Library", + "authors": [ "artio" ], + "tags": [ "" ], + "projectUrl": "", + "licenseUrl": "", + + "dependencies": { + "FlexLabs.Util.Web": "", + "xunit": "2.1.0", + "xunit.runner.dnx": "2.1.0-rc1-*", + "xunit.runner.visualstudio": "2.1.0" + }, + + "commands": { + "test": "xunit.runner.dnx" + }, + + "frameworks": { + "dnx451": { } + } +}