ng-dynamic-forms
ng-dynamic-forms copied to clipboard
Dynamically populate a controls list or options based on a related controls value
The purpose of this PR is to allow for the dynamic population of related input values.
Goals:
- Allow the value of one input to automatically and asynchronously populate the list or options for another input
Configuration
This PR introduces another configuration attribute on the DynamicFormControlModel.
The dataProvider attribute contains the following properties.
| Name | Description |
|---|---|
| relation | Similar to how relations work, you provide a rootPath or id to the related control |
| relation.id | ID of the input control |
| relation.rootPath | The path to the input control from the form group. |
| service | The service that will be used to fetch the data on related input control value change |
Usage
Example Configuration
car-details.form.ts
import { CarDataProviderService } from './car-data-provider.service.ts';
export function CarDetailsForm(): DynamicFormControlModel[] {
return [
new DynamicSelectModel({
id: 'make',
label: 'Make',
value: '',
options: [
{value: '', label: '-- Select a Make'},
{value: 'chevy', label: 'Chevrolet'},
{value: 'ford', label: 'Ford'},
{value: 'toyota', label: 'Toyota'},
],
validators: {
required: null,
},
errorMessages: {
required: '{{ label }} is required',
},
}),
new DynamicSelectModel({
id: 'model',
label: 'Model',
value: '',
options: [
{value: '', label: '-- Select a Model'},
],
dataProvider: {
relation: {id: 'make'},
service: CarDataProviderService,
},
relations: [
{
match: MATCH_DISABLED,
when: [
{
id: 'make', value: '',
},
],
},
],
validators: {
required: null,
},
errorMessages: {
required: '{{ label }} is required',
},
}),
];
}
Create a data provider. The data provider must implement one of two service interfaces DynamicFormControlListDataProvider or DynamicFormControlOptionsDataProvider. Note: The service must return an Observable.
car-data-provider.service.ts
import {Observable, of} from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class CarDataProviderService implements DynamicFormControlOptionDataProvider<string> {
fetchOptions(value: string): Observer<DynamicFormOptionConfig<string>[]> {
switch (value) {
case 'chevy':
return of([
{
value: 'silverado',
label: 'Silverado',
},
{
value: 'traverse',
label: 'Traverse',
},
]);
break;
case 'ford':
return of([
{
value: 'f150',
label: 'F150',
},
{
value: 'f250',
label: 'f250',
},
]);
break;
case 'toyota':
return of([
{
value: 'tacoma',
label: 'Tacoma',
},
{
value: 'tundra',
label: 'Tundra',
},
]);
break;
}
}
}
Note
This PR is based off my previous PR #1054
Codecov Report
Merging #1055 into master will increase coverage by
0.16%. The diff coverage is95.65%.
@@ Coverage Diff @@
## master #1055 +/- ##
==========================================
+ Coverage 90.49% 90.65% +0.16%
==========================================
Files 170 171 +1
Lines 2673 2719 +46
Branches 247 257 +10
==========================================
+ Hits 2419 2465 +46
+ Misses 196 193 -3
- Partials 58 61 +3
| Impacted Files | Coverage Δ | |
|---|---|---|
| ...-ngx-bootstrap-form-control-container.component.ts | 100% <100%> (ø) |
:arrow_up: |
| .../dynamic-basic-form-control-container.component.ts | 100% <100%> (ø) |
:arrow_up: |
| ...c-ng-bootstrap-form-control-container.component.ts | 97.5% <100%> (+0.06%) |
:arrow_up: |
| .../dynamic-ionic-form-control-container.component.ts | 65.78% <100%> (+0.92%) |
:arrow_up: |
| ...s/core/src/lib/model/dynamic-form-control.model.ts | 97.22% <100%> (+0.16%) |
:arrow_up: |
| ...ynamic-primeng-form-control-container.component.ts | 82.35% <100%> (+0.35%) |
:arrow_up: |
| ...namic-material-form-control-container.component.ts | 95% <100%> (+0.12%) |
:arrow_up: |
| .../dynamic-kendo-form-control-container.component.ts | 77.35% <100%> (+0.43%) |
:arrow_up: |
| ...ms/core/src/lib/service/dynamic-form-validators.ts | 100% <100%> (ø) |
:arrow_up: |
| ...amic-bootstrap-form-control-container.component.ts | 100% <100%> (ø) |
:arrow_up: |
| ... and 6 more |
Continue to review full report at Codecov.
Legend - Click here to learn more
Δ = absolute <relative> (impact),ø = not affected,? = missing dataPowered by Codecov. Last update 4ea5ace...dff4256. Read the comment docs.
Hi @steverhoades Do you mind to share your experience with dynamic forms in the discussions of a new library to implement advanced features? https://dev.to/myndpm/a-new-approach-to-have-dynamic-forms-in-angular-5d11 Thanks in advance!