@olafvv/ngx-dynamic-form 20.1.0 → 20.3.0
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.
- package/README.md +108 -56
- package/fesm2022/olafvv-ngx-dynamic-form.mjs +277 -148
- package/fesm2022/olafvv-ngx-dynamic-form.mjs.map +1 -1
- package/index.d.ts +115 -51
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,6 +19,8 @@ Leveraging cutting-edge Angular features like **Strict Typed Forms** and **Signa
|
|
|
19
19
|
|
|
20
20
|
- [Getting Started](#getting-started)
|
|
21
21
|
- [Basic Usage (3 Steps)](#usage)
|
|
22
|
+
- [Layout](#layout)
|
|
23
|
+
- [Field Width Control](#field-width-control)
|
|
22
24
|
- [Validators](#validators)
|
|
23
25
|
- [Relations (Conditional Logic)](#relations)
|
|
24
26
|
- [Built-in Form Controls](#built-in-form-controls)
|
|
@@ -57,27 +59,30 @@ export class AppComponent {}
|
|
|
57
59
|
|
|
58
60
|
##### 2. Define your form configuration
|
|
59
61
|
|
|
60
|
-
Create
|
|
62
|
+
Create an array of field models. Each model describes a single field — its type, label, validators, and any conditional logic.
|
|
61
63
|
|
|
62
64
|
```ts
|
|
63
|
-
import { DynamicInput, DynamicTextarea, DynamicFormConfig } from '@olafvv/ngx-dynamic-form';
|
|
65
|
+
import { DynamicInput, DynamicTextarea, DynamicStaticText, DynamicFormConfig } from '@olafvv/ngx-dynamic-form';
|
|
64
66
|
|
|
65
67
|
export const SAMPLE_FORM: DynamicFormConfig = [
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
68
|
+
new DynamicStaticText({
|
|
69
|
+
name: 'intro',
|
|
70
|
+
value: {
|
|
71
|
+
title: 'Contact Information',
|
|
72
|
+
text: 'Please fill in your details below.'
|
|
73
|
+
}
|
|
74
|
+
}),
|
|
75
|
+
new DynamicInput({
|
|
76
|
+
name: 'name',
|
|
77
|
+
inputType: 'text',
|
|
78
|
+
label: 'Name'
|
|
79
|
+
}),
|
|
80
|
+
new DynamicTextarea({
|
|
81
|
+
name: 'message',
|
|
82
|
+
label: 'Your message',
|
|
83
|
+
maxLength: 200,
|
|
84
|
+
rows: 5
|
|
85
|
+
})
|
|
81
86
|
];
|
|
82
87
|
```
|
|
83
88
|
|
|
@@ -112,6 +117,59 @@ export class MyFormComponent {
|
|
|
112
117
|
|
|
113
118
|
---
|
|
114
119
|
|
|
120
|
+
## Layout
|
|
121
|
+
|
|
122
|
+
By default, fields are stacked vertically — one per row. To arrange fields side-by-side, pass a `layout` input to `<dynamic-form>`. Each string in the array represents one **row**, containing space-separated field `name` values.
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
// component.ts
|
|
126
|
+
layout: string[] = [
|
|
127
|
+
'firstName lastName', // two fields side-by-side
|
|
128
|
+
'email', // full-width
|
|
129
|
+
'street city zip', // three fields in a row
|
|
130
|
+
];
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
```html
|
|
134
|
+
<!-- component.html -->
|
|
135
|
+
<dynamic-form
|
|
136
|
+
[group]="formGroup"
|
|
137
|
+
[formConfig]="formConfig"
|
|
138
|
+
[layout]="layout" />
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Fields not referenced in the layout are not rendered. Fields within a row share available space equally by default.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Field Width Control
|
|
146
|
+
|
|
147
|
+
Field widths are controlled via **CSS custom properties**, keeping presentation cleanly separated from data configuration. Each field exposes a CSS variable named `--field-{name}-width`.
|
|
148
|
+
|
|
149
|
+
Since `<dynamic-form>` is rendered in your own component's template, you can set these variables from your component's scoped stylesheet — no `::ng-deep` or global styles required.
|
|
150
|
+
|
|
151
|
+
```scss
|
|
152
|
+
// my-form.component.scss
|
|
153
|
+
dynamic-form {
|
|
154
|
+
--field-postcode-width: 25%; // postcode takes 25%
|
|
155
|
+
// street fills the remaining 75% automatically
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
This approach also works natively with `@media` queries for fully responsive layouts:
|
|
160
|
+
|
|
161
|
+
```scss
|
|
162
|
+
dynamic-form {
|
|
163
|
+
--field-postcode-width: 25%;
|
|
164
|
+
|
|
165
|
+
@media (max-width: 600px) {
|
|
166
|
+
--field-postcode-width: 100%; // stack on mobile
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
115
173
|
## Validators
|
|
116
174
|
|
|
117
175
|
This library comes with a set of built-in formatters mapped seamlessly to standard [Angular Validators](https://angular.dev/api/forms/Validators). They are provided via static methods inside `DynamicFormValidators` (e.g. `DynamicFormValidators.required()`).
|
|
@@ -119,17 +177,12 @@ This library comes with a set of built-in formatters mapped seamlessly to standa
|
|
|
119
177
|
```ts
|
|
120
178
|
import { DynamicFormValidators } from '@olafvv/ngx-dynamic-form';
|
|
121
179
|
|
|
122
|
-
export const SAMPLE_FORM = [
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
DynamicFormValidators.required('Email address is required!'),
|
|
129
|
-
DynamicFormValidators.email('Please provide a valid email')
|
|
130
|
-
]
|
|
131
|
-
})
|
|
132
|
-
]
|
|
180
|
+
export const SAMPLE_FORM: DynamicFormConfig = [
|
|
181
|
+
new DynamicInput({
|
|
182
|
+
name: 'email',
|
|
183
|
+
inputType: 'email',
|
|
184
|
+
validators: [DynamicFormValidators.required('Email address is required!'), DynamicFormValidators.email('Please provide a valid email')]
|
|
185
|
+
})
|
|
133
186
|
];
|
|
134
187
|
```
|
|
135
188
|
|
|
@@ -197,34 +250,30 @@ type DynamicFormFieldRelation {
|
|
|
197
250
|
##### Example: Conditional Visibility
|
|
198
251
|
|
|
199
252
|
```ts
|
|
200
|
-
const formConfig = [
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
]
|
|
226
|
-
})
|
|
227
|
-
]
|
|
253
|
+
const formConfig: DynamicFormConfig = [
|
|
254
|
+
new DynamicSelect({
|
|
255
|
+
name: 'documentType',
|
|
256
|
+
label: 'Document type',
|
|
257
|
+
options: [
|
|
258
|
+
{ label: 'Passport', value: 'passport' },
|
|
259
|
+
{ label: 'ID Card', value: 'id' }
|
|
260
|
+
]
|
|
261
|
+
}),
|
|
262
|
+
new DynamicInput({
|
|
263
|
+
name: 'passportNumber',
|
|
264
|
+
label: 'Passport number',
|
|
265
|
+
relations: [
|
|
266
|
+
{
|
|
267
|
+
actionType: RelationActionType.VISIBLE, // Make this field visible...
|
|
268
|
+
conditions: [
|
|
269
|
+
{
|
|
270
|
+
fieldName: 'documentType', // ...when 'documentType' field...
|
|
271
|
+
value: (val: string) => val === 'passport' // ...equals 'passport'
|
|
272
|
+
}
|
|
273
|
+
]
|
|
274
|
+
}
|
|
275
|
+
]
|
|
276
|
+
})
|
|
228
277
|
];
|
|
229
278
|
```
|
|
230
279
|
|
|
@@ -236,12 +285,15 @@ The library comes with a battle-tested set of built-in form controls utilizing *
|
|
|
236
285
|
|
|
237
286
|
| Control Name | Description |
|
|
238
287
|
| :---------------- | :------------------------------------------------------------------------------------ |
|
|
288
|
+
| **Autocomplete** | Advanced input with support for local filtering and async search functions. |
|
|
239
289
|
| **Button** | Highly-customizable actionable button with a click callback. |
|
|
240
290
|
| **Button toggle** | Horizontal toggle groupings ideal for single or multi-select radio behavior. |
|
|
241
291
|
| **Checkbox** | Standard binary state checkbox. |
|
|
292
|
+
| **Slide toggle** | Standard binary state slide toggle. |
|
|
242
293
|
| **Input** | Standard HTML5 inputs with embedded floating labels, validation hints, and matchings. |
|
|
243
294
|
| **Radio group** | Vertically or horizontally stacked radio selectors. |
|
|
244
295
|
| **Readonly** | Presentational un-editable field representation. |
|
|
296
|
+
| **Static Text** | Presentational text for titles and/or descriptions. |
|
|
245
297
|
| **Select** | Dropdown menu powered by `mat-select` or native `<select>`. |
|
|
246
298
|
| **Textarea** | Auto-resizing text area input. |
|
|
247
299
|
|