1
+ using FormCraft . DemoBlazorApp . Components . Shared ;
2
+ using FormCraft . DemoBlazorApp . Models ;
3
+ using MudBlazor ;
4
+ using Microsoft . AspNetCore . Components ;
5
+
6
+ namespace FormCraft . DemoBlazorApp . Components . Pages ;
7
+
8
+ public partial class AttributeBasedForms : ComponentBase
9
+ {
10
+ private UserRegistrationModel _model = new ( ) ;
11
+ private IFormConfiguration < UserRegistrationModel > ? _formConfiguration ;
12
+ private bool _isSubmitted = false ;
13
+ private bool _isSubmitting = false ;
14
+
15
+ private readonly List < FormGuidelines . GuidelineItem > _sidebarFeatures =
16
+ [
17
+ new ( ) { Icon = Icons . Material . Filled . TextFields , Text = "[TextField] - Text inputs" } ,
18
+ new ( ) { Icon = Icons . Material . Filled . Email , Text = "[EmailField] - Email validation" } ,
19
+ new ( ) { Icon = Icons . Material . Filled . Numbers , Text = "[NumberField] - Numeric inputs" } ,
20
+ new ( ) { Icon = Icons . Material . Filled . DateRange , Text = "[DateField] - Date pickers" } ,
21
+ new ( ) { Icon = Icons . Material . Filled . ArrowDropDown , Text = "[SelectField] - Dropdowns" } ,
22
+ new ( ) { Icon = Icons . Material . Filled . CheckBox , Text = "[CheckboxField] - Checkboxes" } ,
23
+ new ( ) { Icon = Icons . Material . Filled . Notes , Text = "[TextArea] - Multiline text" } ,
24
+ new ( ) { Icon = Icons . Material . Filled . Check , Text = "Automatic validation" } ,
25
+ new ( ) { Icon = Icons . Material . Filled . Speed , Text = "Zero configuration" }
26
+ ] ;
27
+
28
+ private readonly List < GuidelineItem > _apiGuidelineTableItems =
29
+ [
30
+ new ( )
31
+ {
32
+ Feature = "TextField Attribute" ,
33
+ Usage = "Basic text input fields" ,
34
+ Example = "[TextField(\" First Name\" , \" Enter name\" )]"
35
+ } ,
36
+ new ( )
37
+ {
38
+ Feature = "EmailField Attribute" ,
39
+ Usage = "Email with format validation" ,
40
+ Example = "[EmailField(\" Email Address\" )]"
41
+ } ,
42
+ new ( )
43
+ {
44
+ Feature = "NumberField Attribute" ,
45
+ Usage = "Numeric inputs with min/max" ,
46
+ Example = "[NumberField(\" Age\" )] [Range(18, 120)]"
47
+ } ,
48
+ new ( )
49
+ {
50
+ Feature = "DateField Attribute" ,
51
+ Usage = "Date picker fields" ,
52
+ Example = "[DateField(\" Birth Date\" )]"
53
+ } ,
54
+ new ( )
55
+ {
56
+ Feature = "SelectField Attribute" ,
57
+ Usage = "Dropdown with options" ,
58
+ Example = "[SelectField(\" Country\" , \" USA\" , \" Canada\" , ...)]"
59
+ } ,
60
+ new ( )
61
+ {
62
+ Feature = "CheckboxField Attribute" ,
63
+ Usage = "Boolean checkbox fields" ,
64
+ Example = "[CheckboxField(\" I agree\" , \" Accept terms\" )]"
65
+ } ,
66
+ new ( )
67
+ {
68
+ Feature = "TextArea Attribute" ,
69
+ Usage = "Multiline text input" ,
70
+ Example = "[TextArea(\" Comments\" , \" Your feedback\" )]"
71
+ } ,
72
+ new ( )
73
+ {
74
+ Feature = "Validation Attributes" ,
75
+ Usage = "Standard DataAnnotations" ,
76
+ Example = "[Required] [MinLength(2)] [MaxLength(50)]"
77
+ }
78
+ ] ;
79
+
80
+ protected override void OnInitialized ( )
81
+ {
82
+ // Generate the entire form configuration from attributes with just one line!
83
+ _formConfiguration = FormBuilder < UserRegistrationModel >
84
+ . Create ( )
85
+ . AddFieldsFromAttributes ( )
86
+ . Build ( ) ;
87
+ }
88
+
89
+ private async Task HandleValidSubmit ( )
90
+ {
91
+ _isSubmitting = true ;
92
+ StateHasChanged ( ) ;
93
+
94
+ // Simulate async operation
95
+ await Task . Delay ( 1500 ) ;
96
+
97
+ _isSubmitting = false ;
98
+ _isSubmitted = true ;
99
+ StateHasChanged ( ) ;
100
+
101
+ // Hide success message after 5 seconds
102
+ await Task . Delay ( 5000 ) ;
103
+ _isSubmitted = false ;
104
+ StateHasChanged ( ) ;
105
+ }
106
+
107
+ private void ResetForm ( )
108
+ {
109
+ _model = new UserRegistrationModel ( ) ;
110
+ _isSubmitted = false ;
111
+ _isSubmitting = false ;
112
+ StateHasChanged ( ) ;
113
+ }
114
+
115
+ private List < FormSuccessDisplay . DataDisplayItem > GetDataDisplayItems ( )
116
+ {
117
+ return
118
+ [
119
+ new ( ) { Label = "Name" , Value = $ "{ _model . FirstName } { _model . LastName } " } ,
120
+ new ( ) { Label = "Email" , Value = _model . Email } ,
121
+ new ( ) { Label = "Age" , Value = _model . Age . ToString ( ) } ,
122
+ new ( ) { Label = "Birth Date" , Value = _model . DateOfBirth . ToShortDateString ( ) } ,
123
+ new ( ) { Label = "Country" , Value = _model . Country } ,
124
+ new ( ) { Label = "Language" , Value = _model . PreferredLanguage } ,
125
+ new ( ) { Label = "Experience" , Value = $ "{ _model . YearsOfExperience } years" } ,
126
+ new ( ) { Label = "Salary" , Value = _model . ExpectedSalary . ToString ( "C" ) } ,
127
+ new ( ) { Label = "Newsletter" , Value = _model . SubscribeToNewsletter ? "Subscribed" : "Not Subscribed" } ,
128
+ new ( ) { Label = "Terms" , Value = _model . AcceptTerms ? "Accepted" : "Not Accepted" } ,
129
+ new ( ) { Label = "Contact Date" , Value = _model . PreferredContactDate ? . ToShortDateString ( ) ?? "Not specified" } ,
130
+ new ( ) { Label = "Bio Length" , Value = $ "{ _model . Bio ? . Length ?? 0 } characters" } ,
131
+ new ( ) { Label = "Has Comments" , Value = string . IsNullOrEmpty ( _model . Comments ) ? "No" : "Yes" }
132
+ ] ;
133
+ }
134
+
135
+ private string GetModelCode ( )
136
+ {
137
+ return @"public class UserRegistrationModel
138
+ {
139
+ [TextField(""First Name"", ""Enter your first name"")]
140
+ [Required(ErrorMessage = ""First name is required"")]
141
+ [MinLength(2, ErrorMessage = ""First name must be at least 2 characters"")]
142
+ [MaxLength(50, ErrorMessage = ""First name cannot exceed 50 characters"")]
143
+ public string FirstName { get; set; } = string.Empty;
144
+
145
+ [TextField(""Last Name"", ""Enter your last name"")]
146
+ [Required(ErrorMessage = ""Last name is required"")]
147
+ [MinLength(2, ErrorMessage = ""Last name must be at least 2 characters"")]
148
+ public string LastName { get; set; } = string.Empty;
149
+
150
+ [EmailField(""Email Address"")]
151
+ [Required(ErrorMessage = ""Email is required"")]
152
+ public string Email { get; set; } = string.Empty;
153
+
154
+ [NumberField(""Age"", ""Your age in years"")]
155
+ [Required(ErrorMessage = ""Age is required"")]
156
+ [Range(18, 120, ErrorMessage = ""Age must be between 18 and 120"")]
157
+ public int Age { get; set; }
158
+
159
+ [DateField(""Date of Birth"")]
160
+ [Required(ErrorMessage = ""Date of birth is required"")]
161
+ public DateTime DateOfBirth { get; set; } = DateTime.Now.AddYears(-25);
162
+
163
+ [SelectField(""Country"", ""United States"", ""Canada"", ""United Kingdom"", ...)]
164
+ [Required(ErrorMessage = ""Please select a country"")]
165
+ public string Country { get; set; } = string.Empty;
166
+
167
+ [SelectField(""Preferred Language"", ""English"", ""Spanish"", ""French"", ...)]
168
+ public string PreferredLanguage { get; set; } = ""English"";
169
+
170
+ [NumberField(""Years of Experience"")]
171
+ [Range(0, 50, ErrorMessage = ""Years of experience must be between 0 and 50"")]
172
+ public int YearsOfExperience { get; set; }
173
+
174
+ [TextArea(""Bio"", ""Tell us about yourself..."")]
175
+ [MaxLength(500, ErrorMessage = ""Bio cannot exceed 500 characters"")]
176
+ public string Bio { get; set; } = string.Empty;
177
+
178
+ [CheckboxField(""Subscribe to Newsletter"", ""I want to receive promotional emails"")]
179
+ public bool SubscribeToNewsletter { get; set; }
180
+
181
+ [CheckboxField(""Accept Terms"", ""I accept the terms and conditions"")]
182
+ [Required(ErrorMessage = ""You must accept the terms and conditions"")]
183
+ public bool AcceptTerms { get; set; }
184
+
185
+ [DateField(""Preferred Contact Date"")]
186
+ public DateTime? PreferredContactDate { get; set; }
187
+
188
+ [NumberField(""Expected Salary"", ""$0.00"")]
189
+ [Range(0, 1000000, ErrorMessage = ""Salary must be between 0 and 1,000,000"")]
190
+ public decimal ExpectedSalary { get; set; }
191
+
192
+ [TextArea(""Additional Comments"", ""Any additional information..."")]
193
+ public string Comments { get; set; } = string.Empty;
194
+ }" ;
195
+ }
196
+
197
+ private string GetFormGenerationCode ( )
198
+ {
199
+ return @"// That's it! Just one line to generate the entire form from attributes:
200
+ var formConfiguration = FormBuilder<UserRegistrationModel>
201
+ .Create()
202
+ .AddFieldsFromAttributes() // ← This reads all attributes and builds the form
203
+ .Build();
204
+
205
+ // Then use it in your Blazor component:
206
+ <FormCraftComponent TModel=""UserRegistrationModel""
207
+ Model=""@_model""
208
+ Configuration=""@_formConfiguration""
209
+ OnValidSubmit=""HandleValidSubmit"" />" ;
210
+ }
211
+ }
0 commit comments