From 15dca510e5b76e813f92e5100a18156a001e35f4 Mon Sep 17 00:00:00 2001 From: yekalkan Date: Thu, 26 Apr 2018 13:35:56 +0300 Subject: [PATCH 01/25] basic form-group tag helper --- .../TagHelpers/Form/AbpFormGroupTagHelper.cs | 16 ++++++++++++++++ .../Form/AbpFormGroupTagHelperService.cs | 19 +++++++++++++++++++ .../Pages/Components/Forms.cshtml | 18 +++++++++++++++--- 3 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelper.cs create mode 100644 src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelper.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelper.cs new file mode 100644 index 0000000000..cbbc8fec29 --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelper.cs @@ -0,0 +1,16 @@ +using JetBrains.Annotations; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form +{ + public class AbpFormGroupTagHelper : AbpTagHelper + { + + public bool Checkbox { get; set; } + + public AbpFormGroupTagHelper(AbpFormGroupTagHelperService tagHelperService) + : base(tagHelperService) + { + + } + } +} diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs new file mode 100644 index 0000000000..5823827477 --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs @@ -0,0 +1,19 @@ +using System.Text; +using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form +{ + public class AbpFormGroupTagHelperService : AbpTagHelperService + { + public override void Process(TagHelperContext context, TagHelperOutput output) + { + output.TagName = "div"; + output.Attributes.AddClass("form-group"); + if (TagHelper.Checkbox) + { + output.Attributes.AddClass("form-check"); + } + } + } +} \ No newline at end of file diff --git a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml index 30d8008e0e..7e388521bb 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml +++ b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml @@ -12,11 +12,23 @@
- + + + + + + +
-
-
+        
       
+        <abp-form-group>
+            <input type="text" class="form-control">
+        </abp-form-group>
+        <abp-form-group checkbox="true">
+            <input type="checkbox" class="form-check-input" id="exampleCheck1">
+            <label class="form-check-label" for="exampleCheck1">Check me out</label>
+        </abp-form-group>
         
From 912b2616e401aa2bf9c9ffb61364e10e859c556f Mon Sep 17 00:00:00 2001 From: yekalkan Date: Thu, 26 Apr 2018 15:35:43 +0300 Subject: [PATCH 02/25] basic Form-group and input tag helpers --- .../TagHelpers/Form/AbpFormGroupTagHelper.cs | 1 - .../Form/AbpFormGroupTagHelperService.cs | 29 +++++++++++++++++-- .../TagHelpers/Form/AbpInputTagHelper.cs | 18 ++++++++++++ .../Form/AbpInputTagHelperService.cs | 17 +++++++++++ .../Pages/Components/Forms.cshtml | 4 +-- 5 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs create mode 100644 src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelper.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelper.cs index cbbc8fec29..300ed7a4c3 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelper.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelper.cs @@ -4,7 +4,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { public class AbpFormGroupTagHelper : AbpTagHelper { - public bool Checkbox { get; set; } public AbpFormGroupTagHelper(AbpFormGroupTagHelperService tagHelperService) diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs index 5823827477..6f8b230c6d 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs @@ -1,4 +1,9 @@ -using System.Text; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Text.Encodings.Web; +using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.TagHelpers; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; @@ -6,14 +11,34 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { public class AbpFormGroupTagHelperService : AbpTagHelperService { + private readonly HtmlEncoder _htmlEncoder; + private readonly AbpInputTagHelper _abpInputTagHelper; + + public AbpFormGroupTagHelperService(HtmlEncoder htmlEncoder, AbpInputTagHelper abpInputTagHelper) + { + _htmlEncoder = htmlEncoder; + _abpInputTagHelper = abpInputTagHelper; + } + public override void Process(TagHelperContext context, TagHelperOutput output) { output.TagName = "div"; output.Attributes.AddClass("form-group"); if (TagHelper.Checkbox) { - output.Attributes.AddClass("form-check"); + output.Attributes.AddClass("form-check"); } + + + //var attributes = new TagHelperAttributeList + //{ + // {"Type", "Text"}, + // {"Placeholder", "plcHlder"} + //}; + + //output.Content.AppendHtml(RenderInputTagHelper(attributes, _abpInputTagHelper, _htmlEncoder)); + } + } } \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs new file mode 100644 index 0000000000..7b9e823b29 --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs @@ -0,0 +1,18 @@ +using Microsoft.AspNetCore.Razor.TagHelpers; + + +using JetBrains.Annotations; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form +{ + public class AbpInputTagHelper : AbpTagHelper, ITransientDependency + { + + public AbpInputTagHelper(AbpInputTagHelperService tagHelperService) + : base(tagHelperService) + { + + } + } +} diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs new file mode 100644 index 0000000000..357543793c --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs @@ -0,0 +1,17 @@ +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form +{ + public class AbpInputTagHelperService : AbpTagHelperService + { + public override void Process(TagHelperContext context, TagHelperOutput output) + { + output.TagName = "input"; + output.Attributes.AddClass("form-control"); + output.TagMode = TagMode.SelfClosing; + } + } +} \ No newline at end of file diff --git a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml index 7e388521bb..5f34a0ebf1 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml +++ b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml @@ -13,7 +13,7 @@
- + @@ -23,7 +23,7 @@
       
         <abp-form-group>
-            <input type="text" class="form-control">
+            <abp-input type="text"/>
         </abp-form-group>
         <abp-form-group checkbox="true">
             <input type="checkbox" class="form-check-input" id="exampleCheck1">

From f6302e438bfc4fd023e5d759ef1a52bc97029d20 Mon Sep 17 00:00:00 2001
From: yekalkan 
Date: Thu, 26 Apr 2018 15:35:58 +0300
Subject: [PATCH 03/25] Inner html render

---
 .../TagHelpers/AbpTagHelperService.cs         | 29 ++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs
index 6c5e0c14a1..38f5878cd0 100644
--- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs
+++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs
@@ -1,4 +1,8 @@
-using System.Threading.Tasks;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text.Encodings.Web;
+using System.Threading.Tasks;
 using Microsoft.AspNetCore.Razor.TagHelpers;
 
 namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers
@@ -25,5 +29,28 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers
             Process(context, output);
             return Task.CompletedTask;
         }
+
+        protected string RenderInputTagHelper(TagHelperAttributeList attributeList, AbpTagHelper abpTagHelper, HtmlEncoder htmlEncoder)
+        {
+            var innerOutput = new TagHelperOutput("div", attributeList, (useCachedResult, encoder) => Task.Run(() => new DefaultTagHelperContent()))
+            {
+                TagMode = TagMode.SelfClosing
+            };
+
+            var innerContext = new TagHelperContext(attributeList, new Dictionary(), Guid.NewGuid().ToString());
+
+            abpTagHelper.Process(innerContext, innerOutput);
+
+            return RenderTagHelperOutput(innerOutput, htmlEncoder);
+        }
+
+        protected string RenderTagHelperOutput(TagHelperOutput output, HtmlEncoder htmlEncoder)
+        {
+            using (var writer = new StringWriter())
+            {
+                output.WriteTo(writer, htmlEncoder);
+                return writer.ToString();
+            }
+        }
     }
 }
\ No newline at end of file

From 15e5d1ddf20fb0bfb1b089b4d832777655f5cbe7 Mon Sep 17 00:00:00 2001
From: yekalkan 
Date: Thu, 26 Apr 2018 15:48:47 +0300
Subject: [PATCH 04/25] Added tagName parameter to inner html render function

---
 .../TagHelpers/AbpTagHelperService.cs                         | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs
index 38f5878cd0..f85950be37 100644
--- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs
+++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs
@@ -30,9 +30,9 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers
             return Task.CompletedTask;
         }
 
-        protected string RenderInputTagHelper(TagHelperAttributeList attributeList, AbpTagHelper abpTagHelper, HtmlEncoder htmlEncoder)
+        protected string RenderInputTagHelper(TagHelperAttributeList attributeList, AbpTagHelper abpTagHelper, HtmlEncoder htmlEncoder, string tagName = "div")
         {
-            var innerOutput = new TagHelperOutput("div", attributeList, (useCachedResult, encoder) => Task.Run(() => new DefaultTagHelperContent()))
+            var innerOutput = new TagHelperOutput(tagName, attributeList, (useCachedResult, encoder) => Task.Run(() => new DefaultTagHelperContent()))
             {
                 TagMode = TagMode.SelfClosing
             };

From 89da8b6bce43a2b561965e796ee70d9d8a781f6b Mon Sep 17 00:00:00 2001
From: yekalkan 
Date: Fri, 27 Apr 2018 11:42:26 +0300
Subject: [PATCH 05/25] Render input tag in abp-input

---
 .../TagHelpers/AbpTagHelperService.cs         | 18 +++++-
 .../Form/AbpFormGroupTagHelperService.cs      |  4 +-
 .../TagHelpers/Form/AbpInputTagHelper.cs      | 12 ++--
 .../Form/AbpInputTagHelperService.cs          | 41 +++++++++++++-
 .../Pages/Components/Forms.cshtml             | 55 ++++++++++++++-----
 .../Pages/Components/Forms.cshtml.cs          | 32 ++++++++++-
 6 files changed, 138 insertions(+), 24 deletions(-)

diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs
index f85950be37..87c01534f7 100644
--- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs
+++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs
@@ -30,7 +30,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers
             return Task.CompletedTask;
         }
 
-        protected string RenderInputTagHelper(TagHelperAttributeList attributeList, AbpTagHelper abpTagHelper, HtmlEncoder htmlEncoder, string tagName = "div")
+        protected TagHelperOutput GetInnerTagHelper(TagHelperAttributeList attributeList, TagHelper tagHelper, string tagName = "div")
         {
             var innerOutput = new TagHelperOutput(tagName, attributeList, (useCachedResult, encoder) => Task.Run(() => new DefaultTagHelperContent()))
             {
@@ -39,7 +39,21 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers
 
             var innerContext = new TagHelperContext(attributeList, new Dictionary(), Guid.NewGuid().ToString());
 
-            abpTagHelper.Process(innerContext, innerOutput);
+            tagHelper.Process(innerContext, innerOutput);
+
+            return innerOutput;
+        }
+
+        protected string RenderTagHelper(TagHelperAttributeList attributeList, TagHelper tagHelper, HtmlEncoder htmlEncoder, string tagName = "div")
+        {
+            var innerOutput = new TagHelperOutput(tagName, attributeList, (useCachedResult, encoder) => Task.Run(() => new DefaultTagHelperContent()))
+            {
+                TagMode = TagMode.SelfClosing
+            };
+
+            var innerContext = new TagHelperContext(attributeList, new Dictionary(), Guid.NewGuid().ToString());
+
+            tagHelper.Process(innerContext, innerOutput);
 
             return RenderTagHelperOutput(innerOutput, htmlEncoder);
         }
diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs
index 6f8b230c6d..fed6ccb684 100644
--- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs
+++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs
@@ -35,8 +35,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
             //    {"Type", "Text"},
             //    {"Placeholder", "plcHlder"}
             //};
-            
-            //output.Content.AppendHtml(RenderInputTagHelper(attributes, _abpInputTagHelper, _htmlEncoder));
+
+            //output.Content.AppendHtml(RenderTagHelper(attributes, _abpInputTagHelper, _htmlEncoder));
 
         }
 
diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs
index 7b9e823b29..66915777de 100644
--- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs
+++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs
@@ -1,13 +1,17 @@
-using Microsoft.AspNetCore.Razor.TagHelpers;
-
-
-using JetBrains.Annotations;
+using Microsoft.AspNetCore.Mvc.Rendering;
+using Microsoft.AspNetCore.Mvc.ViewFeatures;
+using Microsoft.AspNetCore.Razor.TagHelpers;
 using Volo.Abp.DependencyInjection;
 
 namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
 {
     public class AbpInputTagHelper : AbpTagHelper, ITransientDependency
     {
+        public ModelExpression AspFor { get; set; }
+
+        [HtmlAttributeNotBound]
+        [ViewContext]
+        public ViewContext ViewContext { get; set; }
 
         public AbpInputTagHelper(AbpInputTagHelperService tagHelperService)
             : base(tagHelperService)
diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs
index 357543793c..d5a726ffe3 100644
--- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs
+++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs
@@ -1,5 +1,9 @@
 using System.Text;
+using System.Text.Encodings.Web;
 using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc.Rendering;
+using Microsoft.AspNetCore.Mvc.TagHelpers;
+using Microsoft.AspNetCore.Mvc.ViewFeatures;
 using Microsoft.AspNetCore.Razor.TagHelpers;
 using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers;
 
@@ -7,11 +11,44 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
 {
     public class AbpInputTagHelperService : AbpTagHelperService
     {
+        private readonly HtmlEncoder _htmlEncoder;
+        private readonly IHtmlGenerator _generator;
+
+        public AbpInputTagHelperService(HtmlEncoder htmlEncoder, IHtmlGenerator generator)
+        {
+            _htmlEncoder = htmlEncoder;
+            _generator = generator;
+        }
+
         public override void Process(TagHelperContext context, TagHelperOutput output)
         {
             output.TagName = "input";
-            output.Attributes.AddClass("form-control");
-            output.TagMode = TagMode.SelfClosing;
+
+            ProcessAttributes(output);
+        }
+
+        protected virtual void ProcessAttributes(TagHelperOutput output)
+        {
+            var inputTagHelperOutput = GetAttributes();
+
+            foreach (var tagHelperAttribute in inputTagHelperOutput.Attributes)
+            {
+                output.Attributes.Add(tagHelperAttribute);
+            }
+
+            output.Attributes.RemoveAll("asp-for");
+            output.Attributes.Add("class", "form-control");
+        }
+
+        protected virtual TagHelperOutput GetAttributes()
+        {
+            var inputTagHelper = new InputTagHelper(_generator)
+            {
+                For = TagHelper.AspFor,
+                ViewContext = TagHelper.ViewContext
+            };
+
+            return GetInnerTagHelper(new TagHelperAttributeList(), inputTagHelper);
         }
     }
 }
\ No newline at end of file
diff --git a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml
index 5f34a0ebf1..748f01f983 100644
--- a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml
+++ b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml
@@ -12,24 +12,53 @@
 
 
- - - - - - - +
+ + + + + + + + + + + + + + + + + + + + + +
       
         <abp-form-group>
-            <abp-input type="text"/>
+            <abp-input asp-for="@Model.Name" />
         </abp-form-group>
-        <abp-form-group checkbox="true">
-            <input type="checkbox" class="form-check-input" id="exampleCheck1">
-            <label class="form-check-label" for="exampleCheck1">Check me out</label>
+        <abp-form-group>
+            <abp-input asp-for="@Model.Password" />
+        </abp-form-group>
+        <abp-form-group>
+            <abp-input asp-for="@Model.PhoneNumber" />
+        </abp-form-group>
+        <abp-form-group>
+            <abp-input asp-for="@Model.EmailAddress" />
+        </abp-form-group>
+        <abp-form-group>
+            <abp-input asp-for="@Model.Count" />
+        </abp-form-group>
+        <abp-form-group>
+            <abp-input asp-for="@Model.Day" />
+        </abp-form-group>
+        <abp-form-group>
+            <abp-input asp-for="@Model.IsActive" />
         </abp-form-group>
         
-
- +
\ No newline at end of file diff --git a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs index ab186db51a..fcc8347a99 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs +++ b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs @@ -1,9 +1,39 @@ -using Microsoft.AspNetCore.Mvc.RazorPages; +using System; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Mvc.RazorPages; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components { public class FormsModel : PageModel { + [Required] + [DisplayName("Name")] + public string Name = "MyName"; + + [Required] + [EmailAddress] + [DisplayName("Email")] + public string EmailAddress = "info@volosoft.com"; + + [DisplayName("Password")] + [DataType(DataType.Password)] + public string Password = "MyPass"; + + [Phone] + [DisplayName("Phone Number")] + public string PhoneNumber = "05069231382"; + + [DisplayName("Count")] + public int Count = 42; + + [DataType(DataType.Date)] + [DisplayName("Day")] + public DateTime Day = DateTime.Today; + + [DisplayName("Is Active")] + public bool IsActive = true; + public void OnGet() { From 8d2c68837eaf3c775f72d20ee13c825c03d2c2ca Mon Sep 17 00:00:00 2001 From: yekalkan Date: Fri, 27 Apr 2018 14:14:19 +0300 Subject: [PATCH 06/25] Select Tag Helper --- .../TagHelpers/AbpTagHelperService.cs | 8 +-- .../Form/AbpInputTagHelperService.cs | 14 ++--- .../TagHelpers/Form/AbpSelectTagHelper.cs | 25 ++++++++ .../Form/AbpSelectTagHelperService.cs | 45 +++++++++++++++ .../Pages/Components/Forms.cshtml | 57 ++++++++++++------- .../Pages/Components/Forms.cshtml.cs | 40 ++++++++++--- 6 files changed, 149 insertions(+), 40 deletions(-) create mode 100644 src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs create mode 100644 src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs index 87c01534f7..9569468bd2 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs @@ -30,11 +30,11 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers return Task.CompletedTask; } - protected TagHelperOutput GetInnerTagHelper(TagHelperAttributeList attributeList, TagHelper tagHelper, string tagName = "div") + protected TagHelperOutput GetInnerTagHelper(TagHelperAttributeList attributeList, TagHelper tagHelper, string tagName = "div", TagMode tagMode = TagMode.SelfClosing) { var innerOutput = new TagHelperOutput(tagName, attributeList, (useCachedResult, encoder) => Task.Run(() => new DefaultTagHelperContent())) { - TagMode = TagMode.SelfClosing + TagMode = tagMode }; var innerContext = new TagHelperContext(attributeList, new Dictionary(), Guid.NewGuid().ToString()); @@ -44,11 +44,11 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers return innerOutput; } - protected string RenderTagHelper(TagHelperAttributeList attributeList, TagHelper tagHelper, HtmlEncoder htmlEncoder, string tagName = "div") + protected string RenderTagHelper(TagHelperAttributeList attributeList, TagHelper tagHelper, HtmlEncoder htmlEncoder, string tagName = "div", TagMode tagMode = TagMode.SelfClosing) { var innerOutput = new TagHelperOutput(tagName, attributeList, (useCachedResult, encoder) => Task.Run(() => new DefaultTagHelperContent())) { - TagMode = TagMode.SelfClosing + TagMode = tagMode }; var innerContext = new TagHelperContext(attributeList, new Dictionary(), Guid.NewGuid().ToString()); diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs index d5a726ffe3..6a0c161ae2 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs @@ -1,4 +1,5 @@ -using System.Text; +using System.Linq; +using System.Text; using System.Text.Encodings.Web; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Rendering; @@ -11,12 +12,10 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { public class AbpInputTagHelperService : AbpTagHelperService { - private readonly HtmlEncoder _htmlEncoder; private readonly IHtmlGenerator _generator; - public AbpInputTagHelperService(HtmlEncoder htmlEncoder, IHtmlGenerator generator) + public AbpInputTagHelperService(IHtmlGenerator generator) { - _htmlEncoder = htmlEncoder; _generator = generator; } @@ -29,18 +28,19 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form protected virtual void ProcessAttributes(TagHelperOutput output) { - var inputTagHelperOutput = GetAttributes(); + output.Attributes.RemoveAll("asp-for"); + + var inputTagHelperOutput = GetAttributes(output); foreach (var tagHelperAttribute in inputTagHelperOutput.Attributes) { output.Attributes.Add(tagHelperAttribute); } - output.Attributes.RemoveAll("asp-for"); output.Attributes.Add("class", "form-control"); } - protected virtual TagHelperOutput GetAttributes() + protected virtual TagHelperOutput GetAttributes(TagHelperOutput output) { var inputTagHelper = new InputTagHelper(_generator) { diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs new file mode 100644 index 0000000000..a7285aa233 --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.AspNetCore.Mvc.ViewFeatures; +using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form +{ + public class AbpSelectTagHelper : AbpTagHelper, ITransientDependency + { + public ModelExpression AspFor { get; set; } + + public IEnumerable AspItems { get; set; } + + [HtmlAttributeNotBound] + [ViewContext] + public ViewContext ViewContext { get; set; } + + public AbpSelectTagHelper(AbpSelectTagHelperService tagHelperService) + : base(tagHelperService) + { + + } + } +} diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs new file mode 100644 index 0000000000..b132d77e75 --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs @@ -0,0 +1,45 @@ +using System.Text; +using System.Text.Encodings.Web; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.AspNetCore.Mvc.TagHelpers; +using Microsoft.AspNetCore.Mvc.ViewFeatures; +using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form +{ + public class AbpSelectTagHelperService : AbpTagHelperService + { + private readonly IHtmlGenerator _generator; + private readonly HtmlEncoder _encoder; + + public AbpSelectTagHelperService(IHtmlGenerator generator, HtmlEncoder encoder) + { + _generator = generator; + _encoder = encoder; + } + + public override void Process(TagHelperContext context, TagHelperOutput output) + { + output.TagName = "div"; + output.Attributes.Add("class", "form-control"); + output.TagMode = TagMode.StartTagAndEndTag; + + output.Content.SetHtmlContent(GetInnerHtml(output)); + output.Attributes.Clear(); + } + + protected virtual string GetInnerHtml(TagHelperOutput output) + { + var selectTagHelper = new SelectTagHelper(_generator) + { + For = TagHelper.AspFor, + Items = TagHelper.AspItems, + ViewContext = TagHelper.ViewContext + }; + + return RenderTagHelper(output.Attributes, selectTagHelper, _encoder, "select", TagMode.StartTagAndEndTag); + } + } +} \ No newline at end of file diff --git a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml index 748f01f983..8df0e4440a 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml +++ b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml @@ -1,4 +1,5 @@ @page +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components @model Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components.FormsModel @{ ViewData["Title"] = "Forms"; @@ -13,6 +14,12 @@
+ + + + + + @@ -38,27 +45,35 @@
       
-        <abp-form-group>
-            <abp-input asp-for="@Model.Name" />
-        </abp-form-group>
-        <abp-form-group>
-            <abp-input asp-for="@Model.Password" />
-        </abp-form-group>
-        <abp-form-group>
-            <abp-input asp-for="@Model.PhoneNumber" />
-        </abp-form-group>
-        <abp-form-group>
-            <abp-input asp-for="@Model.EmailAddress" />
-        </abp-form-group>
-        <abp-form-group>
-            <abp-input asp-for="@Model.Count" />
-        </abp-form-group>
-        <abp-form-group>
-            <abp-input asp-for="@Model.Day" />
-        </abp-form-group>
-        <abp-form-group>
-            <abp-input asp-for="@Model.IsActive" />
-        </abp-form-group>
+        <form method="post" action="#">
+            <abp-form-group>
+                <abp-select asp-for="@Model.Country" asp-items="@Model.Countries"></abp-select>
+            </abp-form-group>
+            <abp-form-group>
+                <abp-select asp-for="@Model.City" asp-items="@Html.GetEnumSelectList(typeof(Cities))"></abp-select>
+            </abp-form-group>
+            <abp-form-group>
+                <abp-input asp-for="@Model.Name" />
+            </abp-form-group>
+            <abp-form-group>
+                <abp-input asp-for="@Model.Password" />
+            </abp-form-group>
+            <abp-form-group>
+                <abp-input asp-for="@Model.PhoneNumber" />
+            </abp-form-group>
+            <abp-form-group>
+                <abp-input asp-for="@Model.EmailAddress" />
+            </abp-form-group>
+            <abp-form-group>
+                <abp-input asp-for="@Model.Count" />
+            </abp-form-group>
+            <abp-form-group>
+                <abp-input asp-for="@Model.Day" />
+            </abp-form-group>
+            <abp-form-group>
+                <abp-input asp-for="@Model.IsActive" />
+            </abp-form-group>
+        </form>
         
\ No newline at end of file diff --git a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs index fcc8347a99..675f4a5839 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs +++ b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs @@ -1,7 +1,10 @@ using System; +using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.AspNetCore.Mvc.ViewFeatures; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components { @@ -9,34 +12,55 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components { [Required] [DisplayName("Name")] - public string Name = "MyName"; + public string Name { get; set; } [Required] [EmailAddress] [DisplayName("Email")] - public string EmailAddress = "info@volosoft.com"; + public string EmailAddress { get; set; } - [DisplayName("Password")] [DataType(DataType.Password)] - public string Password = "MyPass"; + public string Password { get; set; } = "MyPass"; [Phone] [DisplayName("Phone Number")] - public string PhoneNumber = "05069231382"; + public string PhoneNumber { get; set; } [DisplayName("Count")] - public int Count = 42; + public int Count { get; set; } [DataType(DataType.Date)] [DisplayName("Day")] - public DateTime Day = DateTime.Today; + public DateTime Day { get; set; } [DisplayName("Is Active")] - public bool IsActive = true; + public bool IsActive { get; set; } + + [DisplayName("Country")] + public string Country { get; set; } + + [DisplayName("City")] + public Cities City { get; set; } + + public List Countries { get; } = new List + { + new SelectListItem { Value = "MX", Text = "Mexico" }, + new SelectListItem { Value = "CA", Text = "Canada" }, + new SelectListItem { Value = "US", Text = "USA" }, + }; public void OnGet() { + Name = "MyName"; + Day = DateTime.Today; } } + + public enum Cities + { + Istanbul, + NewJersey, + Moscow + } } \ No newline at end of file From d1441e052abfd79fd84c6dc5f2b7fbdafc66bbfe Mon Sep 17 00:00:00 2001 From: yekalkan Date: Fri, 27 Apr 2018 15:57:23 +0300 Subject: [PATCH 07/25] Input tag re-designed & select tag label --- .../TagHelpers/Form/AbpInputTagHelper.cs | 2 + .../Form/AbpInputTagHelperService.cs | 83 +++++++++-- .../TagHelpers/Form/AbpSelectTagHelper.cs | 2 + .../Form/AbpSelectTagHelperService.cs | 64 +++++++- .../Pages/Components/Forms.cshtml | 141 +++++++++++------- 5 files changed, 214 insertions(+), 78 deletions(-) diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs index 66915777de..a2f157be30 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs @@ -9,6 +9,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { public ModelExpression AspFor { get; set; } + public string Label { get; set; } + [HtmlAttributeNotBound] [ViewContext] public ViewContext ViewContext { get; set; } diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs index 6a0c161ae2..3f9cc6e523 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs @@ -1,11 +1,14 @@ -using System.Linq; +using System; +using System.Linq; using System.Text; using System.Text.Encodings.Web; using System.Threading.Tasks; +using Localization.Resources.AbpUi; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.TagHelpers; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Razor.TagHelpers; +using Microsoft.Extensions.Localization; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form @@ -13,34 +16,44 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form public class AbpInputTagHelperService : AbpTagHelperService { private readonly IHtmlGenerator _generator; + private readonly HtmlEncoder _encoder; + private readonly IStringLocalizer _localizer; - public AbpInputTagHelperService(IHtmlGenerator generator) + public AbpInputTagHelperService(IHtmlGenerator generator, HtmlEncoder encoder, IStringLocalizer localizer) { _generator = generator; + _encoder = encoder; + _localizer = localizer; } public override void Process(TagHelperContext context, TagHelperOutput output) { - output.TagName = "input"; + output.TagName = "div"; + output.TagMode = TagMode.StartTagAndEndTag; + + var inputTag = GetInputTag(); + var inputHtml = RenderTagHelperOutput(inputTag, _encoder); + var isCheckbox = IsInputCheckbox(inputTag.Attributes); - ProcessAttributes(output); - } + var label = GetLabelAsHtml(inputTag, isCheckbox); - protected virtual void ProcessAttributes(TagHelperOutput output) - { - output.Attributes.RemoveAll("asp-for"); + var content = isCheckbox ? + inputHtml + Environment.NewLine + label : + label + Environment.NewLine + inputHtml; - var inputTagHelperOutput = GetAttributes(output); + output.Content.SetHtmlContent(content); - foreach (var tagHelperAttribute in inputTagHelperOutput.Attributes) - { - output.Attributes.Add(tagHelperAttribute); - } + SetDivAttributes(output, isCheckbox); + } + + protected virtual void SetDivAttributes(TagHelperOutput output, bool isCheckbox) + { + output.Attributes.RemoveAll("asp-for"); - output.Attributes.Add("class", "form-control"); + output.Attributes.Add("class", isCheckbox ? " form-check" : "form-group"); } - protected virtual TagHelperOutput GetAttributes(TagHelperOutput output) + protected virtual TagHelperOutput GetInputTag() { var inputTagHelper = new InputTagHelper(_generator) { @@ -48,7 +61,45 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form ViewContext = TagHelper.ViewContext }; - return GetInnerTagHelper(new TagHelperAttributeList(), inputTagHelper); + var inputTagHelperOutput = GetInnerTagHelper(new TagHelperAttributeList(), inputTagHelper, "input"); ; + + inputTagHelperOutput.Attributes.Add("class", + IsInputCheckbox(inputTagHelperOutput.Attributes) ? "form-check-input" : "form-control"); + + return inputTagHelperOutput; + } + + protected virtual bool IsInputCheckbox(TagHelperAttributeList attributes) + { + return attributes.Any(a => a.Value != null && a.Name == "type" && a.Value.ToString() == "checkbox"); + } + + protected virtual string GetLabelAsHtml(TagHelperOutput inputTag, bool isCheckbox) + { + if (string.IsNullOrEmpty(TagHelper.Label) && string.IsNullOrEmpty(TagHelper.AspFor.Metadata.DisplayName)) + { + return ""; + } + + var label = GetLabelText(); + var idAttr = inputTag.Attributes.FirstOrDefault(a => a.Name == "id"); + var idAttrAsString = ""; + + if (idAttr != null) + { + idAttrAsString = "for=\"" + idAttr.Value + "\""; + } + + var checkboxClass = isCheckbox ? "class=\"form-check-label\" " : ""; + + return ""; + } + + protected virtual string GetLabelText() + { + return string.IsNullOrEmpty(TagHelper.Label) ? + TagHelper.AspFor.Metadata.DisplayName : + TagHelper.Label; } } } \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs index a7285aa233..cf2786e726 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs @@ -10,6 +10,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { public ModelExpression AspFor { get; set; } + public string Label { get; set; } + public IEnumerable AspItems { get; set; } [HtmlAttributeNotBound] diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs index b132d77e75..62ec7d819f 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs @@ -1,10 +1,14 @@ -using System.Text; +using System; +using System.Linq; +using System.Text; using System.Text.Encodings.Web; using System.Threading.Tasks; +using Localization.Resources.AbpUi; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.TagHelpers; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Razor.TagHelpers; +using Microsoft.Extensions.Localization; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form @@ -13,24 +17,38 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { private readonly IHtmlGenerator _generator; private readonly HtmlEncoder _encoder; + private readonly IStringLocalizer _localizer; - public AbpSelectTagHelperService(IHtmlGenerator generator, HtmlEncoder encoder) + public AbpSelectTagHelperService(IHtmlGenerator generator, HtmlEncoder encoder, IStringLocalizer localizer) { _generator = generator; _encoder = encoder; + _localizer = localizer; } public override void Process(TagHelperContext context, TagHelperOutput output) { output.TagName = "div"; - output.Attributes.Add("class", "form-control"); + SetDivAttributes(output); output.TagMode = TagMode.StartTagAndEndTag; - output.Content.SetHtmlContent(GetInnerHtml(output)); - output.Attributes.Clear(); + var selectTag = GetSelectTag(); + + var seelctAsHtml = RenderTagHelperOutput(selectTag, _encoder); + var labelAsHtml = GetLabelAsHtml(selectTag); + var content = labelAsHtml + Environment.NewLine + seelctAsHtml; + + output.Content.SetHtmlContent(content); + } + + protected virtual void SetDivAttributes(TagHelperOutput output) + { + output.Attributes.RemoveAll("asp-for"); + output.Attributes.RemoveAll("asp-items"); + output.Attributes.Add("class", "form-group"); } - protected virtual string GetInnerHtml(TagHelperOutput output) + protected virtual TagHelperOutput GetSelectTag() { var selectTagHelper = new SelectTagHelper(_generator) { @@ -39,7 +57,39 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form ViewContext = TagHelper.ViewContext }; - return RenderTagHelper(output.Attributes, selectTagHelper, _encoder, "select", TagMode.StartTagAndEndTag); + var attributes = new TagHelperAttributeList { new TagHelperAttribute("class", "form-control") }; + var inputTagHelperOutput = GetInnerTagHelper(attributes, selectTagHelper, "select", TagMode.StartTagAndEndTag); ; + + inputTagHelperOutput.Attributes.Add("class", "form-control"); + + return inputTagHelperOutput; + } + + + protected virtual string GetLabelAsHtml(TagHelperOutput selectTag) + { + if (string.IsNullOrEmpty(TagHelper.Label) && string.IsNullOrEmpty(TagHelper.AspFor.Metadata.DisplayName)) + { + return ""; + } + + var label = GetLabelText(); + var idAttr = selectTag.Attributes.FirstOrDefault(a => a.Name == "id"); + var idAttrAsString = ""; + + if (idAttr != null) + { + idAttrAsString = "for=\"" + idAttr.Value + "\""; + } + + return ""; + } + + protected virtual string GetLabelText() + { + return string.IsNullOrEmpty(TagHelper.Label) ? + TagHelper.AspFor.Metadata.DisplayName : + TagHelper.Label; } } } \ No newline at end of file diff --git a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml index 8df0e4440a..4db1d3782a 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml +++ b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml @@ -14,66 +14,97 @@
- - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + +
       
         <form method="post" action="#">
-            <abp-form-group>
-                <abp-select asp-for="@Model.Country" asp-items="@Model.Countries"></abp-select>
-            </abp-form-group>
-            <abp-form-group>
-                <abp-select asp-for="@Model.City" asp-items="@Html.GetEnumSelectList(typeof(Cities))"></abp-select>
-            </abp-form-group>
-            <abp-form-group>
-                <abp-input asp-for="@Model.Name" />
-            </abp-form-group>
-            <abp-form-group>
-                <abp-input asp-for="@Model.Password" />
-            </abp-form-group>
-            <abp-form-group>
-                <abp-input asp-for="@Model.PhoneNumber" />
-            </abp-form-group>
-            <abp-form-group>
-                <abp-input asp-for="@Model.EmailAddress" />
-            </abp-form-group>
-            <abp-form-group>
-                <abp-input asp-for="@Model.Count" />
-            </abp-form-group>
-            <abp-form-group>
-                <abp-input asp-for="@Model.Day" />
-            </abp-form-group>
-            <abp-form-group>
-                <abp-input asp-for="@Model.IsActive" />
-            </abp-form-group>
+            <abp-input asp-for="Model.Name"/>
+            <abp-input asp-for="Model.Password" label="Password"/>
+            <abp-input asp-for="Model.IsActive" />
+            <abp-input asp-for="Model.PhoneNumber" />
+            <abp-input asp-for="Model.EmailAddress" />
+            <abp-input asp-for="Model.Count" />
+            <abp-input asp-for="Model.Day" />
+            <abp-select asp-for="Model.Country" asp-items="Model.Countries" label="Country"></abp-select>
+            <abp-select asp-for="Model.City" asp-items="Html.GetEnumSelectList(typeof(Cities))"></abp-select>
         </form>
         
-
\ No newline at end of file +
+ +@*
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+            <form method="post" action="#">
+                <abp-form-group>
+                    <abp-select asp-for="@Model.Country" asp-items="@Model.Countries"></abp-select>
+                </abp-form-group>
+                <abp-form-group>
+                    <abp-select asp-for="@Model.City" asp-items="@Html.GetEnumSelectList(typeof(Cities))"></abp-select>
+                </abp-form-group>
+                <abp-form-group>
+                    <abp-input asp-for="@Model.Name" />
+                </abp-form-group>
+                <abp-form-group>
+                    <abp-input asp-for="@Model.Password" />
+                </abp-form-group>
+                <abp-form-group>
+                    <abp-input asp-for="@Model.PhoneNumber" />
+                </abp-form-group>
+                <abp-form-group>
+                    <abp-input asp-for="@Model.EmailAddress" />
+                </abp-form-group>
+                <abp-form-group>
+                    <abp-input asp-for="@Model.Count" />
+                </abp-form-group>
+                <abp-form-group>
+                    <abp-input asp-for="@Model.Day" />
+                </abp-form-group>
+                <abp-form-group>
+                    <abp-input asp-for="@Model.IsActive" />
+                </abp-form-group>
+            </form>
+            
+
+
*@ \ No newline at end of file From 0930fd6e13209b7f3004ffd43cc4aadc1290123a Mon Sep 17 00:00:00 2001 From: yekalkan Date: Fri, 27 Apr 2018 16:13:16 +0300 Subject: [PATCH 08/25] Removed redundant using statements --- .../TagHelpers/Form/AbpSelectTagHelperService.cs | 4 ---- .../TagHelpers/Grid/AbpColBreakTagHelperService.cs | 4 +--- .../TagHelpers/Grid/AbpColumnTagHelperService.cs | 4 +--- .../TagHelpers/Grid/AbpContainerTagHelperService.cs | 3 +-- .../TagHelpers/Grid/AbpRowTagHelperService.cs | 4 +--- .../TagHelpers/Label/AbpLabelTagHelperService.cs | 3 +-- 6 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs index 62ec7d819f..316a141e8b 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs @@ -1,15 +1,11 @@ using System; using System.Linq; -using System.Text; using System.Text.Encodings.Web; -using System.Threading.Tasks; using Localization.Resources.AbpUi; -using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.TagHelpers; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Razor.TagHelpers; using Microsoft.Extensions.Localization; -using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColBreakTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColBreakTagHelperService.cs index f414d7682d..ccbb4e638a 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColBreakTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColBreakTagHelperService.cs @@ -1,6 +1,4 @@ -using System; -using System.Text; -using Microsoft.AspNetCore.Razor.TagHelpers; +using Microsoft.AspNetCore.Razor.TagHelpers; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColumnTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColumnTagHelperService.cs index 82aa86fcd5..b095a8a0a0 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColumnTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColumnTagHelperService.cs @@ -1,6 +1,4 @@ -using System; -using System.Text; -using Microsoft.AspNetCore.Razor.TagHelpers; +using Microsoft.AspNetCore.Razor.TagHelpers; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpContainerTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpContainerTagHelperService.cs index 0c2c429907..75650f7e13 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpContainerTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpContainerTagHelperService.cs @@ -1,5 +1,4 @@ -using System.Text; -using Microsoft.AspNetCore.Razor.TagHelpers; +using Microsoft.AspNetCore.Razor.TagHelpers; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpRowTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpRowTagHelperService.cs index 53b7588764..437e608e55 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpRowTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpRowTagHelperService.cs @@ -1,6 +1,4 @@ -using System.ComponentModel; -using System.Text; -using Microsoft.AspNetCore.Razor.TagHelpers; +using Microsoft.AspNetCore.Razor.TagHelpers; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Label/AbpLabelTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Label/AbpLabelTagHelperService.cs index 45bafc780b..24a094732a 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Label/AbpLabelTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Label/AbpLabelTagHelperService.cs @@ -1,5 +1,4 @@ -using System.Text; -using Microsoft.AspNetCore.Razor.TagHelpers; +using Microsoft.AspNetCore.Razor.TagHelpers; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Label { From 9ca4e3246277ff43ee88aeef9436ae935a992ca2 Mon Sep 17 00:00:00 2001 From: yekalkan Date: Fri, 27 Apr 2018 17:45:56 +0300 Subject: [PATCH 09/25] Form tag helper (in proggress) --- .../Form/AbpDynamicformTagHelper.cs | 16 ++++++++++ .../Form/AbpDynamicformTagHelperService.cs | 32 +++++++++++++++++++ .../Form/AbpFormGroupTagHelperService.cs | 10 ------ .../Pages/Components/Forms.cshtml | 13 ++++++++ .../Pages/Components/Forms.cshtml.cs | 19 +++++++++++ 5 files changed, 80 insertions(+), 10 deletions(-) create mode 100644 src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelper.cs create mode 100644 src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelper.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelper.cs new file mode 100644 index 0000000000..e09daf87a1 --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelper.cs @@ -0,0 +1,16 @@ +using JetBrains.Annotations; +using Microsoft.AspNetCore.Mvc.ViewFeatures; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form +{ + public class AbpDynamicFormTagHelper : AbpTagHelper + { + public ModelExpression Model { get; set; } + + public AbpDynamicFormTagHelper(AbpDynamicFormTagHelperService tagHelperService) + : base(tagHelperService) + { + + } + } +} diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs new file mode 100644 index 0000000000..584f342abc --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Text.Encodings.Web; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form +{ + public class AbpDynamicFormTagHelperService : AbpTagHelperService + { + private readonly HtmlEncoder _htmlEncoder; + private readonly AbpInputTagHelper _abpInputTagHelper; + private readonly AbpSelectTagHelper _abpSelectTagHelper; + + public AbpDynamicFormTagHelperService(HtmlEncoder htmlEncoder, AbpInputTagHelper abpInputTagHelper, AbpSelectTagHelper abpSelectTagHelper) + { + _htmlEncoder = htmlEncoder; + _abpInputTagHelper = abpInputTagHelper; + _abpSelectTagHelper = abpSelectTagHelper; + } + + public override void Process(TagHelperContext context, TagHelperOutput output) + { + var model = TagHelper.Model; + + } + + } +} \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs index fed6ccb684..96b176f994 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs @@ -28,16 +28,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { output.Attributes.AddClass("form-check"); } - - - //var attributes = new TagHelperAttributeList - //{ - // {"Type", "Text"}, - // {"Placeholder", "plcHlder"} - //}; - - //output.Content.AppendHtml(RenderTagHelper(attributes, _abpInputTagHelper, _htmlEncoder)); - } } diff --git a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml index 4db1d3782a..e8bd5cdaf7 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml +++ b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml @@ -11,6 +11,19 @@

# Example

+
+
+ + + +
+
+
       
+        <abp-dynamic-form model="Model.Person" >
+        </form>
+        
+
+
diff --git a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs index 675f4a5839..713619eb1e 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs +++ b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs @@ -42,6 +42,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components [DisplayName("City")] public Cities City { get; set; } + public Person Person { get; set; } + public List Countries { get; } = new List { new SelectListItem { Value = "MX", Text = "Mexico" }, @@ -63,4 +65,21 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components NewJersey, Moscow } + + public class Person + { + public string Name { get; set; } + + public int Age { get; set; } + + public Cities City { get; set; } + + public Phone Phone { get; set; } + } + + public class Phone + { + public string Number { get; set; } + public string Name { get; set; } + } } \ No newline at end of file From 0c36f77c4fa1ecb8e2aab5449ef5a661be3dedb1 Mon Sep 17 00:00:00 2001 From: yekalkan Date: Mon, 30 Apr 2018 10:23:11 +0300 Subject: [PATCH 10/25] Form create from single model (Basic func.) --- .../Form/AbpDynamicformTagHelper.cs | 7 ++ .../Form/AbpDynamicformTagHelperService.cs | 66 ++++++++++++++++++- .../Pages/Components/Forms.cshtml | 10 ++- .../Pages/Components/Forms.cshtml.cs | 12 +++- 4 files changed, 90 insertions(+), 5 deletions(-) diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelper.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelper.cs index e09daf87a1..4dc417967f 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelper.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelper.cs @@ -1,5 +1,7 @@ using JetBrains.Annotations; +using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.ViewFeatures; +using Microsoft.AspNetCore.Razor.TagHelpers; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { @@ -7,6 +9,11 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { public ModelExpression Model { get; set; } + + [HtmlAttributeNotBound] + [ViewContext] + public ViewContext ViewContext { get; set; } + public AbpDynamicFormTagHelper(AbpDynamicFormTagHelperService tagHelperService) : base(tagHelperService) { diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs index 584f342abc..9a043d8a06 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Text; using System.Text.Encodings.Web; using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Razor.TagHelpers; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; @@ -24,9 +26,71 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form public override void Process(TagHelperContext context, TagHelperOutput output) { - var model = TagHelper.Model; + output.TagName = "form"; + output.Attributes.Add("method","post"); + output.Attributes.Add("action","#"); + var innerhtml = GetInnerHtmlContent(); + + output.PreContent.SetHtmlContent(innerhtml); + } + + protected virtual string GetInnerHtmlContent() + { + var innerHtmlcontent = ""; + var models = ExploreModelsRecursively(new List(), TagHelper.Model.ModelExplorer); + + foreach (var model in models) + { + innerHtmlcontent += ProcessField(model); + } + + return innerHtmlcontent; + } + + protected virtual string ProcessField(ModelExpression model) + { + _abpInputTagHelper.AspFor = model; + _abpInputTagHelper.Label = ""; + _abpInputTagHelper.ViewContext = TagHelper.ViewContext; + + return RenderTagHelper(new TagHelperAttributeList(), _abpInputTagHelper,_htmlEncoder,"div",TagMode.StartTagAndEndTag) + + Environment.NewLine; } + protected virtual List ExploreModelsRecursively(List list, ModelExplorer model) + { + if (IsCsharpClassOrPrimitive(model.ModelType)) + { + list.Add(ModelExplorerToModelExpressionConverter(model)); + return list; + } + + return model.Properties.Aggregate(list, ExploreModelsRecursively); + } + + protected virtual ModelExpression ModelExplorerToModelExpressionConverter(ModelExplorer explorer) + { + return new ModelExpression(explorer.Metadata.PropertyName, explorer); + } + + protected virtual bool IsCsharpClassOrPrimitive(Type type) + { + return type.IsPrimitive || + type.IsValueType || + type == typeof(DateTime) || + type == typeof(ValueType) || + type == typeof(String) || + type == typeof(Decimal) || + type == typeof(Double) || + type == typeof(Guid) || + type == typeof(TimeSpan) || + type == typeof(DateTimeOffset) || + type == typeof(Single) || + type == typeof(Int16) || + type == typeof(Int32) || + type == typeof(Int64) || + type.IsEnum; + } } } \ No newline at end of file diff --git a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml index e8bd5cdaf7..9135ed047d 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml +++ b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml @@ -9,7 +9,7 @@

Based on Bootstrap form.

-

# Example

+

# Dynamic Form Example

@@ -24,11 +24,15 @@
+ + +

# Input Group Example

+
- - + + diff --git a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs index 713619eb1e..20301a221c 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs +++ b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs @@ -51,11 +51,14 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components new SelectListItem { Value = "US", Text = "USA" }, }; + public static IEnumerable EnumCityList; + public void OnGet() { Name = "MyName"; Day = DateTime.Today; - + //var htmlHelper = new HtmlHelper(); + //EnumCityList = htmlHelper.GetEnumSelectList(typeof(Cities)); } } @@ -75,6 +78,13 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components public Cities City { get; set; } public Phone Phone { get; set; } + + [DataType(DataType.Date)] + [DisplayName("Day")] + public DateTime Day { get; set; } + + [DisplayName("Is Active")] + public bool IsActive { get; set; } } public class Phone From c6fb606c9a60ef2cc5d4a93272ba2981825847dd Mon Sep 17 00:00:00 2001 From: yekalkan Date: Mon, 30 Apr 2018 10:24:39 +0300 Subject: [PATCH 11/25] Remove Redundant Using statements --- .../TagHelpers/Form/AbpDynamicformTagHelper.cs | 3 +-- .../TagHelpers/Form/AbpDynamicformTagHelperService.cs | 4 ---- .../TagHelpers/Form/AbpFormGroupTagHelper.cs | 4 +--- .../TagHelpers/Form/AbpFormGroupTagHelperService.cs | 7 +------ .../TagHelpers/Form/AbpInputTagHelperService.cs | 4 ---- .../TagHelpers/Grid/AbpColBreakTagHelper.cs | 4 +--- 6 files changed, 4 insertions(+), 22 deletions(-) diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelper.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelper.cs index 4dc417967f..4ff93159c0 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelper.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelper.cs @@ -1,5 +1,4 @@ -using JetBrains.Annotations; -using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Razor.TagHelpers; diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs index 9a043d8a06..5ba7707689 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs @@ -1,13 +1,9 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; -using System.Text; using System.Text.Encodings.Web; -using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Razor.TagHelpers; -using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelper.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelper.cs index 300ed7a4c3..0634a28eb5 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelper.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelper.cs @@ -1,6 +1,4 @@ -using JetBrains.Annotations; - -namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { public class AbpFormGroupTagHelper : AbpTagHelper { diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs index 96b176f994..2a5e251766 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Text.Encodings.Web; -using System.Threading.Tasks; +using System.Text.Encodings.Web; using Microsoft.AspNetCore.Razor.TagHelpers; using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs index 3f9cc6e523..7b73eabb89 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs @@ -1,15 +1,11 @@ using System; using System.Linq; -using System.Text; using System.Text.Encodings.Web; -using System.Threading.Tasks; using Localization.Resources.AbpUi; -using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.TagHelpers; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Razor.TagHelpers; using Microsoft.Extensions.Localization; -using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColBreakTagHelper.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColBreakTagHelper.cs index 446f52e531..fdd6b973a4 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColBreakTagHelper.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColBreakTagHelper.cs @@ -1,6 +1,4 @@ -using Microsoft.AspNetCore.Razor.TagHelpers; - -namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid { public class AbpColBreakTagHelper : AbpTagHelper { From 5c629d6cd82fc129b0947ccd810acbc01ea676bc Mon Sep 17 00:00:00 2001 From: yekalkan Date: Mon, 30 Apr 2018 11:16:33 +0300 Subject: [PATCH 12/25] Removed default select helper in form tag --- .../Form/AbpDynamicformTagHelperService.cs | 16 +++++++------- .../Pages/Components/Forms.cshtml.cs | 21 +++++++++++++++++++ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs index 5ba7707689..b500253414 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text.Encodings.Web; +using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Razor.TagHelpers; @@ -11,20 +12,19 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { private readonly HtmlEncoder _htmlEncoder; private readonly AbpInputTagHelper _abpInputTagHelper; - private readonly AbpSelectTagHelper _abpSelectTagHelper; + private const string SelectItemsPostFix = "selectitems"; - public AbpDynamicFormTagHelperService(HtmlEncoder htmlEncoder, AbpInputTagHelper abpInputTagHelper, AbpSelectTagHelper abpSelectTagHelper) + public AbpDynamicFormTagHelperService(HtmlEncoder htmlEncoder, AbpInputTagHelper abpInputTagHelper) { _htmlEncoder = htmlEncoder; _abpInputTagHelper = abpInputTagHelper; - _abpSelectTagHelper = abpSelectTagHelper; } public override void Process(TagHelperContext context, TagHelperOutput output) { output.TagName = "form"; - output.Attributes.Add("method","post"); - output.Attributes.Add("action","#"); + output.Attributes.Add("method", "post"); + output.Attributes.Add("action", "#"); var innerhtml = GetInnerHtmlContent(); @@ -38,19 +38,19 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form foreach (var model in models) { - innerHtmlcontent += ProcessField(model); + innerHtmlcontent += ProcessInputGroup(model); } return innerHtmlcontent; } - protected virtual string ProcessField(ModelExpression model) + protected virtual string ProcessInputGroup(ModelExpression model) { _abpInputTagHelper.AspFor = model; _abpInputTagHelper.Label = ""; _abpInputTagHelper.ViewContext = TagHelper.ViewContext; - return RenderTagHelper(new TagHelperAttributeList(), _abpInputTagHelper,_htmlEncoder,"div",TagMode.StartTagAndEndTag) + return RenderTagHelper(new TagHelperAttributeList(), _abpInputTagHelper, _htmlEncoder, "div", TagMode.StartTagAndEndTag) + Environment.NewLine; } diff --git a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs index 20301a221c..62ddaac061 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs +++ b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs @@ -71,10 +71,16 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components public class Person { + [Required] + [DisplayName("Name")] public string Name { get; set; } + [Required] + [DisplayName("Age")] public int Age { get; set; } + [Required] + [DisplayName("City")] public Cities City { get; set; } public Phone Phone { get; set; } @@ -85,11 +91,26 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components [DisplayName("Is Active")] public bool IsActive { get; set; } + + [DisplayName("Country")] + public string Country { get; set; } + + public List CountrySelectItems { get; } = new List + { + new SelectListItem { Value = "MX", Text = "Mexico" }, + new SelectListItem { Value = "CA", Text = "Canada" }, + new SelectListItem { Value = "US", Text = "USA" }, + }; } public class Phone { + [Required] + [DisplayName("Number")] public string Number { get; set; } + + [Required] + [DisplayName("Name")] public string Name { get; set; } } } \ No newline at end of file From a486601c281818375b2297a66773fa2e089bbe35 Mon Sep 17 00:00:00 2001 From: yekalkan Date: Mon, 30 Apr 2018 13:59:28 +0300 Subject: [PATCH 13/25] Form Tag helper override --- .../Form/AbpDynamicformTagHelperService.cs | 56 +++++++++++++------ .../Pages/Components/Forms.cshtml | 2 + .../Pages/Components/Forms.cshtml.cs | 7 --- 3 files changed, 42 insertions(+), 23 deletions(-) diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs index b500253414..b59eb269de 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text.Encodings.Web; +using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Razor.TagHelpers; @@ -20,28 +21,36 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form _abpInputTagHelper = abpInputTagHelper; } - public override void Process(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { output.TagName = "form"; output.Attributes.Add("method", "post"); output.Attributes.Add("action", "#"); - var innerhtml = GetInnerHtmlContent(); + var inputsAsHtml = await GetInputsAsHtml(output); - output.PreContent.SetHtmlContent(innerhtml); + output.PreContent.SetHtmlContent(inputsAsHtml); } - protected virtual string GetInnerHtmlContent() + protected virtual async Task GetInputsAsHtml(TagHelperOutput output) { - var innerHtmlcontent = ""; - var models = ExploreModelsRecursively(new List(), TagHelper.Model.ModelExplorer); + var inputsAsHtml = ""; + var models = await GetModels(output); foreach (var model in models) { - innerHtmlcontent += ProcessInputGroup(model); + inputsAsHtml += ProcessInputGroup(model); } - return innerHtmlcontent; + return inputsAsHtml; + } + + protected virtual async Task> GetModels(TagHelperOutput output) + { + + var models = ExploreModelsRecursively(new List(), TagHelper.Model.ModelExplorer); + + return await RemoveOverridenFieldsAndGetModels(output, models); } protected virtual string ProcessInputGroup(ModelExpression model) @@ -67,7 +76,16 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form protected virtual ModelExpression ModelExplorerToModelExpressionConverter(ModelExplorer explorer) { - return new ModelExpression(explorer.Metadata.PropertyName, explorer); + var temp = explorer; + var propertyName = explorer.Metadata.PropertyName; + + while (temp?.Container?.Metadata?.PropertyName != null) + { + temp = temp.Container; + propertyName = temp.Metadata.PropertyName + "." + propertyName; + } + + return new ModelExpression(propertyName, explorer); } protected virtual bool IsCsharpClassOrPrimitive(Type type) @@ -76,17 +94,23 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form type.IsValueType || type == typeof(DateTime) || type == typeof(ValueType) || - type == typeof(String) || - type == typeof(Decimal) || - type == typeof(Double) || + type == typeof(string) || + type == typeof(decimal) || + type == typeof(double) || type == typeof(Guid) || type == typeof(TimeSpan) || type == typeof(DateTimeOffset) || - type == typeof(Single) || - type == typeof(Int16) || - type == typeof(Int32) || - type == typeof(Int64) || + type == typeof(float) || + type == typeof(short) || + type == typeof(int) || + type == typeof(long) || type.IsEnum; } + + protected virtual async Task> RemoveOverridenFieldsAndGetModels(TagHelperOutput output, List models) + { + var overridenFormElementsProcessed = (await output.GetChildContentAsync()).GetContent(); + return models.Where(m => !overridenFormElementsProcessed.Contains("id=\"" + m.Name.Replace('.','_') + "\"")).ToList(); + } } } \ No newline at end of file diff --git a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml index 9135ed047d..66da21ce04 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml +++ b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml @@ -15,6 +15,8 @@
+ +
diff --git a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs index 62ddaac061..d6e8a25b44 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs +++ b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs @@ -94,13 +94,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components [DisplayName("Country")] public string Country { get; set; } - - public List CountrySelectItems { get; } = new List - { - new SelectListItem { Value = "MX", Text = "Mexico" }, - new SelectListItem { Value = "CA", Text = "Canada" }, - new SelectListItem { Value = "US", Text = "USA" }, - }; } public class Phone From 85620a97bc4f9765da915d032fa1e0f881c36840 Mon Sep 17 00:00:00 2001 From: yekalkan Date: Mon, 30 Apr 2018 16:53:43 +0300 Subject: [PATCH 14/25] Tag Helper form improvements --- .../TagHelpers/AbpTagHelperService.cs | 25 +++++++-- .../Form/AbpDynamicformTagHelperService.cs | 40 ++++++-------- .../Form/AbpFormGroupTagHelperService.cs | 10 ---- .../TagHelpers/Form/AbpInputTagHelper.cs | 3 ++ .../Form/AbpInputTagHelperService.cs | 38 +++++++------ .../Form/AbpSelectTagHelperService.cs | 6 +-- .../TagHelpers/Form/DisplayOrder.cs | 18 +++++++ .../TagHelpers/Form/InputGroupContent.cs | 9 ++++ .../Pages/Components/Forms.cshtml | 7 +-- .../Pages/Components/Forms.cshtml.cs | 53 +++++++++---------- 10 files changed, 123 insertions(+), 86 deletions(-) create mode 100644 src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DisplayOrder.cs create mode 100644 src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/InputGroupContent.cs diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs index 9569468bd2..a4a3425c18 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; using System.IO; +using System.Reflection; using System.Text.Encodings.Web; using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Razor.TagHelpers; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers @@ -30,28 +32,28 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers return Task.CompletedTask; } - protected TagHelperOutput GetInnerTagHelper(TagHelperAttributeList attributeList, TagHelper tagHelper, string tagName = "div", TagMode tagMode = TagMode.SelfClosing) + protected TagHelperOutput GetInnerTagHelper(TagHelperAttributeList attributeList, TagHelperContext context, TagHelper tagHelper, string tagName = "div", TagMode tagMode = TagMode.SelfClosing) { var innerOutput = new TagHelperOutput(tagName, attributeList, (useCachedResult, encoder) => Task.Run(() => new DefaultTagHelperContent())) { TagMode = tagMode }; - var innerContext = new TagHelperContext(attributeList, new Dictionary(), Guid.NewGuid().ToString()); + var innerContext = new TagHelperContext(attributeList, context.Items, Guid.NewGuid().ToString()); tagHelper.Process(innerContext, innerOutput); return innerOutput; } - protected string RenderTagHelper(TagHelperAttributeList attributeList, TagHelper tagHelper, HtmlEncoder htmlEncoder, string tagName = "div", TagMode tagMode = TagMode.SelfClosing) + protected string RenderTagHelper(TagHelperAttributeList attributeList, TagHelperContext context, TagHelper tagHelper, HtmlEncoder htmlEncoder, string tagName = "div", TagMode tagMode = TagMode.SelfClosing) { var innerOutput = new TagHelperOutput(tagName, attributeList, (useCachedResult, encoder) => Task.Run(() => new DefaultTagHelperContent())) { TagMode = tagMode }; - var innerContext = new TagHelperContext(attributeList, new Dictionary(), Guid.NewGuid().ToString()); + var innerContext = new TagHelperContext(attributeList, context.Items, Guid.NewGuid().ToString()); tagHelper.Process(innerContext, innerOutput); @@ -66,5 +68,20 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers return writer.ToString(); } } + + public static T GetAttribute(ModelExplorer property) where T : Attribute + { + var xd1 = property.Container.ModelType.GetTypeInfo(); + var xd2 = xd1.GetProperty(property.Metadata.PropertyName); + + if (xd2 == null) + { + return null; + } + + var attribute = xd2 .GetCustomAttribute(); + + return attribute; + } } } \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs index b59eb269de..3f8889a477 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs @@ -13,7 +13,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { private readonly HtmlEncoder _htmlEncoder; private readonly AbpInputTagHelper _abpInputTagHelper; - private const string SelectItemsPostFix = "selectitems"; public AbpDynamicFormTagHelperService(HtmlEncoder htmlEncoder, AbpInputTagHelper abpInputTagHelper) { @@ -23,44 +22,45 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { + var list = new List(); + context.Items.Add("InputGroupContents", list); + output.TagName = "form"; output.Attributes.Add("method", "post"); output.Attributes.Add("action", "#"); - var inputsAsHtml = await GetInputsAsHtml(output); - output.PreContent.SetHtmlContent(inputsAsHtml); + await output.GetChildContentAsync(); + ProcessFields(context, output); + + foreach (var itemConfig in list.OrderBy(o => o.Order)) + { + output.PostContent.SetHtmlContent(output.PostContent.GetContent() + itemConfig.Html); + } } - protected virtual async Task GetInputsAsHtml(TagHelperOutput output) + protected virtual void ProcessFields(TagHelperContext context, TagHelperOutput output) { - var inputsAsHtml = ""; - var models = await GetModels(output); + var models = GetModels(context, output); foreach (var model in models) { - inputsAsHtml += ProcessInputGroup(model); + ProcessInputGroup(context, model); } - - return inputsAsHtml; } - protected virtual async Task> GetModels(TagHelperOutput output) + protected virtual List GetModels(TagHelperContext context, TagHelperOutput output) { - - var models = ExploreModelsRecursively(new List(), TagHelper.Model.ModelExplorer); - - return await RemoveOverridenFieldsAndGetModels(output, models); + return ExploreModelsRecursively(new List(), TagHelper.Model.ModelExplorer); } - protected virtual string ProcessInputGroup(ModelExpression model) + protected virtual void ProcessInputGroup(TagHelperContext context, ModelExpression model) { _abpInputTagHelper.AspFor = model; _abpInputTagHelper.Label = ""; _abpInputTagHelper.ViewContext = TagHelper.ViewContext; - return RenderTagHelper(new TagHelperAttributeList(), _abpInputTagHelper, _htmlEncoder, "div", TagMode.StartTagAndEndTag) - + Environment.NewLine; + RenderTagHelper(new TagHelperAttributeList(), context, _abpInputTagHelper, _htmlEncoder, "div", TagMode.StartTagAndEndTag); } protected virtual List ExploreModelsRecursively(List list, ModelExplorer model) @@ -106,11 +106,5 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form type == typeof(long) || type.IsEnum; } - - protected virtual async Task> RemoveOverridenFieldsAndGetModels(TagHelperOutput output, List models) - { - var overridenFormElementsProcessed = (await output.GetChildContentAsync()).GetContent(); - return models.Where(m => !overridenFormElementsProcessed.Contains("id=\"" + m.Name.Replace('.','_') + "\"")).ToList(); - } } } \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs index 2a5e251766..22b9b95d22 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs @@ -6,15 +6,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { public class AbpFormGroupTagHelperService : AbpTagHelperService { - private readonly HtmlEncoder _htmlEncoder; - private readonly AbpInputTagHelper _abpInputTagHelper; - - public AbpFormGroupTagHelperService(HtmlEncoder htmlEncoder, AbpInputTagHelper abpInputTagHelper) - { - _htmlEncoder = htmlEncoder; - _abpInputTagHelper = abpInputTagHelper; - } - public override void Process(TagHelperContext context, TagHelperOutput output) { output.TagName = "div"; @@ -24,6 +15,5 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form output.Attributes.AddClass("form-check"); } } - } } \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs index a2f157be30..3d038a415d 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs @@ -11,6 +11,9 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form public string Label { get; set; } + [HtmlAttributeName("order")] + public int? FieldOrder { get; set; } + [HtmlAttributeNotBound] [ViewContext] public ViewContext ViewContext { get; set; } diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs index 7b73eabb89..93e34a5871 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs @@ -1,7 +1,10 @@ using System; +using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text.Encodings.Web; using Localization.Resources.AbpUi; +using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.TagHelpers; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Razor.TagHelpers; @@ -24,32 +27,35 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form public override void Process(TagHelperContext context, TagHelperOutput output) { - output.TagName = "div"; - output.TagMode = TagMode.StartTagAndEndTag; - - var inputTag = GetInputTag(); + var inputTag = GetInputTag(context); var inputHtml = RenderTagHelperOutput(inputTag, _encoder); var isCheckbox = IsInputCheckbox(inputTag.Attributes); - var label = GetLabelAsHtml(inputTag, isCheckbox); var content = isCheckbox ? inputHtml + Environment.NewLine + label : label + Environment.NewLine + inputHtml; - output.Content.SetHtmlContent(content); + content ="
" + Environment.NewLine + content + Environment.NewLine + "
"; - SetDivAttributes(output, isCheckbox); - } - - protected virtual void SetDivAttributes(TagHelperOutput output, bool isCheckbox) - { - output.Attributes.RemoveAll("asp-for"); - output.Attributes.Add("class", isCheckbox ? " form-check" : "form-group"); + //var order = GetAttribute(TagHelper.AspFor.ModelExplorer); + + var list = context.Items["InputGroupContents"] as List; + + if (list != null && !list.Any(igc =>igc.Html.Contains("id=\"" + TagHelper.AspFor.Name.Replace('.', '_') + "\""))) + { + list.Add(new InputGroupContent + { + Html = content, + Order = TagHelper.FieldOrder ?? 999 + }); + } + + output.SuppressOutput(); } - protected virtual TagHelperOutput GetInputTag() + protected virtual TagHelperOutput GetInputTag(TagHelperContext context) { var inputTagHelper = new InputTagHelper(_generator) { @@ -57,8 +63,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form ViewContext = TagHelper.ViewContext }; - var inputTagHelperOutput = GetInnerTagHelper(new TagHelperAttributeList(), inputTagHelper, "input"); ; - + var inputTagHelperOutput = GetInnerTagHelper(new TagHelperAttributeList(), context, inputTagHelper, "input"); + inputTagHelperOutput.Attributes.Add("class", IsInputCheckbox(inputTagHelperOutput.Attributes) ? "form-check-input" : "form-control"); diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs index 316a141e8b..27ad072108 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs @@ -28,7 +28,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form SetDivAttributes(output); output.TagMode = TagMode.StartTagAndEndTag; - var selectTag = GetSelectTag(); + var selectTag = GetSelectTag(context); var seelctAsHtml = RenderTagHelperOutput(selectTag, _encoder); var labelAsHtml = GetLabelAsHtml(selectTag); @@ -44,7 +44,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form output.Attributes.Add("class", "form-group"); } - protected virtual TagHelperOutput GetSelectTag() + protected virtual TagHelperOutput GetSelectTag(TagHelperContext context) { var selectTagHelper = new SelectTagHelper(_generator) { @@ -54,7 +54,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form }; var attributes = new TagHelperAttributeList { new TagHelperAttribute("class", "form-control") }; - var inputTagHelperOutput = GetInnerTagHelper(attributes, selectTagHelper, "select", TagMode.StartTagAndEndTag); ; + var inputTagHelperOutput = GetInnerTagHelper(attributes, context,selectTagHelper, "select", TagMode.StartTagAndEndTag); ; inputTagHelperOutput.Attributes.Add("class", "form-control"); diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DisplayOrder.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DisplayOrder.cs new file mode 100644 index 0000000000..7f311790d9 --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DisplayOrder.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form +{ + [AttributeUsage(AttributeTargets.Property)] + public class DisplayOrder : Attribute + { + public int Number { get; set; } + + public DisplayOrder(int number) + { + Number = number; + } + } +} diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/InputGroupContent.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/InputGroupContent.cs new file mode 100644 index 0000000000..06694dbf9a --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/InputGroupContent.cs @@ -0,0 +1,9 @@ +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form +{ + public class InputGroupContent + { + public string Html { get; set; } + + public int Order { get; set; } + } +} \ No newline at end of file diff --git a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml index 66da21ce04..711621d0d9 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml +++ b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml @@ -16,7 +16,8 @@ - + +
@@ -28,7 +29,7 @@
-

# Input Group Example

+@*

# Input Group Example

@@ -59,7 +60,7 @@ </form>
-
+
*@ @*
diff --git a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs index d6e8a25b44..d2ac31c34a 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs +++ b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs @@ -5,42 +5,44 @@ using System.ComponentModel.DataAnnotations; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.ViewFeatures; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components { public class FormsModel : PageModel { - [Required] - [DisplayName("Name")] - public string Name { get; set; } + //[Required] + //[DisplayName("Name")] + //public string Name { get; set; } - [Required] - [EmailAddress] - [DisplayName("Email")] - public string EmailAddress { get; set; } + //[Required] + //[EmailAddress] + //[DisplayName("Email")] + //public string EmailAddress { get; set; } - [DataType(DataType.Password)] - public string Password { get; set; } = "MyPass"; + //[DataType(DataType.Password)] + //public string Password { get; set; } = "MyPass"; - [Phone] - [DisplayName("Phone Number")] - public string PhoneNumber { get; set; } + //[Phone] + //[DisplayName("Phone Number")] + //[DisplayOrder(4)] + //public string PhoneNumber { get; set; } - [DisplayName("Count")] - public int Count { get; set; } + //[DisplayName("Count")] + //public int Count { get; set; } - [DataType(DataType.Date)] - [DisplayName("Day")] - public DateTime Day { get; set; } + //[DataType(DataType.Date)] + //[DisplayName("Day")] + //public DateTime Day { get; set; } - [DisplayName("Is Active")] - public bool IsActive { get; set; } + //[DisplayName("Is Active")] + //public bool IsActive { get; set; } - [DisplayName("Country")] - public string Country { get; set; } + //[DisplayName("Country")] + //public string Country { get; set; } - [DisplayName("City")] - public Cities City { get; set; } + //[DisplayName("City")] + //public Cities City { get; set; } public Person Person { get; set; } @@ -55,10 +57,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components public void OnGet() { - Name = "MyName"; - Day = DateTime.Today; - //var htmlHelper = new HtmlHelper(); - //EnumCityList = htmlHelper.GetEnumSelectList(typeof(Cities)); } } @@ -83,6 +81,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components [DisplayName("City")] public Cities City { get; set; } + [DisplayOrder(51)] public Phone Phone { get; set; } [DataType(DataType.Date)] From f27b487395b6aa7c459564e3045a1f363c057553 Mon Sep 17 00:00:00 2001 From: yekalkan Date: Mon, 30 Apr 2018 17:24:26 +0300 Subject: [PATCH 15/25] Field order attiribute in form tag helper --- .../TagHelpers/AbpTagHelperService.cs | 5 ++++- .../TagHelpers/Form/AbpInputTagHelper.cs | 3 --- .../Form/AbpInputTagHelperService.cs | 20 +++++++++++-------- .../Pages/Components/Forms.cshtml | 4 ++-- .../Pages/Components/Forms.cshtml.cs | 6 ++++-- 5 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs index a4a3425c18..5e2be762ba 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs @@ -71,7 +71,10 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers public static T GetAttribute(ModelExplorer property) where T : Attribute { - var xd1 = property.Container.ModelType.GetTypeInfo(); + //var xd1 = property.Container.ModelType.GetTypeInfo(); + //var xd2 = xd1.GetProperty(property.Metadata.PropertyName); + + var xd1 = property.Metadata.ContainerType.GetTypeInfo(); var xd2 = xd1.GetProperty(property.Metadata.PropertyName); if (xd2 == null) diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs index 3d038a415d..a2f157be30 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs @@ -11,9 +11,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form public string Label { get; set; } - [HtmlAttributeName("order")] - public int? FieldOrder { get; set; } - [HtmlAttributeNotBound] [ViewContext] public ViewContext ViewContext { get; set; } diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs index 93e34a5871..7e255a4847 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs @@ -32,14 +32,9 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form var isCheckbox = IsInputCheckbox(inputTag.Attributes); var label = GetLabelAsHtml(inputTag, isCheckbox); - var content = isCheckbox ? - inputHtml + Environment.NewLine + label : - label + Environment.NewLine + inputHtml; + var content = GetContent(label, inputHtml, isCheckbox); - content ="
" + Environment.NewLine + content + Environment.NewLine + "
"; - - - //var order = GetAttribute(TagHelper.AspFor.ModelExplorer); + var order = GetAttribute(TagHelper.AspFor.ModelExplorer); var list = context.Items["InputGroupContents"] as List; @@ -48,13 +43,22 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form list.Add(new InputGroupContent { Html = content, - Order = TagHelper.FieldOrder ?? 999 + Order = order?.Number ?? 0 }); } output.SuppressOutput(); } + protected virtual string GetContent(string label, string inputHtml, bool isCheckbox) + { + var content = isCheckbox ? + inputHtml + Environment.NewLine + label : + label + Environment.NewLine + inputHtml; + + return "
" + Environment.NewLine + content + Environment.NewLine + "
"; + } + protected virtual TagHelperOutput GetInputTag(TagHelperContext context) { var inputTagHelper = new InputTagHelper(_generator) diff --git a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml index 711621d0d9..532c283118 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml +++ b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml @@ -16,8 +16,8 @@ - - + +
diff --git a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs index d2ac31c34a..0682045d01 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs +++ b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs @@ -74,6 +74,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components public string Name { get; set; } [Required] + [DisplayOrder(61)] [DisplayName("Age")] public int Age { get; set; } @@ -81,13 +82,13 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components [DisplayName("City")] public Cities City { get; set; } - [DisplayOrder(51)] public Phone Phone { get; set; } [DataType(DataType.Date)] [DisplayName("Day")] public DateTime Day { get; set; } + [DisplayOrder(51)] [DisplayName("Is Active")] public bool IsActive { get; set; } @@ -102,7 +103,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components public string Number { get; set; } [Required] - [DisplayName("Name")] + [DisplayOrder(71)] + [DisplayName("PhoneName")] public string Name { get; set; } } } \ No newline at end of file From 0e5d126ebf97dc82b39441a625dd5ffc4123bc2f Mon Sep 17 00:00:00 2001 From: yekalkan Date: Mon, 30 Apr 2018 17:42:08 +0300 Subject: [PATCH 16/25] Select Items Attribute --- .../TagHelpers/Form/SelectItems.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectItems.cs diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectItems.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectItems.cs new file mode 100644 index 0000000000..2b0eb37566 --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectItems.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Rendering; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form +{ + [AttributeUsage(AttributeTargets.Property)] + public class SelectItems: Attribute + { + public IEnumerable Items { get; set; } + + public SelectItems(IEnumerable items) + { + Items = items; + } + } +} From 48512ca236e748839518f7719e7fb419639f2739 Mon Sep 17 00:00:00 2001 From: yekalkan Date: Tue, 1 May 2018 08:39:30 +0300 Subject: [PATCH 17/25] Select Item Attribute improvements --- .../TagHelpers/AbpTagHelperService.cs | 15 +------ .../TagHelpers/Form/SelectItems.cs | 40 +++++++++++++++++-- .../TagHelpers/Form/SelectType.cs | 8 ++++ 3 files changed, 46 insertions(+), 17 deletions(-) create mode 100644 src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectType.cs diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs index 5e2be762ba..2b8f15118a 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs @@ -71,20 +71,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers public static T GetAttribute(ModelExplorer property) where T : Attribute { - //var xd1 = property.Container.ModelType.GetTypeInfo(); - //var xd2 = xd1.GetProperty(property.Metadata.PropertyName); - - var xd1 = property.Metadata.ContainerType.GetTypeInfo(); - var xd2 = xd1.GetProperty(property.Metadata.PropertyName); - - if (xd2 == null) - { - return null; - } - - var attribute = xd2 .GetCustomAttribute(); - - return attribute; + return property?.Metadata?.ContainerType?.GetTypeInfo()?.GetProperty(property.Metadata.PropertyName)?.GetCustomAttribute(); } } } \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectItems.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectItems.cs index 2b0eb37566..b1e29b1a32 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectItems.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectItems.cs @@ -1,19 +1,53 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.AspNetCore.Mvc.ViewFeatures; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { [AttributeUsage(AttributeTargets.Property)] public class SelectItems: Attribute { - public IEnumerable Items { get; set; } + public string ItemsListPropertyName { get; set; } - public SelectItems(IEnumerable items) + public Type EnumType { get; set; } + + public SelectType SelectType { get; set; } = SelectType.Dropdown; + + public IEnumerable GetItems(ModelExplorer explorer) + { + if (IsEnumItem()) + { + return GetItemsFromEnum(); + } + else + { + return GetItemsFromListField(explorer); + } + } + + private IEnumerable GetItemsFromListField(ModelExplorer explorer) + { + var properties = explorer.Properties.Where(p => p.Metadata.PropertyName.Equals(ItemsListPropertyName)).ToList(); + + return properties.Count > 0 + ? properties.First().Model as IEnumerable + : new List(); + } + + private IEnumerable GetItemsFromEnum() + { + var enumItems = EnumType.GetTypeInfo().GetMembers(BindingFlags.Public | BindingFlags.Static); + + return enumItems.Select((t, i) => new SelectListItem() { Value = i.ToString(), Text = t.Name }).ToList(); + } + + private bool IsEnumItem() { - Items = items; + return EnumType != null && EnumType.GetTypeInfo().IsEnum; } } } diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectType.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectType.cs new file mode 100644 index 0000000000..b1c3bfa846 --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectType.cs @@ -0,0 +1,8 @@ +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form +{ + public enum SelectType + { + Dropdown, + Radio + } +} \ No newline at end of file From 794932cb7de541bbccefe6ab76ab40dc2ea16700 Mon Sep 17 00:00:00 2001 From: yekalkan Date: Tue, 1 May 2018 13:39:58 +0300 Subject: [PATCH 18/25] Form Tag helper improvements --- .../Form/AbpDynamicformTagHelper.cs | 2 +- .../Form/AbpDynamicformTagHelperService.cs | 81 ++++++++++++++++--- .../Form/AbpInputTagHelperService.cs | 4 +- .../Form/AbpSelectTagHelperService.cs | 31 ++++--- .../TagHelpers/Form/SelectItems.cs | 30 +------ .../Pages/Components/Forms.cshtml | 70 ++++++++-------- .../Pages/Components/Forms.cshtml.cs | 62 ++++---------- 7 files changed, 147 insertions(+), 133 deletions(-) diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelper.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelper.cs index 4ff93159c0..1bef51ea2e 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelper.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelper.cs @@ -6,8 +6,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { public class AbpDynamicFormTagHelper : AbpTagHelper { + [HtmlAttributeName("asp-model")] public ModelExpression Model { get; set; } - [HtmlAttributeNotBound] [ViewContext] diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs index 3f8889a477..1e005209a8 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text.Encodings.Web; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.Rendering; @@ -13,11 +14,13 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { private readonly HtmlEncoder _htmlEncoder; private readonly AbpInputTagHelper _abpInputTagHelper; + private readonly AbpSelectTagHelper _abpSelectTagHelper; - public AbpDynamicFormTagHelperService(HtmlEncoder htmlEncoder, AbpInputTagHelper abpInputTagHelper) + public AbpDynamicFormTagHelperService(HtmlEncoder htmlEncoder, AbpInputTagHelper abpInputTagHelper, AbpSelectTagHelper abpSelectTagHelper) { _htmlEncoder = htmlEncoder; _abpInputTagHelper = abpInputTagHelper; + _abpSelectTagHelper = abpSelectTagHelper; } public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) @@ -45,13 +48,24 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form foreach (var model in models) { + if (IsSelectGroup(context, model, out var selectItems)) + { + ProcessSelectGroup(context, model, selectItems); + continue; + } + ProcessInputGroup(context, model); } } - protected virtual List GetModels(TagHelperContext context, TagHelperOutput output) + protected virtual void ProcessSelectGroup(TagHelperContext context, ModelExpression model, IEnumerable selectItems) { - return ExploreModelsRecursively(new List(), TagHelper.Model.ModelExplorer); + _abpSelectTagHelper.AspFor = model; + _abpSelectTagHelper.AspItems = selectItems; + _abpSelectTagHelper.Label = ""; + _abpSelectTagHelper.ViewContext = TagHelper.ViewContext; + + RenderTagHelper(new TagHelperAttributeList(), context, _abpSelectTagHelper, _htmlEncoder, "div", TagMode.StartTagAndEndTag); } protected virtual void ProcessInputGroup(TagHelperContext context, ModelExpression model) @@ -63,6 +77,11 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form RenderTagHelper(new TagHelperAttributeList(), context, _abpInputTagHelper, _htmlEncoder, "div", TagMode.StartTagAndEndTag); } + protected virtual List GetModels(TagHelperContext context, TagHelperOutput output) + { + return TagHelper.Model.ModelExplorer.Properties.Aggregate(new List(), ExploreModelsRecursively); + } + protected virtual List ExploreModelsRecursively(List list, ModelExplorer model) { if (IsCsharpClassOrPrimitive(model.ModelType)) @@ -71,6 +90,11 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form return list; } + if (IsListOfSelectItem(model.ModelType)) + { + return list; + } + return model.Properties.Aggregate(list, ExploreModelsRecursively); } @@ -78,13 +102,13 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { var temp = explorer; var propertyName = explorer.Metadata.PropertyName; - + while (temp?.Container?.Metadata?.PropertyName != null) { temp = temp.Container; propertyName = temp.Metadata.PropertyName + "." + propertyName; } - + return new ModelExpression(propertyName, explorer); } @@ -94,17 +118,52 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form type.IsValueType || type == typeof(DateTime) || type == typeof(ValueType) || - type == typeof(string) || - type == typeof(decimal) || - type == typeof(double) || + type == typeof(String) || + type == typeof(Decimal) || + type == typeof(Double) || type == typeof(Guid) || + type == typeof(Char) || + type == typeof(Byte) || + type == typeof(Boolean) || type == typeof(TimeSpan) || type == typeof(DateTimeOffset) || + type == typeof(Int16) || + type == typeof(Int32) || + type == typeof(Int64) || + type == typeof(ushort) || + type == typeof(uint) || + type == typeof(ulong) || type == typeof(float) || - type == typeof(short) || - type == typeof(int) || - type == typeof(long) || type.IsEnum; } + + protected virtual bool IsListOfSelectItem(Type type) + { + return type == typeof(List) || type == typeof(IEnumerable); + } + + protected virtual bool IsSelectGroup(TagHelperContext context, ModelExpression model, out IEnumerable selectItems) + { + return IsEnum(model.ModelExplorer, out selectItems) || AreSelectItemsProvided(model.ModelExplorer, out selectItems); + } + + protected virtual bool IsEnum(ModelExplorer explorer, out IEnumerable selectItems) + { + selectItems = explorer.Metadata.IsEnum ? GetSelectItemsFromEnum(explorer.ModelType) : null; + return explorer.Metadata.IsEnum; + } + + protected virtual IEnumerable GetSelectItemsFromEnum(Type enumType) + { + return enumType.GetTypeInfo().GetMembers(BindingFlags.Public | BindingFlags.Static) + .Select((t, i) => new SelectListItem { Value = i.ToString(), Text = t.Name }).ToList(); + } + + protected virtual bool AreSelectItemsProvided(ModelExplorer explorer, out IEnumerable selectItems) + { + selectItems = GetAttribute(explorer)?.GetItems(explorer); + + return selectItems != null; + } } } \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs index 7e255a4847..d44f74c8e1 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs @@ -52,11 +52,11 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form protected virtual string GetContent(string label, string inputHtml, bool isCheckbox) { - var content = isCheckbox ? + var innerContent = isCheckbox ? inputHtml + Environment.NewLine + label : label + Environment.NewLine + inputHtml; - return "
" + Environment.NewLine + content + Environment.NewLine + "
"; + return "
" + Environment.NewLine + innerContent + Environment.NewLine + "
"; } protected virtual TagHelperOutput GetInputTag(TagHelperContext context) diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs index 27ad072108..e0bd59792d 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Text.Encodings.Web; using Localization.Resources.AbpUi; @@ -24,24 +25,34 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form public override void Process(TagHelperContext context, TagHelperOutput output) { - output.TagName = "div"; - SetDivAttributes(output); - output.TagMode = TagMode.StartTagAndEndTag; - var selectTag = GetSelectTag(context); var seelctAsHtml = RenderTagHelperOutput(selectTag, _encoder); var labelAsHtml = GetLabelAsHtml(selectTag); - var content = labelAsHtml + Environment.NewLine + seelctAsHtml; + var content = GetContent(labelAsHtml,seelctAsHtml); + + var order = GetAttribute(TagHelper.AspFor.ModelExplorer); + var list = context.Items["InputGroupContents"] as List; + + if (list != null && !list.Any(igc => igc.Html.Contains("id=\"" + TagHelper.AspFor.Name.Replace('.', '_') + "\""))) + { + list.Add(new InputGroupContent + { + Html = content, + Order = order?.Number ?? 0 + }); + } - output.Content.SetHtmlContent(content); + output.SuppressOutput(); } - protected virtual void SetDivAttributes(TagHelperOutput output) + + + protected virtual string GetContent(string label, string inputHtml) { - output.Attributes.RemoveAll("asp-for"); - output.Attributes.RemoveAll("asp-items"); - output.Attributes.Add("class", "form-group"); + var innerContent = label + Environment.NewLine + inputHtml; + + return "
" + Environment.NewLine + innerContent + Environment.NewLine + "
"; } protected virtual TagHelperOutput GetSelectTag(TagHelperContext context) diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectItems.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectItems.cs index b1e29b1a32..ef4e708c65 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectItems.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectItems.cs @@ -13,41 +13,15 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { public string ItemsListPropertyName { get; set; } - public Type EnumType { get; set; } - public SelectType SelectType { get; set; } = SelectType.Dropdown; public IEnumerable GetItems(ModelExplorer explorer) { - if (IsEnumItem()) - { - return GetItemsFromEnum(); - } - else - { - return GetItemsFromListField(explorer); - } - } - - private IEnumerable GetItemsFromListField(ModelExplorer explorer) - { - var properties = explorer.Properties.Where(p => p.Metadata.PropertyName.Equals(ItemsListPropertyName)).ToList(); + var properties = explorer.Container.Properties.Where(p => p.Metadata.PropertyName.Equals(ItemsListPropertyName)).ToList(); return properties.Count > 0 ? properties.First().Model as IEnumerable - : new List(); - } - - private IEnumerable GetItemsFromEnum() - { - var enumItems = EnumType.GetTypeInfo().GetMembers(BindingFlags.Public | BindingFlags.Static); - - return enumItems.Select((t, i) => new SelectListItem() { Value = i.ToString(), Text = t.Name }).ToList(); - } - - private bool IsEnumItem() - { - return EnumType != null && EnumType.GetTypeInfo().IsEnum; + : null; } } } diff --git a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml index 532c283118..8df7bad9cf 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml +++ b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml @@ -1,8 +1,9 @@ @page @using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components -@model Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components.FormsModel +@model FormsModel + @{ - ViewData["Title"] = "Forms"; + ViewData["Title"] = "Forms"; }

Forms

@@ -13,11 +14,8 @@
- + - - -
@@ -31,36 +29,36 @@ @*

# Input Group Example

-
-
- - - - - - - - - - - -
-
-
       
-        <form method="post" action="#">
-            <abp-input asp-for="Model.Name"/>
-            <abp-input asp-for="Model.Password" label="Password"/>
-            <abp-input asp-for="Model.IsActive" />
-            <abp-input asp-for="Model.PhoneNumber" />
-            <abp-input asp-for="Model.EmailAddress" />
-            <abp-input asp-for="Model.Count" />
-            <abp-input asp-for="Model.Day" />
-            <abp-select asp-for="Model.Country" asp-items="Model.Countries" label="Country"></abp-select>
-            <abp-select asp-for="Model.City" asp-items="Html.GetEnumSelectList(typeof(Cities))"></abp-select>
-        </form>
-        
-
-
*@ +
+
+
+ + + + + + + + + + +
+
+
+            <form method="post" action="#">
+                <abp-input asp-for="Model.Name"/>
+                <abp-input asp-for="Model.Password" label="Password"/>
+                <abp-input asp-for="Model.IsActive" />
+                <abp-input asp-for="Model.PhoneNumber" />
+                <abp-input asp-for="Model.EmailAddress" />
+                <abp-input asp-for="Model.Count" />
+                <abp-input asp-for="Model.Day" />
+                <abp-select asp-for="Model.Country" asp-items="Model.Countries" label="Country"></abp-select>
+                <abp-select asp-for="Model.City" asp-items="Html.GetEnumSelectList(typeof(Cities))"></abp-select>
+            </form>
+            
+
+
*@ @*
diff --git a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs index 0682045d01..e0d49d5ebd 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs +++ b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs @@ -11,52 +11,16 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components { public class FormsModel : PageModel { - //[Required] - //[DisplayName("Name")] - //public string Name { get; set; } - - //[Required] - //[EmailAddress] - //[DisplayName("Email")] - //public string EmailAddress { get; set; } - - //[DataType(DataType.Password)] - //public string Password { get; set; } = "MyPass"; - - //[Phone] - //[DisplayName("Phone Number")] - //[DisplayOrder(4)] - //public string PhoneNumber { get; set; } - - //[DisplayName("Count")] - //public int Count { get; set; } - - //[DataType(DataType.Date)] - //[DisplayName("Day")] - //public DateTime Day { get; set; } - - //[DisplayName("Is Active")] - //public bool IsActive { get; set; } - - //[DisplayName("Country")] - //public string Country { get; set; } - - //[DisplayName("City")] - //public Cities City { get; set; } - - public Person Person { get; set; } - - public List Countries { get; } = new List - { - new SelectListItem { Value = "MX", Text = "Mexico" }, - new SelectListItem { Value = "CA", Text = "Canada" }, - new SelectListItem { Value = "US", Text = "USA" }, - }; - - public static IEnumerable EnumCityList; + public PersonViewModel Ahmet { get; set; } = new PersonViewModel(); public void OnGet() { + Ahmet = new PersonViewModel + { + Name = "ahmet", + Age = 65, + Phone = new Phone {Number = "326346231",Name = "MyPhone"} + }; } } @@ -67,11 +31,11 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components Moscow } - public class Person + public class PersonViewModel { [Required] [DisplayName("Name")] - public string Name { get; set; } + public string Name { get; set; } = "MyName"; [Required] [DisplayOrder(61)] @@ -93,7 +57,15 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components public bool IsActive { get; set; } [DisplayName("Country")] + [SelectItems(ItemsListPropertyName = nameof(Countries))] public string Country { get; set; } + + public List Countries { get; set; } = new List + { + new SelectListItem { Value = "MX", Text = "Mexico" }, + new SelectListItem { Value = "CA", Text = "Canada" }, + new SelectListItem { Value = "US", Text = "USA" }, + }; } public class Phone From 6e69fe71a259c0811efeb219c99378de047737f9 Mon Sep 17 00:00:00 2001 From: yekalkan Date: Tue, 1 May 2018 13:57:59 +0300 Subject: [PATCH 19/25] Form Tag Helpers Refactoring --- .../TagHelpers/AbpTagHelperService.cs | 2 ++ .../Form/AbpDynamicformTagHelperService.cs | 31 ++++++++++++++----- .../Form/AbpInputTagHelperService.cs | 4 +-- .../Form/AbpSelectTagHelperService.cs | 4 +-- ...putGroupContent.cs => FormGroupContent.cs} | 2 +- .../Pages/Components/Forms.cshtml | 4 +-- 6 files changed, 32 insertions(+), 15 deletions(-) rename src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/{InputGroupContent.cs => FormGroupContent.cs} (81%) diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs index 2b8f15118a..597b8be601 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs @@ -12,6 +12,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers public abstract class AbpTagHelperService : IAbpTagHelperService where TTagHelper : TagHelper { + protected const string FormGroupContents = "FormGroupContents"; + public TTagHelper TagHelper { get; set; } public virtual int Order { get; } diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs index 1e005209a8..50dca5e705 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs @@ -25,23 +25,37 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { - var list = new List(); - context.Items.Add("InputGroupContents", list); - - output.TagName = "form"; - output.Attributes.Add("method", "post"); - output.Attributes.Add("action", "#"); - - + var list = InitilizeFormGroupContentsContext(context); + await output.GetChildContentAsync(); + ProcessFields(context, output); + SetContent(output,list); + } + + protected virtual void SetContent(TagHelperOutput output, List list) + { foreach (var itemConfig in list.OrderBy(o => o.Order)) { output.PostContent.SetHtmlContent(output.PostContent.GetContent() + itemConfig.Html); } } + protected virtual void SetFormAttributes(TagHelperOutput output) + { + output.TagName = "form"; + output.Attributes.Add("method", "post"); + output.Attributes.Add("action", "#"); + } + + protected virtual List InitilizeFormGroupContentsContext(TagHelperContext context) + { + var list = new List(); + context.Items.Add(FormGroupContents, list); + return list; + } + protected virtual void ProcessFields(TagHelperContext context, TagHelperOutput output) { var models = GetModels(context, output); @@ -87,6 +101,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form if (IsCsharpClassOrPrimitive(model.ModelType)) { list.Add(ModelExplorerToModelExpressionConverter(model)); + return list; } diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs index d44f74c8e1..38b8e8f417 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs @@ -36,11 +36,11 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form var order = GetAttribute(TagHelper.AspFor.ModelExplorer); - var list = context.Items["InputGroupContents"] as List; + var list = context.Items["InputGroupContents"] as List; if (list != null && !list.Any(igc =>igc.Html.Contains("id=\"" + TagHelper.AspFor.Name.Replace('.', '_') + "\""))) { - list.Add(new InputGroupContent + list.Add(new FormGroupContent { Html = content, Order = order?.Number ?? 0 diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs index e0bd59792d..9f1b904548 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs @@ -32,11 +32,11 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form var content = GetContent(labelAsHtml,seelctAsHtml); var order = GetAttribute(TagHelper.AspFor.ModelExplorer); - var list = context.Items["InputGroupContents"] as List; + var list = context.Items["InputGroupContents"] as List; if (list != null && !list.Any(igc => igc.Html.Contains("id=\"" + TagHelper.AspFor.Name.Replace('.', '_') + "\""))) { - list.Add(new InputGroupContent + list.Add(new FormGroupContent { Html = content, Order = order?.Number ?? 0 diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/InputGroupContent.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/FormGroupContent.cs similarity index 81% rename from src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/InputGroupContent.cs rename to src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/FormGroupContent.cs index 06694dbf9a..9a1c9e9f3e 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/InputGroupContent.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/FormGroupContent.cs @@ -1,6 +1,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { - public class InputGroupContent + public class FormGroupContent { public string Html { get; set; } diff --git a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml index 8df7bad9cf..5cada5ef21 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml +++ b/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml @@ -20,8 +20,8 @@
       
-        <abp-dynamic-form model="Model.Person" >
-        </form>
+        <abp-dynamic-form asp-model="Model.Ahmet" >
+        </abp-dynamic-form>
         
From 69b2ab8a440568c757f6eee28cf05143e7b99e8f Mon Sep 17 00:00:00 2001 From: yekalkan Date: Tue, 1 May 2018 13:58:43 +0300 Subject: [PATCH 20/25] Removed form-group tag helper --- .../TagHelpers/Form/AbpFormGroupTagHelper.cs | 13 ------------- .../Form/AbpFormGroupTagHelperService.cs | 19 ------------------- 2 files changed, 32 deletions(-) delete mode 100644 src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelper.cs delete mode 100644 src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelper.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelper.cs deleted file mode 100644 index 0634a28eb5..0000000000 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelper.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form -{ - public class AbpFormGroupTagHelper : AbpTagHelper - { - public bool Checkbox { get; set; } - - public AbpFormGroupTagHelper(AbpFormGroupTagHelperService tagHelperService) - : base(tagHelperService) - { - - } - } -} diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs deleted file mode 100644 index 22b9b95d22..0000000000 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpFormGroupTagHelperService.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Text.Encodings.Web; -using Microsoft.AspNetCore.Razor.TagHelpers; -using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers; - -namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form -{ - public class AbpFormGroupTagHelperService : AbpTagHelperService - { - public override void Process(TagHelperContext context, TagHelperOutput output) - { - output.TagName = "div"; - output.Attributes.AddClass("form-group"); - if (TagHelper.Checkbox) - { - output.Attributes.AddClass("form-check"); - } - } - } -} \ No newline at end of file From 2acf65ea7939917982338a4dc2169c3695b96217 Mon Sep 17 00:00:00 2001 From: yekalkan Date: Tue, 1 May 2018 14:22:00 +0300 Subject: [PATCH 21/25] Input Tag helper refactor --- .../TagHelpers/AbpTagHelperService.cs | 29 ++++----- .../Form/AbpInputTagHelperService.cs | 63 +++++++++++-------- 2 files changed, 53 insertions(+), 39 deletions(-) diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs index 597b8be601..00b0a8714e 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs @@ -6,6 +6,7 @@ using System.Text.Encodings.Web; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form; namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers { @@ -15,7 +16,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers protected const string FormGroupContents = "FormGroupContents"; public TTagHelper TagHelper { get; set; } - + public virtual int Order { get; } public virtual void Init(TagHelperContext context) @@ -34,7 +35,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers return Task.CompletedTask; } - protected TagHelperOutput GetInnerTagHelper(TagHelperAttributeList attributeList, TagHelperContext context, TagHelper tagHelper, string tagName = "div", TagMode tagMode = TagMode.SelfClosing) + protected virtual TagHelperOutput GetInnerTagHelper(TagHelperAttributeList attributeList, TagHelperContext context, TagHelper tagHelper, string tagName = "div", TagMode tagMode = TagMode.SelfClosing) { var innerOutput = new TagHelperOutput(tagName, attributeList, (useCachedResult, encoder) => Task.Run(() => new DefaultTagHelperContent())) { @@ -48,21 +49,14 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers return innerOutput; } - protected string RenderTagHelper(TagHelperAttributeList attributeList, TagHelperContext context, TagHelper tagHelper, HtmlEncoder htmlEncoder, string tagName = "div", TagMode tagMode = TagMode.SelfClosing) + protected virtual string RenderTagHelper(TagHelperAttributeList attributeList, TagHelperContext context, TagHelper tagHelper, HtmlEncoder htmlEncoder, string tagName = "div", TagMode tagMode = TagMode.SelfClosing) { - var innerOutput = new TagHelperOutput(tagName, attributeList, (useCachedResult, encoder) => Task.Run(() => new DefaultTagHelperContent())) - { - TagMode = tagMode - }; - - var innerContext = new TagHelperContext(attributeList, context.Items, Guid.NewGuid().ToString()); - - tagHelper.Process(innerContext, innerOutput); + var innerOutput = GetInnerTagHelper(attributeList, context, tagHelper, tagName, tagMode); return RenderTagHelperOutput(innerOutput, htmlEncoder); } - protected string RenderTagHelperOutput(TagHelperOutput output, HtmlEncoder htmlEncoder) + protected virtual string RenderTagHelperOutput(TagHelperOutput output, HtmlEncoder htmlEncoder) { using (var writer = new StringWriter()) { @@ -70,10 +64,17 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers return writer.ToString(); } } - - public static T GetAttribute(ModelExplorer property) where T : Attribute + + protected virtual T GetAttribute(ModelExplorer property) where T : Attribute { return property?.Metadata?.ContainerType?.GetTypeInfo()?.GetProperty(property.Metadata.PropertyName)?.GetCustomAttribute(); } + + protected virtual List GetFormGroupContentsList(TagHelperContext context) + { + return context.Items[FormGroupContents] as List; + } + + } } \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs index 38b8e8f417..23fc16e1f4 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs @@ -27,27 +27,39 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form public override void Process(TagHelperContext context, TagHelperOutput output) { - var inputTag = GetInputTag(context); - var inputHtml = RenderTagHelperOutput(inputTag, _encoder); - var isCheckbox = IsInputCheckbox(inputTag.Attributes); - var label = GetLabelAsHtml(inputTag, isCheckbox); + var html = GetFormInputGroupAsHtml(context, output); + + var order = GetInputOrder(); - var content = GetContent(label, inputHtml, isCheckbox); + AddGroupToFormGroupContents(GetFormGroupContentsList(context), html, order); - var order = GetAttribute(TagHelper.AspFor.ModelExplorer); + output.SuppressOutput(); + } - var list = context.Items["InputGroupContents"] as List; + protected virtual int GetInputOrder() + { + return GetAttribute(TagHelper.AspFor.ModelExplorer)?.Number ?? 0; + } - if (list != null && !list.Any(igc =>igc.Html.Contains("id=\"" + TagHelper.AspFor.Name.Replace('.', '_') + "\""))) + protected virtual void AddGroupToFormGroupContents(List list, string html, int order) + { + if (list != null && !list.Any(igc => igc.Html.Contains("id=\"" + TagHelper.AspFor.Name.Replace('.', '_') + "\""))) { list.Add(new FormGroupContent { - Html = content, - Order = order?.Number ?? 0 + Html = html, + Order = order }); } + } - output.SuppressOutput(); + protected virtual string GetFormInputGroupAsHtml(TagHelperContext context, TagHelperOutput output) + { + var inputTag = GetInputTag(context, out var isCheckbox); + var inputHtml = RenderTagHelperOutput(inputTag, _encoder); + var label = GetLabelAsHtml(inputTag, isCheckbox); + + return GetContent(label, inputHtml, isCheckbox); } protected virtual string GetContent(string label, string inputHtml, bool isCheckbox) @@ -59,7 +71,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form return "
" + Environment.NewLine + innerContent + Environment.NewLine + "
"; } - protected virtual TagHelperOutput GetInputTag(TagHelperContext context) + protected virtual TagHelperOutput GetInputTag(TagHelperContext context, out bool isCheckbox) { var inputTagHelper = new InputTagHelper(_generator) { @@ -68,9 +80,9 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form }; var inputTagHelperOutput = GetInnerTagHelper(new TagHelperAttributeList(), context, inputTagHelper, "input"); + isCheckbox = IsInputCheckbox(inputTagHelperOutput.Attributes); - inputTagHelperOutput.Attributes.Add("class", - IsInputCheckbox(inputTagHelperOutput.Attributes) ? "form-check-input" : "form-control"); + inputTagHelperOutput.Attributes.Add("class", isCheckbox ? "form-check-input" : "form-control"); return inputTagHelperOutput; } @@ -87,25 +99,26 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form return ""; } - var label = GetLabelText(); - var idAttr = inputTag.Attributes.FirstOrDefault(a => a.Name == "id"); - var idAttrAsString = ""; - - if (idAttr != null) - { - idAttrAsString = "for=\"" + idAttr.Value + "\""; - } - + var label = GetLabelValue(); var checkboxClass = isCheckbox ? "class=\"form-check-label\" " : ""; - return ""; + return ""; } - protected virtual string GetLabelText() + protected virtual string GetLabelValue() { return string.IsNullOrEmpty(TagHelper.Label) ? TagHelper.AspFor.Metadata.DisplayName : TagHelper.Label; } + + protected virtual string GetIdAttributeAsString(TagHelperOutput inputTag) + { + var idAttr = inputTag.Attributes.FirstOrDefault(a => a.Name == "id"); + + return idAttr != null ? "for=\"" + idAttr.Value + "\"" : ""; + } } } \ No newline at end of file From 9da812d9e7023839dd50dd856c7f5e1b746b913a Mon Sep 17 00:00:00 2001 From: yekalkan Date: Tue, 1 May 2018 14:38:46 +0300 Subject: [PATCH 22/25] select tag helper refactor --- .../TagHelpers/AbpTagHelperService.cs | 34 ++++++++++++++ .../Form/AbpInputTagHelperService.cs | 33 ++------------ .../Form/AbpSelectTagHelperService.cs | 45 +++++++------------ 3 files changed, 53 insertions(+), 59 deletions(-) diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs index 00b0a8714e..f668d3faac 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Reflection; using System.Text.Encodings.Web; using System.Threading.Tasks; @@ -75,6 +76,39 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers return context.Items[FormGroupContents] as List; } + protected virtual string GetIdAttributeAsString(TagHelperOutput inputTag) + { + var idAttr = inputTag.Attributes.FirstOrDefault(a => a.Name == "id"); + + return idAttr != null ? "for=\"" + idAttr.Value + "\"" : ""; + } + + protected virtual int GetInputOrder(ModelExplorer explorer) + { + return GetAttribute(explorer)?.Number ?? 0; + } + + protected virtual void AddGroupToFormGroupContents(TagHelperContext context, string propertyName, string html, int order) + { + var list = GetFormGroupContentsList(context); + if (list != null && !list.Any(igc => igc.Html.Contains("id=\"" + propertyName.Replace('.', '_') + "\""))) + { + list.Add(new FormGroupContent + { + Html = html, + Order = order + }); + } + } + + protected virtual string GetFormInputGroupAsHtml(TagHelperContext context, TagHelperOutput output) + { + var inputTag = GetInputTag(context, out var isCheckbox); + var inputHtml = RenderTagHelperOutput(inputTag, _encoder); + var label = GetLabelAsHtml(inputTag, isCheckbox); + + return GetContent(label, inputHtml, isCheckbox); + } } } \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs index 23fc16e1f4..9259b7aaf6 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs @@ -29,30 +29,13 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { var html = GetFormInputGroupAsHtml(context, output); - var order = GetInputOrder(); + var order = GetInputOrder(TagHelper.AspFor.ModelExplorer); - AddGroupToFormGroupContents(GetFormGroupContentsList(context), html, order); + AddGroupToFormGroupContents(context,TagHelper.AspFor.Name, html, order); output.SuppressOutput(); } - protected virtual int GetInputOrder() - { - return GetAttribute(TagHelper.AspFor.ModelExplorer)?.Number ?? 0; - } - - protected virtual void AddGroupToFormGroupContents(List list, string html, int order) - { - if (list != null && !list.Any(igc => igc.Html.Contains("id=\"" + TagHelper.AspFor.Name.Replace('.', '_') + "\""))) - { - list.Add(new FormGroupContent - { - Html = html, - Order = order - }); - } - } - protected virtual string GetFormInputGroupAsHtml(TagHelperContext context, TagHelperOutput output) { var inputTag = GetInputTag(context, out var isCheckbox); @@ -98,12 +81,11 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { return ""; } - - var label = GetLabelValue(); + var checkboxClass = isCheckbox ? "class=\"form-check-label\" " : ""; return ""; } @@ -113,12 +95,5 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form TagHelper.AspFor.Metadata.DisplayName : TagHelper.Label; } - - protected virtual string GetIdAttributeAsString(TagHelperOutput inputTag) - { - var idAttr = inputTag.Attributes.FirstOrDefault(a => a.Name == "id"); - - return idAttr != null ? "for=\"" + idAttr.Value + "\"" : ""; - } } } \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs index 9f1b904548..ea8418cc9b 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs @@ -25,28 +25,23 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form public override void Process(TagHelperContext context, TagHelperOutput output) { - var selectTag = GetSelectTag(context); - - var seelctAsHtml = RenderTagHelperOutput(selectTag, _encoder); - var labelAsHtml = GetLabelAsHtml(selectTag); - var content = GetContent(labelAsHtml,seelctAsHtml); + var html = GetFormInputGroupAsHtml(context, output); + + var order = GetInputOrder(TagHelper.AspFor.ModelExplorer); - var order = GetAttribute(TagHelper.AspFor.ModelExplorer); - var list = context.Items["InputGroupContents"] as List; - - if (list != null && !list.Any(igc => igc.Html.Contains("id=\"" + TagHelper.AspFor.Name.Replace('.', '_') + "\""))) - { - list.Add(new FormGroupContent - { - Html = content, - Order = order?.Number ?? 0 - }); - } + AddGroupToFormGroupContents(context, TagHelper.AspFor.Name, html, order); output.SuppressOutput(); } + + protected virtual string GetFormInputGroupAsHtml(TagHelperContext context, TagHelperOutput output) + { + var selectTag = GetSelectTag(context); + var selectAsHtml = RenderTagHelperOutput(selectTag, _encoder); + var label = GetLabelAsHtml(selectTag); - + return GetContent(label, selectAsHtml); + } protected virtual string GetContent(string label, string inputHtml) { @@ -63,9 +58,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form Items = TagHelper.AspItems, ViewContext = TagHelper.ViewContext }; - - var attributes = new TagHelperAttributeList { new TagHelperAttribute("class", "form-control") }; - var inputTagHelperOutput = GetInnerTagHelper(attributes, context,selectTagHelper, "select", TagMode.StartTagAndEndTag); ; + + var inputTagHelperOutput = GetInnerTagHelper(new TagHelperAttributeList(), context,selectTagHelper, "select", TagMode.StartTagAndEndTag); ; inputTagHelperOutput.Attributes.Add("class", "form-control"); @@ -80,16 +74,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form return ""; } - var label = GetLabelText(); - var idAttr = selectTag.Attributes.FirstOrDefault(a => a.Name == "id"); - var idAttrAsString = ""; - - if (idAttr != null) - { - idAttrAsString = "for=\"" + idAttr.Value + "\""; - } - - return ""; + return ""; } protected virtual string GetLabelText() From 6e57405a90501acf11bf7c2168af8fe90dac2133 Mon Sep 17 00:00:00 2001 From: yekalkan Date: Tue, 1 May 2018 15:00:19 +0300 Subject: [PATCH 23/25] Added text-danger class to asp-validation-for tag --- .../TagHelpers/AbpTagHelperService.cs | 9 --------- .../Form/AbpValidationAttributeTagHelper.cs | 18 +++++++++++++++++ .../AbpValidationAttributeTagHelperService.cs | 20 +++++++++++++++++++ 3 files changed, 38 insertions(+), 9 deletions(-) create mode 100644 src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpValidationAttributeTagHelper.cs create mode 100644 src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpValidationAttributeTagHelperService.cs diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs index f668d3faac..df9c90f3b2 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs @@ -101,14 +101,5 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers }); } } - - protected virtual string GetFormInputGroupAsHtml(TagHelperContext context, TagHelperOutput output) - { - var inputTag = GetInputTag(context, out var isCheckbox); - var inputHtml = RenderTagHelperOutput(inputTag, _encoder); - var label = GetLabelAsHtml(inputTag, isCheckbox); - - return GetContent(label, inputHtml, isCheckbox); - } } } \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpValidationAttributeTagHelper.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpValidationAttributeTagHelper.cs new file mode 100644 index 0000000000..99c9fc4cce --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpValidationAttributeTagHelper.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.AspNetCore.Mvc.ViewFeatures; +using Microsoft.AspNetCore.Razor.TagHelpers; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form +{ + [HtmlTargetElement(Attributes = "asp-validation-for")] + public class AbpValidationAttributeTagHelper : AbpTagHelper, ITransientDependency + { + public AbpValidationAttributeTagHelper(AbpValidationAttributeTagHelperService tagHelperService) + : base(tagHelperService) + { + + } + } +} diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpValidationAttributeTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpValidationAttributeTagHelperService.cs new file mode 100644 index 0000000000..0c78cf5396 --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpValidationAttributeTagHelperService.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.Encodings.Web; +using Localization.Resources.AbpUi; +using Microsoft.AspNetCore.Mvc.TagHelpers; +using Microsoft.AspNetCore.Mvc.ViewFeatures; +using Microsoft.AspNetCore.Razor.TagHelpers; +using Microsoft.Extensions.Localization; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form +{ + public class AbpValidationAttributeTagHelperService : AbpTagHelperService + { + public override void Process(TagHelperContext context, TagHelperOutput output) + { + output.Attributes.Add("class","text-danger"); + } + } +} \ No newline at end of file From b95ddd50c69200e4b6486b0efa500b8db4500d83 Mon Sep 17 00:00:00 2001 From: yekalkan Date: Tue, 1 May 2018 15:13:16 +0300 Subject: [PATCH 24/25] Added validation to input group --- .../Form/AbpInputTagHelperService.cs | 27 +++++++++++++++---- .../Form/AbpSelectTagHelperService.cs | 3 +-- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs index 9259b7aaf6..7084b81877 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs +++ b/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs @@ -31,7 +31,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form var order = GetInputOrder(TagHelper.AspFor.ModelExplorer); - AddGroupToFormGroupContents(context,TagHelper.AspFor.Name, html, order); + AddGroupToFormGroupContents(context, TagHelper.AspFor.Name, html, order); output.SuppressOutput(); } @@ -42,16 +42,33 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form var inputHtml = RenderTagHelperOutput(inputTag, _encoder); var label = GetLabelAsHtml(inputTag, isCheckbox); - return GetContent(label, inputHtml, isCheckbox); + var validation = isCheckbox ? "" : GetValidationAsHtml(context); + + return GetContent(label, inputHtml, validation, isCheckbox); + } + protected virtual string GetValidationAsHtml(TagHelperContext context) + { + var validationMessageTagHelper = new ValidationMessageTagHelper(_generator) + { + For = TagHelper.AspFor, + ViewContext = TagHelper.ViewContext + }; + + var attributeList = new TagHelperAttributeList { { "class", "form-control" } }; + + return RenderTagHelper(attributeList, context, validationMessageTagHelper, _encoder, "span", TagMode.StartTagAndEndTag); } - protected virtual string GetContent(string label, string inputHtml, bool isCheckbox) + protected virtual string GetContent(string label, string inputHtml, string validation, bool isCheckbox) { var innerContent = isCheckbox ? inputHtml + Environment.NewLine + label : label + Environment.NewLine + inputHtml; - return "
" + Environment.NewLine + innerContent + Environment.NewLine + "
"; + return "
" + + Environment.NewLine + innerContent + Environment.NewLine + + Environment.NewLine + validation + Environment.NewLine + + "
"; } protected virtual TagHelperOutput GetInputTag(TagHelperContext context, out bool isCheckbox) @@ -81,7 +98,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form { return ""; } - + var checkboxClass = isCheckbox ? "class=\"form-check-label\" " : ""; return "