@bcweed/dynamic-form-lib 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +19 -15
  2. package/fesm2022/bcweed-dynamic-form-lib.mjs +938 -0
  3. package/fesm2022/bcweed-dynamic-form-lib.mjs.map +1 -0
  4. package/index.d.ts +254 -0
  5. package/package.json +37 -65
  6. package/.editorconfig +0 -17
  7. package/.postcssrc.json +0 -5
  8. package/.vscode/extensions.json +0 -4
  9. package/.vscode/launch.json +0 -20
  10. package/.vscode/tasks.json +0 -42
  11. package/AngularDynamicFormLibrary.esproj +0 -13
  12. package/CHANGELOG.md +0 -16
  13. package/angular.json +0 -169
  14. package/aspnetcore-https.js +0 -37
  15. package/karma.conf.js +0 -44
  16. package/obj/Debug/AngularDynamicFormLibrary.esproj.CoreCompileInputs.cache +0 -0
  17. package/obj/Debug/AngularDynamicFormLibrary.esproj.FileListAbsolute.txt +0 -1
  18. package/obj/Debug/package.g.props +0 -56
  19. package/postcss.config.js +0 -6
  20. package/projects/dynamic-form-lib/.postcssrc.json +0 -5
  21. package/projects/dynamic-form-lib/README.md +0 -63
  22. package/projects/dynamic-form-lib/ng-package.json +0 -10
  23. package/projects/dynamic-form-lib/package.json +0 -27
  24. package/projects/dynamic-form-lib/src/lib/README.md +0 -424
  25. package/projects/dynamic-form-lib/src/lib/SUMMARY.md +0 -159
  26. package/projects/dynamic-form-lib/src/lib/directives/dynamic-ref-directive.ts +0 -13
  27. package/projects/dynamic-form-lib/src/lib/dynamic-form-demo/dynamic-form-demo.component.html +0 -75
  28. package/projects/dynamic-form-lib/src/lib/dynamic-form-demo/dynamic-form-demo.component.scss +0 -127
  29. package/projects/dynamic-form-lib/src/lib/dynamic-form-demo/dynamic-form-demo.component.ts +0 -50
  30. package/projects/dynamic-form-lib/src/lib/dynamic-form-field/dynamic-form-field.component.html +0 -234
  31. package/projects/dynamic-form-lib/src/lib/dynamic-form-field/dynamic-form-field.component.scss +0 -315
  32. package/projects/dynamic-form-lib/src/lib/dynamic-form-field/dynamic-form-field.component.ts +0 -219
  33. package/projects/dynamic-form-lib/src/lib/dynamic-form.component.html +0 -137
  34. package/projects/dynamic-form-lib/src/lib/dynamic-form.component.scss +0 -141
  35. package/projects/dynamic-form-lib/src/lib/dynamic-form.component.ts +0 -366
  36. package/projects/dynamic-form-lib/src/lib/helpers/component-helper.ts +0 -54
  37. package/projects/dynamic-form-lib/src/lib/index.ts +0 -10
  38. package/projects/dynamic-form-lib/src/lib/models/dynamic-form-interfaces.ts +0 -117
  39. package/projects/dynamic-form-lib/src/lib/services/dynamic-form.service.spec.ts +0 -302
  40. package/projects/dynamic-form-lib/src/lib/services/dynamic-form.service.ts +0 -325
  41. package/projects/dynamic-form-lib/src/lib/style.scss +0 -3
  42. package/projects/dynamic-form-lib/src/lib/tailwind-output.css +0 -0
  43. package/projects/dynamic-form-lib/src/lib/validators/compare-validator.ts +0 -26
  44. package/projects/dynamic-form-lib/src/public-api.css +0 -1
  45. package/projects/dynamic-form-lib/src/public-api.ts +0 -10
  46. package/projects/dynamic-form-lib/tailwind.config.js +0 -10
  47. package/projects/dynamic-form-lib/tsconfig.lib.json +0 -15
  48. package/projects/dynamic-form-lib/tsconfig.lib.prod.json +0 -11
  49. package/projects/dynamic-form-lib/tsconfig.spec.json +0 -15
  50. package/public/favicon.ico +0 -0
  51. package/src/app/app-routing.module.ts +0 -10
  52. package/src/app/app.component.css +0 -0
  53. package/src/app/app.component.html +0 -18
  54. package/src/app/app.component.spec.ts +0 -35
  55. package/src/app/app.component.ts +0 -1038
  56. package/src/app/app.config.ts +0 -45
  57. package/src/app/app.module.ts +0 -46
  58. package/src/app/app.routes.ts +0 -8
  59. package/src/index.html +0 -13
  60. package/src/main.ts +0 -16
  61. package/src/styles.css +0 -2
  62. package/tailwind.config.js +0 -10
  63. package/tsconfig.app.json +0 -15
  64. package/tsconfig.json +0 -32
  65. package/tsconfig.spec.json +0 -15
  66. /package/{projects/dynamic-form-lib/src → src}/lib/style.css +0 -0
@@ -1,424 +0,0 @@
1
- # Dynamic Form Component
2
-
3
- A comprehensive, reusable dynamic form system for Angular applications with built-in validation and visual state management.
4
-
5
- ## Features
6
-
7
- - 🎨 **Multiple Field Types**: text, email, number, select, checkbox, radio, date, textarea
8
- - ✅ **Built-in Validation**: required, minLength, maxLength, min, max, email, pattern, custom validators
9
- - 🎯 **Visual State Changes**: Real-time visual feedback for valid/invalid fields
10
- - 📱 **Responsive Design**: Mobile-friendly layout using Bootstrap grid
11
- - 🔄 **State Management**: Complete form state tracking (values, errors, touched fields)
12
- - 🎭 **Conditional Display**: Show/hide fields based on form values
13
- - 🎨 **PrimeNG Integration**: Uses PrimeNG components for consistent UI
14
- - 🚀 **Standalone Components**: Uses Angular standalone components
15
-
16
- ## Installation
17
-
18
- The dynamic form components are located in `src/app/dynamic-form/`.
19
-
20
- ### Required Dependencies
21
-
22
- Make sure you have the following packages installed:
23
- - `@angular/forms`
24
- - `@angular/common`
25
- - `primeng`
26
- - `primeicons`
27
- - `@primeng/themes`
28
-
29
- ## Usage
30
-
31
- ### Basic Example
32
-
33
- ```typescript
34
- import { Component } from '@angular/core';
35
- import { DynamicFormComponent } from './dynamic-form/dynamic-form.component';
36
- import { DynamicFormConfig, DynamicFormValue } from './models/dynamic-forms';
37
-
38
- @Component({
39
- selector: 'app-example',
40
- standalone: true,
41
- imports: [DynamicFormComponent],
42
- template: `
43
- <app-dynamic-form
44
- [config]="formConfig"
45
- (formSubmit)="onSubmit($event)"
46
- (formCancel)="onCancel()">
47
- </app-dynamic-form>
48
- `
49
- })
50
- export class ExampleComponent {
51
- formConfig: DynamicFormConfig = {
52
- id: 'example-form',
53
- title: 'Example Form',
54
- description: 'This is an example form',
55
- fields: [
56
- {
57
- id: 'name',
58
- label: 'Name',
59
- type: 'text',
60
- placeholder: 'Enter your name',
61
- required: true,
62
- validations: [
63
- {
64
- type: 'required',
65
- message: 'Name is required'
66
- }
67
- ]
68
- },
69
- {
70
- id: 'email',
71
- label: 'Email',
72
- type: 'email',
73
- placeholder: 'Enter your email',
74
- required: true,
75
- validations: [
76
- {
77
- type: 'required',
78
- message: 'Email is required'
79
- },
80
- {
81
- type: 'email',
82
- message: 'Please enter a valid email'
83
- }
84
- ]
85
- }
86
- ],
87
- submitLabel: 'Submit',
88
- cancelLabel: 'Cancel'
89
- };
90
-
91
- onSubmit(values: DynamicFormValue): void {
92
- console.log('Form submitted:', values);
93
- }
94
-
95
- onCancel(): void {
96
- console.log('Form cancelled');
97
- }
98
- }
99
- ```
100
-
101
- ### Field Types
102
-
103
- #### Text Input
104
- ```typescript
105
- {
106
- id: 'firstName',
107
- label: 'First Name',
108
- type: 'text',
109
- placeholder: 'Enter first name',
110
- required: true
111
- }
112
- ```
113
-
114
- #### Email Input
115
- ```typescript
116
- {
117
- id: 'email',
118
- label: 'Email',
119
- type: 'email',
120
- placeholder: 'email@example.com',
121
- required: true,
122
- validations: [
123
- { type: 'required', message: 'Email is required' },
124
- { type: 'email', message: 'Invalid email format' }
125
- ]
126
- }
127
- ```
128
-
129
- #### Number Input
130
- ```typescript
131
- {
132
- id: 'age',
133
- label: 'Age',
134
- type: 'number',
135
- validations: [
136
- { type: 'min', value: 18, message: 'Must be at least 18' },
137
- { type: 'max', value: 120, message: 'Must be less than 120' }
138
- ]
139
- }
140
- ```
141
-
142
- #### Select Dropdown
143
- ```typescript
144
- {
145
- id: 'country',
146
- label: 'Country',
147
- type: 'select',
148
- required: true,
149
- options: [
150
- { label: 'United States', value: 'US' },
151
- { label: 'Canada', value: 'CA' },
152
- { label: 'United Kingdom', value: 'UK' }
153
- ]
154
- }
155
- ```
156
-
157
- #### Radio Buttons
158
- ```typescript
159
- {
160
- id: 'gender',
161
- label: 'Gender',
162
- type: 'radio',
163
- options: [
164
- { label: 'Male', value: 'male' },
165
- { label: 'Female', value: 'female' },
166
- { label: 'Other', value: 'other' }
167
- ]
168
- }
169
- ```
170
-
171
- #### Checkbox
172
- ```typescript
173
- {
174
- id: 'newsletter',
175
- label: 'Subscribe to newsletter',
176
- type: 'checkbox',
177
- value: false
178
- }
179
- ```
180
-
181
- #### Date Picker
182
- ```typescript
183
- {
184
- id: 'birthDate',
185
- label: 'Birth Date',
186
- type: 'date',
187
- placeholder: 'Select date',
188
- required: true
189
- }
190
- ```
191
-
192
- #### Textarea
193
- ```typescript
194
- {
195
- id: 'comments',
196
- label: 'Comments',
197
- type: 'textarea',
198
- placeholder: 'Enter comments',
199
- validations: [
200
- { type: 'maxLength', value: 500, message: 'Max 500 characters' }
201
- ]
202
- }
203
- ```
204
-
205
- ### Validation Types
206
-
207
- #### Required
208
- ```typescript
209
- {
210
- type: 'required',
211
- message: 'This field is required'
212
- }
213
- ```
214
-
215
- #### Min/Max Length
216
- ```typescript
217
- {
218
- type: 'minLength',
219
- value: 3,
220
- message: 'Minimum 3 characters'
221
- },
222
- {
223
- type: 'maxLength',
224
- value: 50,
225
- message: 'Maximum 50 characters'
226
- }
227
- ```
228
-
229
- #### Min/Max Value
230
- ```typescript
231
- {
232
- type: 'min',
233
- value: 0,
234
- message: 'Value must be at least 0'
235
- },
236
- {
237
- type: 'max',
238
- value: 100,
239
- message: 'Value must be at most 100'
240
- }
241
- ```
242
-
243
- #### Pattern (Regex)
244
- ```typescript
245
- {
246
- type: 'pattern',
247
- value: '^[0-9]{5}$',
248
- message: 'Must be a 5-digit ZIP code'
249
- }
250
- ```
251
-
252
- #### Custom Validator
253
- ```typescript
254
- {
255
- type: 'custom',
256
- message: 'Password must contain at least one uppercase letter',
257
- validator: (value: any) => {
258
- return /[A-Z]/.test(value);
259
- }
260
- }
261
- ```
262
-
263
- ### Conditional Display
264
-
265
- You can show/hide fields based on other field values:
266
-
267
- ```typescript
268
- {
269
- id: 'companyName',
270
- label: 'Company Name',
271
- type: 'text',
272
- conditionalDisplay: (formValues: any) => {
273
- return formValues.accountType === 'business';
274
- }
275
- }
276
- ```
277
-
278
- ### Field Ordering and Layout
279
-
280
- Control field order and layout using `order` and `cssClass`:
281
-
282
- ```typescript
283
- {
284
- id: 'firstName',
285
- label: 'First Name',
286
- type: 'text',
287
- order: 1,
288
- cssClass: 'col-md-6' // Bootstrap grid class
289
- }
290
- ```
291
-
292
- ### Form State Management
293
-
294
- Track form state in real-time:
295
-
296
- ```typescript
297
- onFormStateChange(state: DynamicFormState): void {
298
- console.log('Form valid:', state.isValid);
299
- console.log('Current values:', state.values);
300
- console.log('Errors:', state.errors);
301
- console.log('Touched fields:', state.touched);
302
- console.log('Submitting:', state.isSubmitting);
303
- }
304
- ```
305
-
306
- ### Initial Values
307
-
308
- Provide initial values to the form:
309
-
310
- ```typescript
311
- <app-dynamic-form
312
- [config]="formConfig"
313
- [initialValues]="{ firstName: 'John', email: 'john@example.com' }"
314
- (formSubmit)="onSubmit($event)">
315
- </app-dynamic-form>
316
- ```
317
-
318
- ## Component API
319
-
320
- ### Inputs
321
-
322
- | Input | Type | Description |
323
- |-------|------|-------------|
324
- | `config` | `DynamicFormConfig` | Form configuration (required) |
325
- | `initialValues` | `DynamicFormValue` | Initial form values (optional) |
326
-
327
- ### Outputs
328
-
329
- | Output | Type | Description |
330
- |--------|------|-------------|
331
- | `formSubmit` | `DynamicFormValue` | Emitted when form is submitted |
332
- | `formCancel` | `void` | Emitted when cancel is clicked |
333
- | `formStateChange` | `DynamicFormState` | Emitted when form state changes |
334
-
335
- ### Methods
336
-
337
- The component exposes these methods via ViewChild:
338
-
339
- - `reset()`: Reset the form to initial state
340
- - `patchValues(values: DynamicFormValue)`: Update form values
341
- - `getFormValue()`: Get current form values
342
-
343
- ## Demo Component
344
-
345
- A complete demo component is available at `src/app/dynamic-form/dynamic-form-demo/` that showcases all features.
346
-
347
- To use the demo:
348
- 1. Import and add to your routes
349
- 2. Navigate to the demo route
350
- 3. Interact with the form to see validation and state changes
351
-
352
- ## Styling
353
-
354
- The components use a combination of:
355
- - Bootstrap grid system for layout
356
- - PrimeNG component styles
357
- - Custom SCSS for visual state changes
358
-
359
- Visual states include:
360
- - ✅ Valid fields (green border + checkmark)
361
- - ❌ Invalid fields (red border + error messages)
362
- - 🔒 Disabled fields (grayed out)
363
- - ⭐ Required fields (asterisk indicator)
364
-
365
- ## Service
366
-
367
- The `DynamicFormService` provides:
368
- - Validator creation from validation config
369
- - Error message generation
370
- - Form configuration validation
371
- - Sample form configuration generator
372
-
373
- ## File Structure
374
-
375
- ```
376
- src/app/dynamic-form/
377
- ├── dynamic-form.component.ts
378
- ├── dynamic-form.component.html
379
- ├── dynamic-form.component.scss
380
- ├── dynamic-form-field/
381
- │ ├── dynamic-form-field.component.ts
382
- │ ├── dynamic-form-field.component.html
383
- │ └── dynamic-form-field.component.scss
384
- ├── services/
385
- │ └── dynamic-form.service.ts
386
- ├── dynamic-form-demo/
387
- │ ├── dynamic-form-demo.component.ts
388
- │ ├── dynamic-form-demo.component.html
389
- │ └── dynamic-form-demo.component.scss
390
- └── README.md
391
- ```
392
-
393
- ## TypeScript Interfaces
394
-
395
- All interfaces are defined in `src/app/models/dynamic-forms.ts`:
396
-
397
- - `DynamicFormField`: Field configuration
398
- - `DynamicFormOption`: Select/Radio options
399
- - `DynamicFormValidation`: Validation rules
400
- - `DynamicFormConfig`: Complete form configuration
401
- - `DynamicFormValue`: Form values object
402
- - `DynamicFormError`: Error representation
403
- - `DynamicFormState`: Complete form state
404
-
405
- ## Best Practices
406
-
407
- 1. **Always provide validation messages**: Users need clear feedback
408
- 2. **Use appropriate field types**: Choose the right input type for data
409
- 3. **Order fields logically**: Use the `order` property
410
- 4. **Group related fields**: Use `cssClass` for layout
411
- 5. **Handle form submission**: Always provide feedback after submission
412
- 6. **Validate configuration**: Use `DynamicFormService.validateFormConfig()`
413
-
414
- ## Browser Support
415
-
416
- Supports all modern browsers that Angular 19 supports:
417
- - Chrome (latest)
418
- - Firefox (latest)
419
- - Safari (latest)
420
- - Edge (latest)
421
-
422
- ## License
423
-
424
- Part of the VesselRegistry application.
@@ -1,159 +0,0 @@
1
- # Dynamic Form System - Summary
2
-
3
- ## Created Files
4
-
5
- The following files have been successfully created in `vesselregistry.client/src/app/dynamic-form/`:
6
-
7
- ### Core Components
8
- 1. **dynamic-form.component.ts** - Main container component that manages the entire form
9
- 2. **dynamic-form.component.html** - Template for the form container
10
- 3. **dynamic-form.component.scss** - Styles for the form container
11
-
12
- ### Field Component
13
- 4. **dynamic-form-field/dynamic-form-field.component.ts** - Individual field renderer
14
- 5. **dynamic-form-field/dynamic-form-field.component.html** - Template for individual fields
15
- 6. **dynamic-form-field/dynamic-form-field.component.scss** - Styles for fields with visual states
16
-
17
- ### Service
18
- 7. **services/dynamic-form.service.ts** - Form validation and state management service
19
- 8. **services/dynamic-form.service.spec.ts** - Unit tests for the service
20
-
21
- ### Demo Component
22
- 9. **dynamic-form-demo/dynamic-form-demo.component.ts** - Demonstration component
23
- 10. **dynamic-form-demo/dynamic-form-demo.component.html** - Demo template
24
- 11. **dynamic-form-demo/dynamic-form-demo.component.scss** - Demo styles
25
-
26
- ### Documentation
27
- 12. **README.md** - Comprehensive documentation with examples
28
- 13. **index.ts** - Barrel export file for easy imports
29
-
30
- ## Features Implemented
31
-
32
- ### ✅ Field Types
33
- - Text input
34
- - Email input
35
- - Number input
36
- - Select dropdown (with PrimeNG Dropdown)
37
- - Radio buttons (with PrimeNG RadioButton)
38
- - Checkbox (with PrimeNG Checkbox)
39
- - Date picker (with PrimeNG Calendar)
40
- - Textarea
41
-
42
- ### ✅ Validation
43
- - Required
44
- - Min/Max length
45
- - Min/Max value
46
- - Email format
47
- - Pattern (regex)
48
- - Custom validators
49
-
50
- ### ✅ Visual State Changes
51
- - **Valid fields**: Green border + checkmark icon (animated fadeIn)
52
- - **Invalid fields**: Red border + error messages (animated slideDown)
53
- - **Disabled fields**: Grayed out appearance
54
- - **Required fields**: Asterisk indicator
55
- - **Touched/Dirty states**: Visual feedback based on interaction
56
-
57
- ### ✅ Advanced Features
58
- - Conditional field display based on form values
59
- - Field ordering system
60
- - Bootstrap grid integration for responsive layout
61
- - Custom CSS classes per field
62
- - Initial values support
63
- - Form state tracking (values, errors, touched, isSubmitting, isValid)
64
- - Real-time validation
65
- - Form reset functionality
66
- - Value patching
67
-
68
- ### ✅ Styling
69
- - Smooth transitions and animations
70
- - Responsive design (mobile-friendly)
71
- - PrimeNG component integration
72
- - Bootstrap grid system
73
- - Custom visual states with color coding
74
- - Accessible form labels and error messages
75
-
76
- ## Architecture
77
-
78
- ### Component Hierarchy
79
- ```
80
- DynamicFormComponent (Container)
81
- └── DynamicFormFieldComponent (Field Renderer)
82
- └── PrimeNG Components (UI Elements)
83
- ```
84
-
85
- ### Data Flow
86
- 1. Parent provides `DynamicFormConfig`
87
- 2. `DynamicFormComponent` builds Angular `FormGroup`
88
- 3. `DynamicFormService` creates validators
89
- 4. `DynamicFormFieldComponent` renders appropriate field type
90
- 5. Form state tracked and emitted via `formStateChange`
91
- 6. Submission handled via `formSubmit` event
92
-
93
- ## Integration Points
94
-
95
- ### With Existing Project
96
- - Uses existing PrimeNG components (already installed)
97
- - Follows Bootstrap grid conventions (already in use)
98
- - Standalone components (Angular 19 best practice)
99
- - Compatible with existing form patterns
100
-
101
- ### TypeScript Interfaces
102
- All interfaces defined in `vesselregistry.client/src/app/models/dynamic-forms.ts`:
103
- - `DynamicFormField`
104
- - `DynamicFormOption`
105
- - `DynamicFormValidation`
106
- - `DynamicFormConfig`
107
- - `DynamicFormValue`
108
- - `DynamicFormError`
109
- - `DynamicFormState`
110
-
111
- ## Usage Example
112
-
113
- ```typescript
114
- import { DynamicFormComponent } from './dynamic-form/dynamic-form.component';
115
- import { DynamicFormConfig } from './models/dynamic-forms';
116
-
117
- formConfig: DynamicFormConfig = {
118
- id: 'my-form',
119
- title: 'Contact Form',
120
- fields: [
121
- {
122
- id: 'name',
123
- label: 'Name',
124
- type: 'text',
125
- required: true,
126
- validations: [
127
- { type: 'required', message: 'Name is required' }
128
- ]
129
- }
130
- ]
131
- };
132
- ```
133
-
134
- ## Testing
135
-
136
- - Unit tests provided for `DynamicFormService`
137
- - Test coverage for validators and error messages
138
- - Demo component available for manual testing
139
-
140
- ## Next Steps
141
-
142
- To use the dynamic form system:
143
-
144
- 1. Import `DynamicFormComponent` in your component
145
- 2. Create a `DynamicFormConfig` object
146
- 3. Handle `formSubmit` and `formCancel` events
147
- 4. Optionally track state with `formStateChange`
148
-
149
- See `README.md` for detailed examples and API documentation.
150
-
151
- ## Status
152
-
153
- ✅ All files created successfully
154
- ✅ No TypeScript compilation errors
155
- ✅ Follows Angular 19 and PrimeNG conventions
156
- ✅ Includes comprehensive documentation
157
- ✅ Visual states implemented with animations
158
- ✅ Fully responsive design
159
- ✅ Unit tests included
@@ -1,13 +0,0 @@
1
- import { Directive, ElementRef, Input } from '@angular/core';
2
- import { RadioButton } from 'primeng/radiobutton';
3
-
4
- @Directive({
5
- selector: '[dynamicRef]',
6
- standalone: true
7
- })
8
- export class DynamicRefDirective {
9
- @Input() refKey!: string;
10
- constructor(public el: ElementRef) {
11
- const t = this.refKey;
12
- }
13
- }
@@ -1,75 +0,0 @@
1
- <div class="demo-container">
2
- <div class="container-fluid">
3
- <div class="row">
4
- <div class="col-md-8">
5
- <app-dynamic-form
6
- [config]="formConfig"
7
- [initialValues]="formValues"
8
- (formSubmit)="onFormSubmit($event)"
9
- (formCancel)="onFormCancel()"
10
- (formStateChange)="onFormStateChange($event)"
11
- ></app-dynamic-form>
12
- </div>
13
-
14
- <div class="col-md-4">
15
- <div class="info-panel card-style card-corner-style">
16
- <h5>Form Status</h5>
17
- <hr />
18
-
19
- <div class="status-item">
20
- <label>Form Valid:</label>
21
- <span [class]="formIsValid ? 'status-success' : 'status-error'">
22
- {{ formIsValid ? 'Yes' : 'No' }}
23
- </span>
24
- </div>
25
-
26
- <div class="status-item">
27
- <label>Error Count:</label>
28
- <span [class]="formErrorCount > 0 ? 'status-error' : 'status-success'">
29
- {{ formErrorCount }}
30
- </span>
31
- </div>
32
-
33
- @if (formState?.isSubmitting) {
34
- <div class="status-item">
35
- <label>Status:</label>
36
- <span class="status-info">Submitting...</span>
37
- </div>
38
- }
39
-
40
- @if (formState?.errors && formState.errors.length > 0) {
41
- <div class="errors-section">
42
- <h6>Current Errors:</h6>
43
- <ul>
44
- @for (error of formState.errors; track error) {
45
- <li class="error-item">
46
- <strong>{{ error.fieldId }}:</strong> {{ error.message }}
47
- </li>
48
- }
49
- </ul>
50
- </div>
51
- }
52
-
53
- @if (submittedData) {
54
- <div class="submitted-data">
55
- <h6>Submitted Data:</h6>
56
- <pre>{{ submittedData | json }}</pre>
57
- </div>
58
- }
59
- </div>
60
-
61
- <div class="help-panel card-style card-corner-style">
62
- <h5>Instructions</h5>
63
- <hr />
64
- <ul>
65
- <li>Fill out all required fields (marked with *)</li>
66
- <li>Fields will show validation errors when touched</li>
67
- <li>Valid fields will show a green checkmark</li>
68
- <li>Form state is tracked in real-time</li>
69
- <li>Click Submit to see the form data</li>
70
- </ul>
71
- </div>
72
- </div>
73
- </div>
74
- </div>
75
- </div>