1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . Linq ;
4+ using ChameleonForms . Component ;
5+ using ChameleonForms . Component . Config ;
6+ using ChameleonForms . Enums ;
7+ using ChameleonForms . FieldGenerators ;
8+ using ChameleonForms . FieldGenerators . Handlers ;
9+ using ChameleonForms . Templates . ChameleonFormsBootstrap4Template ;
10+ using ChameleonForms . Templates . ChameleonFormsBootstrap4Template . Params ;
11+ using Humanizer ;
12+ using Microsoft . AspNetCore . Html ;
13+ using Microsoft . AspNetCore . Mvc . ModelBinding ;
14+ using Microsoft . AspNetCore . Mvc . Rendering ;
15+ using RazorRenderer ;
16+
17+ namespace ChameleonForms . Templates . Bootstrap4
18+ {
19+ /// <summary>
20+ /// The default Chameleon Forms form template renderer.
21+ /// </summary>
22+ public class Bootstrap4FormTemplate : Default . DefaultFormTemplate
23+ {
24+ private static readonly IEnumerable < string > StyledButtonClasses = Enum . GetNames ( typeof ( ButtonStyle ) )
25+ . Select ( x => x . Humanize ( ) )
26+ . ToArray ( ) ;
27+
28+ private static readonly FieldDisplayType [ ] NormalFieldTypes = new [ ] { FieldDisplayType . DropDown , FieldDisplayType . SingleLineText , FieldDisplayType . MultiLineText } ;
29+
30+ /// <inheritdoc />
31+ public override void PrepareFieldConfiguration < TModel , T > ( IFieldGenerator < TModel , T > fieldGenerator , IFieldGeneratorHandler < TModel , T > fieldGeneratorHandler , IFieldConfiguration fieldConfiguration , FieldParent fieldParent )
32+ {
33+ if ( fieldParent == FieldParent . Form )
34+ return ;
35+
36+ fieldConfiguration . InlineLabelWrapsElement ( ) ;
37+
38+ fieldConfiguration . AddValidationClass ( "invalid-feedback" ) ;
39+
40+ var displayType = fieldGeneratorHandler . GetDisplayType ( fieldConfiguration ) ;
41+ if ( NormalFieldTypes . Contains ( displayType ) )
42+ {
43+ fieldConfiguration . Bag . CanBeInputGroup = true ;
44+ fieldConfiguration . AddClass ( "form-control" ) ;
45+ }
46+
47+ if ( displayType == FieldDisplayType . Checkbox )
48+ {
49+ fieldConfiguration . Bag . IsCheckboxControl = true ;
50+ // Hide the parent label otherwise it looks weird
51+ fieldConfiguration . Label ( "" ) . WithoutLabelElement ( ) ;
52+ }
53+
54+ if ( displayType == FieldDisplayType . List )
55+ fieldConfiguration . Bag . IsRadioOrCheckboxList = true ;
56+ }
57+
58+ /// <inheritdoc />
59+ public override IHtmlContent BeginForm ( string action , FormMethod method , HtmlAttributes htmlAttributes , EncType ? enctype , bool formSubmitted )
60+ {
61+ if ( formSubmitted )
62+ htmlAttributes . AddClass ( "was-validated" ) ;
63+ return HtmlCreator . BuildFormTag ( action , method , htmlAttributes , enctype ) ;
64+ }
65+
66+ /// <inheritdoc />
67+ public override IHtmlContent EndForm ( )
68+ {
69+ return new EndForm ( ) . Render ( ) ;
70+ }
71+
72+ /// <inheritdoc />
73+ public override IHtmlContent BeginSection ( IHtmlContent heading = null , IHtmlContent leadingHtml = null , HtmlAttributes htmlAttributes = null )
74+ {
75+ return new BeginSection ( ) . Render ( new BeginSectionParams { Heading = heading , LeadingHtml = leadingHtml , HtmlAttributes = htmlAttributes ?? new HtmlAttributes ( ) } ) ;
76+ }
77+
78+ /// <inheritdoc />
79+ public override IHtmlContent EndSection ( )
80+ {
81+ return new EndSection ( ) . Render ( ) ;
82+ }
83+
84+ /// <inheritdoc />
85+ public override IHtmlContent BeginNestedSection ( IHtmlContent heading = null , IHtmlContent leadingHtml = null , HtmlAttributes htmlAttributes = null )
86+ {
87+ return new BeginNestedSection ( ) . Render ( new BeginSectionParams { Heading = heading , LeadingHtml = leadingHtml , HtmlAttributes = htmlAttributes ?? new HtmlAttributes ( ) } ) ;
88+ }
89+
90+ /// <inheritdoc />
91+ public override IHtmlContent EndNestedSection ( )
92+ {
93+ return new EndNestedSection ( ) . Render ( ) ;
94+ }
95+
96+ /// <inheritdoc />
97+ public override IHtmlContent Field ( IHtmlContent labelHtml , IHtmlContent elementHtml , IHtmlContent validationHtml , ModelMetadata fieldMetadata , IReadonlyFieldConfiguration fieldConfiguration , bool isValid )
98+ {
99+ return new Field ( ) . Render ( new FieldParams
100+ {
101+ RenderMode = FieldRenderMode . Field , LabelHtml = labelHtml , ElementHtml = elementHtml ,
102+ ValidationHtml = validationHtml , FieldMetadata = fieldMetadata , FieldConfiguration = fieldConfiguration ,
103+ IsValid = isValid , RequiredDesignator = RequiredDesignator ( fieldMetadata , fieldConfiguration , isValid )
104+ } ) ;
105+ }
106+
107+ /// <inheritdoc />
108+ public override IHtmlContent BeginField ( IHtmlContent labelHtml , IHtmlContent elementHtml , IHtmlContent validationHtml , ModelMetadata fieldMetadata , IReadonlyFieldConfiguration fieldConfiguration , bool isValid )
109+ {
110+ return new Field ( ) . Render ( new FieldParams
111+ {
112+ RenderMode = FieldRenderMode . BeginField ,
113+ LabelHtml = labelHtml ,
114+ ElementHtml = elementHtml ,
115+ ValidationHtml = validationHtml ,
116+ FieldMetadata = fieldMetadata ,
117+ FieldConfiguration = fieldConfiguration ,
118+ IsValid = isValid ,
119+ RequiredDesignator = RequiredDesignator ( fieldMetadata , fieldConfiguration , isValid )
120+ } ) ;
121+ }
122+
123+ /// <inheritdoc />
124+ protected override IHtmlContent RequiredDesignator ( ModelMetadata fieldMetadata , IReadonlyFieldConfiguration fieldConfiguration , bool isValid )
125+ {
126+ return new RequiredDesignator ( ) . Render ( ) ;
127+ }
128+
129+ /// <inheritdoc />
130+ public override IHtmlContent EndField ( )
131+ {
132+ return new EndField ( ) . Render ( ) ;
133+ }
134+
135+ /// <inheritdoc />
136+ public override IHtmlContent BeginMessage ( MessageType messageType , IHtmlContent heading )
137+ {
138+ string alertType ;
139+ switch ( messageType )
140+ {
141+ case MessageType . Warning :
142+ alertType = "warning" ;
143+ break ;
144+ case MessageType . Action :
145+ alertType = "primary" ;
146+ break ;
147+ case MessageType . Failure :
148+ alertType = "danger" ;
149+ break ;
150+ case MessageType . Success :
151+ alertType = "success" ;
152+ break ;
153+ default :
154+ alertType = "info" ;
155+ break ;
156+ }
157+
158+ return new BeginAlert ( ) . Render ( new AlertParams { AlertType = alertType , Heading = heading } ) ;
159+ }
160+
161+ /// <inheritdoc />
162+ public override IHtmlContent EndMessage ( )
163+ {
164+ return new EndAlert ( ) . Render ( ) ;
165+ }
166+
167+ /// <inheritdoc />
168+ public override IHtmlContent BeginNavigation ( )
169+ {
170+ return new BeginNavigation ( ) . Render ( ) ;
171+ }
172+
173+ /// <inheritdoc />
174+ public override IHtmlContent EndNavigation ( )
175+ {
176+ return new EndNavigation ( ) . Render ( ) ;
177+ }
178+
179+ /// <inheritdoc />
180+ public override IHtmlContent Button ( IHtmlContent content , string type , string id , string value , HtmlAttributes htmlAttributes )
181+ {
182+ htmlAttributes = htmlAttributes ?? new HtmlAttributes ( ) ;
183+ htmlAttributes . AddClass ( "btn" ) ;
184+ if ( ! StyledButtonClasses . Any ( c => htmlAttributes . Attributes [ "class" ] . Contains ( c ) ) )
185+ htmlAttributes . AddClass ( "btn-light" ) ;
186+
187+ return base . Button ( content , type , id , value , htmlAttributes ) ;
188+ }
189+
190+ /// <inheritdoc />
191+ public override IHtmlContent RadioOrCheckboxList ( IEnumerable < IHtmlContent > list , bool isCheckbox )
192+ {
193+ return new RadioOrCheckboxList ( ) . Render ( new ListParams { Items = list , IsCheckbox = isCheckbox } ) ;
194+ }
195+ }
196+ }
0 commit comments