Browse Source

Merge pull request #272 from volosoft/FormTagHelper

Form tag helper
pull/279/head
Halil İbrahim Kalkan 8 years ago
committed by GitHub
parent
commit
ff694ea5fe
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 88
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs
  2. 22
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelper.cs
  3. 184
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs
  4. 24
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs
  5. 116
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs
  6. 27
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs
  7. 86
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs
  8. 18
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpValidationAttributeTagHelper.cs
  9. 20
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpValidationAttributeTagHelperService.cs
  10. 18
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DisplayOrder.cs
  11. 9
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/FormGroupContent.cs
  12. 27
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectItems.cs
  13. 8
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectType.cs
  14. 4
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColBreakTagHelper.cs
  15. 4
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColBreakTagHelperService.cs
  16. 4
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpColumnTagHelperService.cs
  17. 3
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpContainerTagHelperService.cs
  18. 4
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Grid/AbpRowTagHelperService.cs
  19. 3
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Label/AbpLabelTagHelperService.cs
  20. 115
      test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml
  21. 75
      test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs

88
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs

@ -1,13 +1,24 @@
using System.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
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;
using Volo.Abp.Threading;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers
{
public abstract class AbpTagHelperService<TTagHelper> : IAbpTagHelperService<TTagHelper>
where TTagHelper : TagHelper
{
protected const string FormGroupContents = "FormGroupContents";
public TTagHelper TagHelper { get; set; }
public virtual int Order { get; }
public virtual void Init(TagHelperContext context)
@ -25,5 +36,78 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers
Process(context, output);
return Task.CompletedTask;
}
protected virtual TagHelperOutput GetInnerTagHelper(TagHelperAttributeList attributeList, TagHelperContext context, TagHelper tagHelper, string tagName = "div", TagMode tagMode = TagMode.SelfClosing, bool runAsync = false)
{
var innerOutput = new TagHelperOutput(tagName, attributeList, (useCachedResult, encoder) => Task.Run<TagHelperContent>(() => new DefaultTagHelperContent()))
{
TagMode = tagMode
};
var innerContext = new TagHelperContext(attributeList, context.Items, Guid.NewGuid().ToString());
if (runAsync)
{
AsyncHelper.RunSync(() => tagHelper.ProcessAsync(innerContext, innerOutput));
}
else
{
tagHelper.Process(innerContext, innerOutput);
}
return innerOutput;
}
protected virtual string RenderTagHelper(TagHelperAttributeList attributeList, TagHelperContext context, TagHelper tagHelper, HtmlEncoder htmlEncoder, string tagName = "div", TagMode tagMode = TagMode.SelfClosing, bool runAsync = false)
{
var innerOutput = GetInnerTagHelper(attributeList, context, tagHelper, tagName, tagMode, runAsync);
return RenderTagHelperOutput(innerOutput, htmlEncoder);
}
protected virtual string RenderTagHelperOutput(TagHelperOutput output, HtmlEncoder htmlEncoder)
{
using (var writer = new StringWriter())
{
output.WriteTo(writer, htmlEncoder);
return writer.ToString();
}
}
protected virtual T GetAttribute<T>(ModelExplorer property) where T : Attribute
{
return property?.Metadata?.ContainerType?.GetTypeInfo()?.GetProperty(property.Metadata.PropertyName)?.GetCustomAttribute<T>();
}
protected virtual List<FormGroupContent> GetFormGroupContentsList(TagHelperContext context)
{
return context.Items[FormGroupContents] as List<FormGroupContent>;
}
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<DisplayOrder>(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
});
}
}
}
}

22
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelper.cs

@ -0,0 +1,22 @@
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
{
public class AbpDynamicFormTagHelper : AbpTagHelper<AbpDynamicFormTagHelper, AbpDynamicFormTagHelperService>
{
[HtmlAttributeName("asp-model")]
public ModelExpression Model { get; set; }
[HtmlAttributeNotBound]
[ViewContext]
public ViewContext ViewContext { get; set; }
public AbpDynamicFormTagHelper(AbpDynamicFormTagHelperService tagHelperService)
: base(tagHelperService)
{
}
}
}

184
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpDynamicformTagHelperService.cs

@ -0,0 +1,184 @@
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;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
{
public class AbpDynamicFormTagHelperService : AbpTagHelperService<AbpDynamicFormTagHelper>
{
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 async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
var list = InitilizeFormGroupContentsContext(context);
await output.GetChildContentAsync();
ProcessFields(context, output);
SetContent(output,list);
}
protected virtual void SetContent(TagHelperOutput output, List<FormGroupContent> 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<FormGroupContent> InitilizeFormGroupContentsContext(TagHelperContext context)
{
var list = new List<FormGroupContent>();
context.Items.Add(FormGroupContents, list);
return list;
}
protected virtual void ProcessFields(TagHelperContext context, TagHelperOutput output)
{
var models = GetModels(context, output);
foreach (var model in models)
{
if (IsSelectGroup(context, model, out var selectItems))
{
ProcessSelectGroup(context, model, selectItems);
continue;
}
ProcessInputGroup(context, model);
}
}
protected virtual void ProcessSelectGroup(TagHelperContext context, ModelExpression model, IEnumerable<SelectListItem> selectItems)
{
_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)
{
_abpInputTagHelper.AspFor = model;
_abpInputTagHelper.Label = "";
_abpInputTagHelper.ViewContext = TagHelper.ViewContext;
RenderTagHelper(new TagHelperAttributeList(), context, _abpInputTagHelper, _htmlEncoder, "div", TagMode.StartTagAndEndTag);
}
protected virtual List<ModelExpression> GetModels(TagHelperContext context, TagHelperOutput output)
{
return TagHelper.Model.ModelExplorer.Properties.Aggregate(new List<ModelExpression>(), ExploreModelsRecursively);
}
protected virtual List<ModelExpression> ExploreModelsRecursively(List<ModelExpression> list, ModelExplorer model)
{
if (IsCsharpClassOrPrimitive(model.ModelType))
{
list.Add(ModelExplorerToModelExpressionConverter(model));
return list;
}
if (IsListOfSelectItem(model.ModelType))
{
return list;
}
return model.Properties.Aggregate(list, ExploreModelsRecursively);
}
protected virtual ModelExpression ModelExplorerToModelExpressionConverter(ModelExplorer 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)
{
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(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.IsEnum;
}
protected virtual bool IsListOfSelectItem(Type type)
{
return type == typeof(List<SelectListItem>) || type == typeof(IEnumerable<SelectListItem>);
}
protected virtual bool IsSelectGroup(TagHelperContext context, ModelExpression model, out IEnumerable<SelectListItem> selectItems)
{
return IsEnum(model.ModelExplorer, out selectItems) || AreSelectItemsProvided(model.ModelExplorer, out selectItems);
}
protected virtual bool IsEnum(ModelExplorer explorer, out IEnumerable<SelectListItem> selectItems)
{
selectItems = explorer.Metadata.IsEnum ? GetSelectItemsFromEnum(explorer.ModelType) : null;
return explorer.Metadata.IsEnum;
}
protected virtual IEnumerable<SelectListItem> 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<SelectListItem> selectItems)
{
selectItems = GetAttribute<SelectItems>(explorer)?.GetItems(explorer);
return selectItems != null;
}
}
}

24
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelper.cs

@ -0,0 +1,24 @@
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<AbpInputTagHelper, AbpInputTagHelperService>, ITransientDependency
{
public ModelExpression AspFor { get; set; }
public string Label { get; set; }
[HtmlAttributeNotBound]
[ViewContext]
public ViewContext ViewContext { get; set; }
public AbpInputTagHelper(AbpInputTagHelperService tagHelperService)
: base(tagHelperService)
{
}
}
}

116
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs

@ -0,0 +1,116 @@
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;
using Microsoft.Extensions.Localization;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
{
public class AbpInputTagHelperService : AbpTagHelperService<AbpInputTagHelper>
{
private readonly IHtmlGenerator _generator;
private readonly HtmlEncoder _encoder;
private readonly IStringLocalizer<AbpUiResource> _localizer;
public AbpInputTagHelperService(IHtmlGenerator generator, HtmlEncoder encoder, IStringLocalizer<AbpUiResource> localizer)
{
_generator = generator;
_encoder = encoder;
_localizer = localizer;
}
public override void Process(TagHelperContext context, TagHelperOutput output)
{
var html = GetFormInputGroupAsHtml(context, output);
var order = GetInputOrder(TagHelper.AspFor.ModelExplorer);
AddGroupToFormGroupContents(context, TagHelper.AspFor.Name, html, 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);
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", "text-danger" } };
return RenderTagHelper(attributeList, context, validationMessageTagHelper, _encoder, "span", TagMode.StartTagAndEndTag, true);
}
protected virtual string GetContent(string label, string inputHtml, string validation, bool isCheckbox)
{
var innerContent = isCheckbox ?
inputHtml + Environment.NewLine + label :
label + Environment.NewLine + inputHtml;
return "<div class=\"" + (isCheckbox ? "form-check" : "form-group") + "\">" +
Environment.NewLine + innerContent + Environment.NewLine +
Environment.NewLine + validation + Environment.NewLine +
"</div>";
}
protected virtual TagHelperOutput GetInputTag(TagHelperContext context, out bool isCheckbox)
{
var inputTagHelper = new InputTagHelper(_generator)
{
For = TagHelper.AspFor,
ViewContext = TagHelper.ViewContext
};
var inputTagHelperOutput = GetInnerTagHelper(new TagHelperAttributeList(), context, inputTagHelper, "input");
isCheckbox = IsInputCheckbox(inputTagHelperOutput.Attributes);
inputTagHelperOutput.Attributes.Add("class", isCheckbox ? "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 checkboxClass = isCheckbox ? "class=\"form-check-label\" " : "";
return "<label " + checkboxClass + GetIdAttributeAsString(inputTag) + ">"
+ _localizer[GetLabelValue()] +
"</label>";
}
protected virtual string GetLabelValue()
{
return string.IsNullOrEmpty(TagHelper.Label) ?
TagHelper.AspFor.Metadata.DisplayName :
TagHelper.Label;
}
}
}

27
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs

@ -0,0 +1,27 @@
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<AbpSelectTagHelper, AbpSelectTagHelperService>, ITransientDependency
{
public ModelExpression AspFor { get; set; }
public string Label { get; set; }
public IEnumerable<SelectListItem> AspItems { get; set; }
[HtmlAttributeNotBound]
[ViewContext]
public ViewContext ViewContext { get; set; }
public AbpSelectTagHelper(AbpSelectTagHelperService tagHelperService)
: base(tagHelperService)
{
}
}
}

86
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs

@ -0,0 +1,86 @@
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 AbpSelectTagHelperService : AbpTagHelperService<AbpSelectTagHelper>
{
private readonly IHtmlGenerator _generator;
private readonly HtmlEncoder _encoder;
private readonly IStringLocalizer<AbpUiResource> _localizer;
public AbpSelectTagHelperService(IHtmlGenerator generator, HtmlEncoder encoder, IStringLocalizer<AbpUiResource> localizer)
{
_generator = generator;
_encoder = encoder;
_localizer = localizer;
}
public override void Process(TagHelperContext context, TagHelperOutput output)
{
var html = GetFormInputGroupAsHtml(context, output);
var order = GetInputOrder(TagHelper.AspFor.ModelExplorer);
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)
{
var innerContent = label + Environment.NewLine + inputHtml;
return "<div class=\"form-group\">" + Environment.NewLine + innerContent + Environment.NewLine + "</div>";
}
protected virtual TagHelperOutput GetSelectTag(TagHelperContext context)
{
var selectTagHelper = new SelectTagHelper(_generator)
{
For = TagHelper.AspFor,
Items = TagHelper.AspItems,
ViewContext = TagHelper.ViewContext
};
var inputTagHelperOutput = GetInnerTagHelper(new TagHelperAttributeList(), context,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 "";
}
return "<label " + GetIdAttributeAsString(selectTag) + ">" + _localizer[GetLabelText()] + "</label>";
}
protected virtual string GetLabelText()
{
return string.IsNullOrEmpty(TagHelper.Label) ?
TagHelper.AspFor.Metadata.DisplayName :
TagHelper.Label;
}
}
}

18
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<AbpValidationAttributeTagHelper, AbpValidationAttributeTagHelperService>, ITransientDependency
{
public AbpValidationAttributeTagHelper(AbpValidationAttributeTagHelperService tagHelperService)
: base(tagHelperService)
{
}
}
}

20
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<AbpValidationAttributeTagHelper>
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.Attributes.Add("class","text-danger");
}
}
}

18
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;
}
}
}

9
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/FormGroupContent.cs

@ -0,0 +1,9 @@
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
{
public class FormGroupContent
{
public string Html { get; set; }
public int Order { get; set; }
}
}

27
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/SelectItems.cs

@ -0,0 +1,27 @@
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 string ItemsListPropertyName { get; set; }
public SelectType SelectType { get; set; } = SelectType.Dropdown;
public IEnumerable<SelectListItem> GetItems(ModelExplorer explorer)
{
var properties = explorer.Container.Properties.Where(p => p.Metadata.PropertyName.Equals(ItemsListPropertyName)).ToList();
return properties.Count > 0
? properties.First().Model as IEnumerable<SelectListItem>
: null;
}
}
}

8
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
}
}

4
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<AbpColBreakTagHelper, AbpColBreakTagHelperService>
{

4
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

4
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

3
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

4
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

3
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
{

115
test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml

@ -1,23 +1,128 @@
@page
@model Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components.FormsModel
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components
@model FormsModel
@{
ViewData["Title"] = "Forms";
ViewData["Title"] = "Forms";
}
<h2>Forms</h2>
<p>Based on <a href="http://getbootstrap.com/docs/4.1/components/forms/" target="_blank"> Bootstrap form</a>.</p>
<h4># Example</h4>
<h4># Dynamic Form Example</h4>
<div class="demo-with-code">
<div class="demo-area">
<abp-dynamic-form asp-model="@Model.Ahmet">
</abp-dynamic-form>
</div>
<div class="code-area">
<pre>
<pre>
&lt;abp-dynamic-form asp-model=&quot;Model.Ahmet&quot; &gt;
&lt;/abp-dynamic-form&gt;
</pre>
</div>
</div>
@*<h4># Input Group Example</h4>
<div class="demo-with-code">
<div class="demo-area">
<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>
</div>
<div class="code-area">
<pre>
&lt;form method=&quot;post&quot; action=&quot;#&quot;&gt;
&lt;abp-input asp-for=&quot;Model.Name&quot;/&gt;
&lt;abp-input asp-for=&quot;Model.Password&quot; label=&quot;Password&quot;/&gt;
&lt;abp-input asp-for=&quot;Model.IsActive&quot; /&gt;
&lt;abp-input asp-for=&quot;Model.PhoneNumber&quot; /&gt;
&lt;abp-input asp-for=&quot;Model.EmailAddress&quot; /&gt;
&lt;abp-input asp-for=&quot;Model.Count&quot; /&gt;
&lt;abp-input asp-for=&quot;Model.Day&quot; /&gt;
&lt;abp-select asp-for=&quot;Model.Country&quot; asp-items=&quot;Model.Countries&quot; label=&quot;Country&quot;&gt;&lt;/abp-select&gt;
&lt;abp-select asp-for=&quot;Model.City&quot; asp-items=&quot;Html.GetEnumSelectList(typeof(Cities))&quot;&gt;&lt;/abp-select&gt;
&lt;/form&gt;
</pre>
</div>
</div>*@
@*<div class="demo-with-code">
<div class="demo-area">
<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>
</div>
<div class="code-area">
<pre>
&lt;form method=&quot;post&quot; action=&quot;#&quot;&gt;
&lt;abp-form-group&gt;
&lt;abp-select asp-for=&quot;@Model.Country&quot; asp-items=&quot;@Model.Countries&quot;&gt;&lt;/abp-select&gt;
&lt;/abp-form-group&gt;
&lt;abp-form-group&gt;
&lt;abp-select asp-for=&quot;@Model.City&quot; asp-items=&quot;@Html.GetEnumSelectList(typeof(Cities))&quot;&gt;&lt;/abp-select&gt;
&lt;/abp-form-group&gt;
&lt;abp-form-group&gt;
&lt;abp-input asp-for=&quot;@Model.Name&quot; /&gt;
&lt;/abp-form-group&gt;
&lt;abp-form-group&gt;
&lt;abp-input asp-for=&quot;@Model.Password&quot; /&gt;
&lt;/abp-form-group&gt;
&lt;abp-form-group&gt;
&lt;abp-input asp-for=&quot;@Model.PhoneNumber&quot; /&gt;
&lt;/abp-form-group&gt;
&lt;abp-form-group&gt;
&lt;abp-input asp-for=&quot;@Model.EmailAddress&quot; /&gt;
&lt;/abp-form-group&gt;
&lt;abp-form-group&gt;
&lt;abp-input asp-for=&quot;@Model.Count&quot; /&gt;
&lt;/abp-form-group&gt;
&lt;abp-form-group&gt;
&lt;abp-input asp-for=&quot;@Model.Day&quot; /&gt;
&lt;/abp-form-group&gt;
&lt;abp-form-group&gt;
&lt;abp-input asp-for=&quot;@Model.IsActive&quot; /&gt;
&lt;/abp-form-group&gt;
&lt;/form&gt;
</pre>
</div>
</div>*@

75
test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Forms.cshtml.cs

@ -1,12 +1,83 @@
using Microsoft.AspNetCore.Mvc.RazorPages;
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;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components
{
public class FormsModel : PageModel
{
public PersonViewModel Ahmet { get; set; } = new PersonViewModel();
public void OnGet()
{
Ahmet = new PersonViewModel
{
Name = "ahmet",
Age = 65,
Phone = new Phone {Number = "326346231",Name = "MyPhone"}
};
}
}
public enum Cities
{
Istanbul,
NewJersey,
Moscow
}
public class PersonViewModel
{
[Required]
[DisplayName("Name")]
public string Name { get; set; } = "MyName";
[Required]
[DisplayOrder(61)]
[DisplayName("Age")]
[Range(1, 100)]
public int Age { get; set; }
[Required]
[DisplayName("City")]
public Cities City { get; set; }
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; }
[DisplayName("Country")]
[SelectItems(ItemsListPropertyName = nameof(Countries))]
public string Country { get; set; }
public List<SelectListItem> Countries { get; set; } = new List<SelectListItem>
{
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]
[DisplayOrder(71)]
[DisplayName("PhoneName")]
public string Name { get; set; }
}
}
Loading…
Cancel
Save