@rxdi/forms 0.7.229 → 0.7.231
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 +32 -11
- package/dist/form.group.js +30 -7
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -327,17 +327,17 @@ function ErrorTemplate(input: AbstractInput) {
|
|
|
327
327
|
|
|
328
328
|
### 1. Grouping Multiple Inputs (Checkbox Groups)
|
|
329
329
|
|
|
330
|
-
By default, inputs with the same `name` attribute
|
|
330
|
+
By default (`multi: false`), inputs with the same `name` attribute behave like radio buttons (single selection). To allow multiple selections (array of values), set `multi: true` in the form options.
|
|
331
331
|
|
|
332
332
|
**Scenario:** A list of permissions where multiple can be selected.
|
|
333
333
|
|
|
334
334
|
```typescript
|
|
335
335
|
@Form({
|
|
336
336
|
name: 'permissions-form',
|
|
337
|
-
multi: true // Enable multi-value binding for
|
|
337
|
+
multi: true // Enable multi-value binding for SAME-NAME inputs
|
|
338
338
|
})
|
|
339
339
|
form = new FormGroup({
|
|
340
|
-
roles: [] // Will be an array of values
|
|
340
|
+
roles: [] // Will be an array of values ['admin', 'viewer']
|
|
341
341
|
});
|
|
342
342
|
```
|
|
343
343
|
|
|
@@ -347,19 +347,17 @@ form = new FormGroup({
|
|
|
347
347
|
<label> <input name="roles" type="checkbox" value="viewer" /> Viewer </label>
|
|
348
348
|
```
|
|
349
349
|
|
|
350
|
-
|
|
350
|
+
### 2. Single Selection Checkbox (Default Behavior)
|
|
351
351
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
If you want multiple checkboxes to act like a radio button (only one valid at a time) but with uncheck capability:
|
|
352
|
+
If you want multiple checkboxes to act like a radio button (only one valid at a time) but with uncheck capability, simply use the default `multi: false`.
|
|
355
353
|
|
|
356
354
|
```typescript
|
|
357
355
|
@Form({
|
|
358
356
|
name: 'settings-form',
|
|
359
|
-
multi: false // Default behavior
|
|
357
|
+
// multi: false // Default behavior
|
|
360
358
|
})
|
|
361
359
|
form = new FormGroup({
|
|
362
|
-
mode: ''
|
|
360
|
+
mode: '' // Will be a single string 'dark' or 'light'
|
|
363
361
|
});
|
|
364
362
|
```
|
|
365
363
|
|
|
@@ -368,9 +366,32 @@ form = new FormGroup({
|
|
|
368
366
|
<label> <input name="mode" type="checkbox" value="light" /> Light </label>
|
|
369
367
|
```
|
|
370
368
|
|
|
371
|
-
|
|
369
|
+
### 3. Per-Field Multi-Select Override
|
|
370
|
+
|
|
371
|
+
You can mix single-select and multi-select groups in the same form by keeping the global `multi: false` (default) and adding the `multiple` attribute to specific inputs.
|
|
372
|
+
|
|
373
|
+
```typescript
|
|
374
|
+
@Form({
|
|
375
|
+
name: 'mixed-form',
|
|
376
|
+
multi: false // Default (Single Select)
|
|
377
|
+
})
|
|
378
|
+
form = new FormGroup({
|
|
379
|
+
mode: '', // Single value
|
|
380
|
+
tags: [] // Array of values
|
|
381
|
+
});
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
```html
|
|
385
|
+
<!-- Single Select (Radio behavior) -->
|
|
386
|
+
<input name="mode" type="checkbox" value="A" />
|
|
387
|
+
<input name="mode" type="checkbox" value="B" />
|
|
388
|
+
|
|
389
|
+
<!-- Multi Select (Array behavior) via 'multiple' attribute -->
|
|
390
|
+
<input name="tags" type="checkbox" value="news" multiple />
|
|
391
|
+
<input name="tags" type="checkbox" value="tech" multiple />
|
|
392
|
+
```
|
|
372
393
|
|
|
373
|
-
###
|
|
394
|
+
### 4. Framework-Agnostic Usage (Vanilla JS)
|
|
374
395
|
|
|
375
396
|
You can use this library without Decorators or LitHtml, with any UI library or vanilla HTML.
|
|
376
397
|
|
package/dist/form.group.js
CHANGED
|
@@ -76,11 +76,12 @@ class FormGroup {
|
|
|
76
76
|
}
|
|
77
77
|
else if (value[0].constructor === String ||
|
|
78
78
|
value[0].constructor === Number ||
|
|
79
|
-
value[0].constructor === Boolean
|
|
79
|
+
value[0].constructor === Boolean ||
|
|
80
|
+
value[0].constructor === Array) {
|
|
80
81
|
this.value[v] = value[0];
|
|
81
82
|
}
|
|
82
83
|
else {
|
|
83
|
-
throw new Error(`Input value must be of type 'string', 'boolean' or 'number'`);
|
|
84
|
+
throw new Error(`Input value must be of type 'string', 'boolean', 'array' or 'number'`);
|
|
84
85
|
}
|
|
85
86
|
}
|
|
86
87
|
});
|
|
@@ -169,12 +170,19 @@ class FormGroup {
|
|
|
169
170
|
.querySelectorAll(`input[name="${this.name}"]:checked`)).values(),
|
|
170
171
|
];
|
|
171
172
|
if (hasMultipleBindings > 1) {
|
|
172
|
-
if (
|
|
173
|
+
if ((self.options.multi || this.hasAttribute('multiple')) &&
|
|
174
|
+
this.type === 'checkbox') {
|
|
173
175
|
value = inputsWithBindings.map((e) => e.value);
|
|
174
176
|
}
|
|
175
|
-
if (self.options.multi
|
|
176
|
-
|
|
177
|
+
if (!self.options.multi &&
|
|
178
|
+
!this.hasAttribute('multiple') &&
|
|
179
|
+
this.type === 'checkbox') {
|
|
180
|
+
inputsWithBindings.forEach((el) => {
|
|
181
|
+
if (el !== this)
|
|
182
|
+
el.checked = false;
|
|
183
|
+
});
|
|
177
184
|
this.checked = true;
|
|
185
|
+
value = this.value;
|
|
178
186
|
}
|
|
179
187
|
}
|
|
180
188
|
self.resetErrors();
|
|
@@ -452,8 +460,12 @@ class FormGroup {
|
|
|
452
460
|
// User code had return; but we might want to update model even if no input?
|
|
453
461
|
// return;
|
|
454
462
|
}
|
|
455
|
-
if (input &&
|
|
463
|
+
if (input &&
|
|
464
|
+
input.value !== undefined &&
|
|
465
|
+
input.type !== 'checkbox' &&
|
|
466
|
+
input.type !== 'radio') {
|
|
456
467
|
input.value = value;
|
|
468
|
+
}
|
|
457
469
|
const values = this.value;
|
|
458
470
|
values[name] = value;
|
|
459
471
|
this.value = values;
|
|
@@ -472,7 +484,18 @@ class FormGroup {
|
|
|
472
484
|
setInputs(inputs) {
|
|
473
485
|
this.inputs = new Map(inputs.map((e) => {
|
|
474
486
|
const key = this.getModelKeyName(e.name);
|
|
475
|
-
|
|
487
|
+
const modelValue = this.getValue(key);
|
|
488
|
+
if (e.type === 'checkbox' || e.type === 'radio') {
|
|
489
|
+
if (Array.isArray(modelValue)) {
|
|
490
|
+
e.checked = modelValue.includes(e.value);
|
|
491
|
+
}
|
|
492
|
+
else {
|
|
493
|
+
e.checked = modelValue === e.value;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
else {
|
|
497
|
+
e.value = modelValue;
|
|
498
|
+
}
|
|
476
499
|
e.valueChanges = this._valueChanges.pipe((0, operators_1.map)((value) => value === null || value === void 0 ? void 0 : value[key]), (0, operators_1.distinctUntilChanged)());
|
|
477
500
|
return [key, e];
|
|
478
501
|
}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rxdi/forms",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.231",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"author": "Kristiyan Tachev",
|
|
6
6
|
"license": "MIT",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"build": "tsc"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
|
-
"@rxdi/lit-html": "^0.7.
|
|
15
|
+
"@rxdi/lit-html": "^0.7.230",
|
|
16
16
|
"@types/node": "^25.0.3",
|
|
17
17
|
"rxjs": "^7.8.2",
|
|
18
18
|
"typescript": "^5.9.3"
|