1- using Microsoft . AspNetCore . Mvc . Rendering ;
1+ using Microsoft . AspNetCore . Mvc . Rendering ;
22using Microsoft . AspNetCore . Mvc . ViewFeatures ;
33using Microsoft . AspNetCore . Razor . TagHelpers ;
44using Microsoft . Extensions . Localization ;
55using System ;
66using System . Collections . Generic ;
7+ using System . ComponentModel . DataAnnotations ;
78using System . Linq ;
89using System . Reflection ;
910using System . Text ;
11+ using System . Text . Encodings . Web ;
12+ using System . Threading . Tasks ;
13+ using Microsoft . AspNetCore . Mvc . TagHelpers ;
1014using Volo . Abp . AspNetCore . Mvc . UI . Bootstrap . TagHelpers . Extensions ;
15+ using Volo . Abp . Localization ;
1116
1217namespace Volo . Abp . AspNetCore . Mvc . UI . Bootstrap . TagHelpers . Form ;
1318
1419public class AbpRadioInputTagHelperService : AbpTagHelperService < AbpRadioInputTagHelper >
1520{
1621 private readonly IAbpTagHelperLocalizer _tagHelperLocalizer ;
17-
18- public AbpRadioInputTagHelperService ( IAbpTagHelperLocalizer tagHelperLocalizer )
22+ private readonly IHtmlGenerator _generator ;
23+ private readonly HtmlEncoder _encoder ;
24+ private readonly IStringLocalizerFactory _stringLocalizerFactory ;
25+ private readonly IAbpEnumLocalizer _abpEnumLocalizer ;
26+
27+ public AbpRadioInputTagHelperService (
28+ IAbpTagHelperLocalizer tagHelperLocalizer ,
29+ IHtmlGenerator generator ,
30+ HtmlEncoder encoder ,
31+ IStringLocalizerFactory stringLocalizerFactory ,
32+ IAbpEnumLocalizer abpEnumLocalizer )
1933 {
2034 _tagHelperLocalizer = tagHelperLocalizer ;
35+ _generator = generator ;
36+ _encoder = encoder ;
37+ _stringLocalizerFactory = stringLocalizerFactory ;
38+ _abpEnumLocalizer = abpEnumLocalizer ;
2139 }
2240
23- public override void Process ( TagHelperContext context , TagHelperOutput output )
41+ public override async Task ProcessAsync ( TagHelperContext context , TagHelperOutput output )
2442 {
2543 var selectItems = GetSelectItems ( context , output ) ;
2644 SetSelectedValue ( context , output , selectItems ) ;
2745
2846 var order = TagHelper . AspFor . ModelExplorer . GetDisplayOrder ( ) ;
2947
30- var html = GetHtml ( context , output , selectItems ) ;
48+ var html = await GetRadioInputGroupAsHtmlAsync ( context , output , selectItems ) ;
3149
3250 AddGroupToFormGroupContents ( context , TagHelper . AspFor . Name , html , order , out var suppress ) ;
3351
@@ -44,6 +62,21 @@ public override void Process(TagHelperContext context, TagHelperOutput output)
4462 }
4563 }
4664
65+ protected virtual async Task < string > GetRadioInputGroupAsHtmlAsync ( TagHelperContext context , TagHelperOutput output , List < SelectListItem > selectItems )
66+ {
67+ var radioGroupHtml = GetHtml ( context , output , selectItems ) ;
68+ var label = await GetLabelAsHtmlAsync ( context , output ) ;
69+ var infoText = GetInfoAsHtml ( context , output ) ;
70+
71+ var tagBuilder = new TagBuilder ( "div" ) ;
72+ tagBuilder . AddCssClass ( "mb-3" ) ;
73+ tagBuilder . InnerHtml . AppendHtml ( label ) ;
74+ tagBuilder . InnerHtml . AppendHtml ( radioGroupHtml ) ;
75+ tagBuilder . InnerHtml . AppendHtml ( infoText ) ;
76+
77+ return tagBuilder . ToHtmlString ( ) ;
78+ }
79+
4780 protected virtual string GetHtml ( TagHelperContext context , TagHelperOutput output , List < SelectListItem > selectItems )
4881 {
4982 var html = new StringBuilder ( "" ) ;
@@ -77,14 +110,92 @@ protected virtual string GetHtml(TagHelperContext context, TagHelperOutput outpu
77110 label . InnerHtml . AppendHtml ( selectItem . Text ) ;
78111
79112 var wrapper = new TagBuilder ( "div" ) ;
80- wrapper . AddCssClass ( "form-check" + inlineClass ) ;
113+ wrapper . AddCssClass ( "form-check mb-1 " + inlineClass ) ;
81114 wrapper . InnerHtml . AppendHtml ( input ) ;
82115 wrapper . InnerHtml . AppendHtml ( label ) ;
83116
84117 html . AppendLine ( wrapper . ToHtmlString ( ) ) ;
85118 }
86119
87- return html . ToString ( ) ;
120+ var div = new TagBuilder ( "div" ) ;
121+ div . AddCssClass ( "mb-1" ) ;
122+ div . InnerHtml . AppendHtml ( html . ToString ( ) ) ;
123+
124+ return div . ToHtmlString ( ) ;
125+ }
126+
127+ protected virtual async Task < string > GetLabelAsHtmlAsync ( TagHelperContext context , TagHelperOutput output )
128+ {
129+ if ( TagHelper . SuppressLabel )
130+ {
131+ return string . Empty ;
132+ }
133+
134+ if ( string . IsNullOrEmpty ( TagHelper . Label ) )
135+ {
136+ return await GetLabelAsHtmlUsingTagHelperAsync ( context , output ) ;
137+ }
138+
139+ var label = new TagBuilder ( "label" ) ;
140+ label . AddCssClass ( "form-label" ) ;
141+ label . InnerHtml . AppendHtml ( TagHelper . Label ) ;
142+ label . InnerHtml . AppendHtml ( GetRequiredSymbol ( context , output ) ) ;
143+
144+ return label . ToHtmlString ( ) ;
145+ }
146+
147+ protected virtual async Task < string > GetLabelAsHtmlUsingTagHelperAsync ( TagHelperContext context , TagHelperOutput output )
148+ {
149+ var labelTagHelper = new LabelTagHelper ( _generator )
150+ {
151+ For = TagHelper . AspFor ,
152+ ViewContext = TagHelper . ViewContext ,
153+ } ;
154+
155+ var innerOutput = await labelTagHelper . ProcessAndGetOutputAsync (
156+ new TagHelperAttributeList { { "class" , "form-label" } } ,
157+ context ,
158+ "label" ,
159+ TagMode . StartTagAndEndTag ) ;
160+
161+ innerOutput . Content . AppendHtml ( GetRequiredSymbol ( context , output ) ) ;
162+
163+ return innerOutput . Render ( _encoder ) ;
164+ }
165+
166+ protected virtual string GetRequiredSymbol ( TagHelperContext context , TagHelperOutput output )
167+ {
168+ var isHaveRequiredAttribute = context . AllAttributes . Any ( a => a . Name == "required" ) ;
169+
170+ return TagHelper . AspFor . ModelExplorer . GetAttribute < RequiredAttribute > ( ) != null || isHaveRequiredAttribute
171+ ? "<span> * </span>"
172+ : "" ;
173+ }
174+
175+ protected virtual string GetInfoAsHtml ( TagHelperContext context , TagHelperOutput output )
176+ {
177+ var text = string . Empty ;
178+ var infoAttribute = TagHelper . AspFor . ModelExplorer . GetAttribute < InputInfoText > ( ) ;
179+
180+ if ( ! string . IsNullOrEmpty ( TagHelper . InfoText ) )
181+ {
182+ text = TagHelper . InfoText ! ;
183+ }
184+ else if ( infoAttribute != null )
185+ {
186+ text = _tagHelperLocalizer . GetLocalizedText ( infoAttribute . Text , TagHelper . AspFor . ModelExplorer ) ;
187+ }
188+ else
189+ {
190+ return "" ;
191+ }
192+
193+ var small = new TagBuilder ( "small" ) ;
194+ small . Attributes . Add ( "id" , TagHelper . AspFor . Name . Replace ( '.' , '_' ) + "InfoText" ) ;
195+ small . AddCssClass ( "form-text" ) ;
196+ small . InnerHtml . Append ( text ) ;
197+
198+ return small . ToHtmlString ( ) ;
88199 }
89200
90201 protected virtual List < SelectListItem > GetSelectItems ( TagHelperContext context , TagHelperOutput output )
@@ -110,10 +221,32 @@ protected virtual List<SelectListItem> GetSelectItems(TagHelperContext context,
110221
111222 protected virtual List < SelectListItem > GetSelectItemsFromEnum ( TagHelperContext context , TagHelperOutput output , ModelExplorer explorer )
112223 {
113- var localizer = _tagHelperLocalizer . GetLocalizerOrNull ( explorer ) ;
224+ var selectItems = new List < SelectListItem > ( ) ;
225+ var isNullableType = Nullable . GetUnderlyingType ( explorer . ModelType ) != null ;
226+ var enumType = explorer . ModelType ;
227+
228+ if ( isNullableType )
229+ {
230+ enumType = Nullable . GetUnderlyingType ( explorer . ModelType ) ! ;
231+ selectItems . Add ( new SelectListItem ( ) ) ;
232+ }
233+
234+ var containerLocalizer = _tagHelperLocalizer . GetLocalizerOrNull ( explorer . Container . ModelType . Assembly ) ;
114235
115- var selectItems = explorer . Metadata . IsEnum ? explorer . ModelType . GetTypeInfo ( ) . GetMembers ( BindingFlags . Public | BindingFlags . Static )
116- . Select ( ( t , i ) => new SelectListItem { Value = i . ToString ( ) , Text = GetLocalizedPropertyName ( localizer , explorer . ModelType , t . Name ) } ) . ToList ( ) : new List < SelectListItem > ( ) ;
236+ foreach ( var enumValue in enumType . GetEnumValuesAsUnderlyingType ( ) )
237+ {
238+ var localizedMemberName = _abpEnumLocalizer . GetString ( enumType , enumValue ,
239+ new [ ]
240+ {
241+ containerLocalizer ,
242+ _stringLocalizerFactory . CreateDefaultOrNull ( )
243+ } ! ) ;
244+ selectItems . Add ( new SelectListItem
245+ {
246+ Value = enumValue . ToString ( ) ,
247+ Text = localizedMemberName
248+ } ) ;
249+ }
117250
118251 return selectItems ;
119252 }
0 commit comments