Skip to content

Commit df9563a

Browse files
committed
Add documentation section for the dynamic option and list data
1 parent d9b641e commit df9563a

File tree

1 file changed

+118
-0
lines changed

1 file changed

+118
-0
lines changed

README.md

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Explore the [**live sample**](http://ng2-dynamic-forms.udos86.de/sample/index.ht
3131
- [Form Control Configuration](#form-control-configuration)
3232
- [Form Control Events](#form-control-events)
3333
- [Updating Form Controls](#updating-form-controls)
34+
- [Dynamic Option and List Population](#dynamic-form-control-option-and-list-population)
3435
- [Custom Templates](#custom-templates)
3536
- [Custom Validators](#custom-validators)
3637
- [Custom Form Controls](#custom-form-controls)
@@ -689,6 +690,123 @@ To optimize this you can optionally pass a `DynamicFormComponent` to `detectChan
689690
this.formService.detectChanges(this.formComponent);
690691
```
691692

693+
## Dynamic Option And List Population
694+
A common use case of forms is having select, datalist, checkboxes and radio buttons automatically populate based on another form controls value. NG Dynamic Forms accomplishes this by allowing you to provide a `service` per form control to dynamically pull these values based on a related form controls input.
695+
696+
### Configuration
697+
To connect your form controls you will need to provide a `dataProvider` attribute along with a relation with a path to the `id` or `rootPath` of the related form control. Additionally you will need to provide a `service` which is a token from which your service can be pulled from DI.
698+
699+
| Name | Description |
700+
| :--- | :--- |
701+
| relation | Similar to how relations work, you provide a rootPath or id to the related control |
702+
| *relation*.id | ID of the input control |
703+
| *relation*.rootPath | The path to the input control from the form group. |
704+
| service | A token representing the service in the DI. |
705+
706+
```typescript
707+
export function WikiPageForm(): DynamicFormControlModel[] {
708+
return [
709+
new DynamicInputModel({
710+
id: 'wiki-title',
711+
label: 'Search Title',
712+
value: '',
713+
validators: {
714+
required: null,
715+
},
716+
errorMessages: {
717+
required: '{{ label }} is required',
718+
},
719+
}),
720+
new DynamicSelectModel({
721+
id: 'wiki-page',
722+
label: 'Wiki Page',
723+
value: '-1',
724+
options: [{value: '-1', label: '-- select a wikipedia page'}],
725+
dataProvider: {
726+
relation: {id: 'wiki-title'},
727+
service: WikipediaService,
728+
},
729+
relations: [
730+
{
731+
match: MATCH_DISABLED,
732+
when: [
733+
{
734+
rootPath: 'wiki-title', value: '',
735+
},
736+
],
737+
},
738+
],
739+
validators: {
740+
required: null,
741+
},
742+
errorMessages: {
743+
required: '{{ label }} is required',
744+
},
745+
})
746+
];
747+
}
748+
```
749+
### Data Provider
750+
NG Dynamic forms will look attempt to inject a given service via the token provided by the `dataProvider.service` definition. Your service must implement one of two methods depending on your form control.
751+
752+
| Control Name | Interface |
753+
| :--- | :--- |
754+
| DynamicInputModel | DynamicFormControlListDataProvider\<T> |
755+
| DynamicSelectModel | DynamicFormControlOptionDataProvider\<T> |
756+
| DynamicSelectModel | DynamicFormControlOptionDataProvider\<T> |
757+
| DynamicRadioModel | DynamicFormControlOptionDataProvider\<T> |
758+
| DynamicCheckboxModel | DynamicFormControlOptionDataProvider\<T> |
759+
760+
```typescript
761+
const WIKI_URL = 'https://en.wikipedia.org/w/api.php';
762+
const PARAMS = new HttpParams({
763+
fromObject: {
764+
action: 'opensearch',
765+
format: 'json',
766+
origin: '*',
767+
},
768+
});
769+
770+
@Injectable({
771+
providedIn: 'root',
772+
})
773+
export class WikipediaService
774+
implements DynamicFormControlListDataProvider<string>, DynamicFormControlOptionDataProvider<string> {
775+
constructor(private http: HttpClient) {}
776+
777+
fetchList(value: string): Observable<string> {
778+
return this.fetch(value);
779+
}
780+
781+
fetchOptions(value: string): Observable<DynamicFormOptionConfig<string>[]> {
782+
return this.fetch(value).pipe(map(
783+
response => {
784+
if (!Array.isArray(response)) {
785+
return [];
786+
}
787+
788+
return response.map((val) => {
789+
return {
790+
label: val,
791+
value: val as string,
792+
} as DynamicFormOptionConfig<string>;
793+
});
794+
}),
795+
);
796+
}
797+
798+
fetch(term: string): Observable<any> {
799+
if (typeof(term) !== 'string' || term === '') {
800+
return of([]);
801+
}
802+
803+
return this.http
804+
.get<any>(WIKI_URL, {params: PARAMS.set('search', term)}).pipe(
805+
map(response => response[1]),
806+
);
807+
}
808+
}
809+
```
692810

693811
## Custom Templates
694812

0 commit comments

Comments
 (0)