From bf12f5bf5ffc16a27fc12edb4d837d283361e44e Mon Sep 17 00:00:00 2001 From: blackWinds <745673576@qq.com> Date: Sun, 19 Oct 2025 20:30:35 +0800 Subject: [PATCH] Add label and info to AbpRadioInput --- .../TagHelpers/Form/AbpRadioInputTagHelper.cs | 5 + .../Form/AbpRadioInputTagHelperService.cs | 153 ++++++++++++++++-- 2 files changed, 148 insertions(+), 10 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpRadioInputTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpRadioInputTagHelper.cs index 0135d136ba..c97b7c1e69 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpRadioInputTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpRadioInputTagHelper.cs @@ -12,6 +12,11 @@ public class AbpRadioInputTagHelper : AbpTagHelper { private readonly IAbpTagHelperLocalizer _tagHelperLocalizer; - - public AbpRadioInputTagHelperService(IAbpTagHelperLocalizer tagHelperLocalizer) + private readonly IHtmlGenerator _generator; + private readonly HtmlEncoder _encoder; + private readonly IStringLocalizerFactory _stringLocalizerFactory; + private readonly IAbpEnumLocalizer _abpEnumLocalizer; + + public AbpRadioInputTagHelperService( + IAbpTagHelperLocalizer tagHelperLocalizer, + IHtmlGenerator generator, + HtmlEncoder encoder, + IStringLocalizerFactory stringLocalizerFactory, + IAbpEnumLocalizer abpEnumLocalizer) { _tagHelperLocalizer = tagHelperLocalizer; + _generator = generator; + _encoder = encoder; + _stringLocalizerFactory = stringLocalizerFactory; + _abpEnumLocalizer = abpEnumLocalizer; } - public override void Process(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { var selectItems = GetSelectItems(context, output); SetSelectedValue(context, output, selectItems); var order = TagHelper.AspFor.ModelExplorer.GetDisplayOrder(); - var html = GetHtml(context, output, selectItems); + var html = await GetRadioInputGroupAsHtmlAsync(context, output, selectItems); AddGroupToFormGroupContents(context, TagHelper.AspFor.Name, html, order, out var suppress); @@ -44,6 +62,21 @@ public class AbpRadioInputTagHelperService : AbpTagHelperService GetRadioInputGroupAsHtmlAsync(TagHelperContext context, TagHelperOutput output, List selectItems) + { + var radioGroupHtml = GetHtml(context, output, selectItems); + var label = await GetLabelAsHtmlAsync(context, output); + var infoText = GetInfoAsHtml(context, output); + + var tagBuilder = new TagBuilder("div"); + tagBuilder.AddCssClass("mb-3"); + tagBuilder.InnerHtml.AppendHtml(label); + tagBuilder.InnerHtml.AppendHtml(radioGroupHtml); + tagBuilder.InnerHtml.AppendHtml(infoText); + + return tagBuilder.ToHtmlString(); + } + protected virtual string GetHtml(TagHelperContext context, TagHelperOutput output, List selectItems) { var html = new StringBuilder(""); @@ -77,14 +110,92 @@ public class AbpRadioInputTagHelperService : AbpTagHelperService GetLabelAsHtmlAsync(TagHelperContext context, TagHelperOutput output) + { + if (TagHelper.SuppressLabel) + { + return string.Empty; + } + + if (string.IsNullOrEmpty(TagHelper.Label)) + { + return await GetLabelAsHtmlUsingTagHelperAsync(context, output); + } + + var label = new TagBuilder("label"); + label.AddCssClass("form-label"); + label.InnerHtml.AppendHtml(TagHelper.Label); + label.InnerHtml.AppendHtml(GetRequiredSymbol(context, output)); + + return label.ToHtmlString(); + } + + protected virtual async Task GetLabelAsHtmlUsingTagHelperAsync(TagHelperContext context, TagHelperOutput output) + { + var labelTagHelper = new LabelTagHelper(_generator) + { + For = TagHelper.AspFor, + ViewContext = TagHelper.ViewContext, + }; + + var innerOutput = await labelTagHelper.ProcessAndGetOutputAsync( + new TagHelperAttributeList { { "class", "form-label" } }, + context, + "label", + TagMode.StartTagAndEndTag); + + innerOutput.Content.AppendHtml(GetRequiredSymbol(context, output)); + + return innerOutput.Render(_encoder); + } + + protected virtual string GetRequiredSymbol(TagHelperContext context, TagHelperOutput output) + { + var isHaveRequiredAttribute = context.AllAttributes.Any(a => a.Name == "required"); + + return TagHelper.AspFor.ModelExplorer.GetAttribute() != null || isHaveRequiredAttribute + ? " * " + : ""; + } + + protected virtual string GetInfoAsHtml(TagHelperContext context, TagHelperOutput output) + { + var text = string.Empty; + var infoAttribute = TagHelper.AspFor.ModelExplorer.GetAttribute(); + + if (!string.IsNullOrEmpty(TagHelper.InfoText)) + { + text = TagHelper.InfoText!; + } + else if (infoAttribute != null) + { + text = _tagHelperLocalizer.GetLocalizedText(infoAttribute.Text, TagHelper.AspFor.ModelExplorer); + } + else + { + return ""; + } + + var small = new TagBuilder("small"); + small.Attributes.Add("id", TagHelper.AspFor.Name.Replace('.', '_') + "InfoText"); + small.AddCssClass("form-text"); + small.InnerHtml.Append(text); + + return small.ToHtmlString(); } protected virtual List GetSelectItems(TagHelperContext context, TagHelperOutput output) @@ -110,10 +221,32 @@ public class AbpRadioInputTagHelperService : AbpTagHelperService GetSelectItemsFromEnum(TagHelperContext context, TagHelperOutput output, ModelExplorer explorer) { - var localizer = _tagHelperLocalizer.GetLocalizerOrNull(explorer); + var selectItems = new List(); + var isNullableType = Nullable.GetUnderlyingType(explorer.ModelType) != null; + var enumType = explorer.ModelType; + + if (isNullableType) + { + enumType = Nullable.GetUnderlyingType(explorer.ModelType)!; + selectItems.Add(new SelectListItem()); + } + + var containerLocalizer = _tagHelperLocalizer.GetLocalizerOrNull(explorer.Container.ModelType.Assembly); - var selectItems = explorer.Metadata.IsEnum ? explorer.ModelType.GetTypeInfo().GetMembers(BindingFlags.Public | BindingFlags.Static) - .Select((t, i) => new SelectListItem { Value = i.ToString(), Text = GetLocalizedPropertyName(localizer, explorer.ModelType, t.Name) }).ToList() : new List(); + foreach (var enumValue in enumType.GetEnumValuesAsUnderlyingType()) + { + var localizedMemberName = _abpEnumLocalizer.GetString(enumType, enumValue, + new[] + { + containerLocalizer, + _stringLocalizerFactory.CreateDefaultOrNull() + }!); + selectItems.Add(new SelectListItem + { + Value = enumValue.ToString(), + Text = localizedMemberName + }); + } return selectItems; }