docs: updated dynamic forms example (#31510)
Fixes #31446 PR Close #31510
This commit is contained in:
parent
53fc2ed8bf
commit
6fadb7a3a4
|
@ -2,21 +2,23 @@
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
import { QuestionService } from './question.service';
|
import { QuestionService } from './question.service';
|
||||||
|
import { QuestionBase } from './question-base';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
template: `
|
template: `
|
||||||
<div>
|
<div>
|
||||||
<h2>Job Application for Heroes</h2>
|
<h2>Job Application for Heroes</h2>
|
||||||
<app-dynamic-form [questions]="questions"></app-dynamic-form>
|
<app-dynamic-form [questions]="questions$ | async"></app-dynamic-form>
|
||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
providers: [QuestionService]
|
providers: [QuestionService]
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent {
|
||||||
questions: any[];
|
questions$: Observable<QuestionBase<any>[]>;
|
||||||
|
|
||||||
constructor(service: QuestionService) {
|
constructor(service: QuestionService) {
|
||||||
this.questions = service.getQuestions();
|
this.questions$ = service.getQuestions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<option *ngFor="let opt of question.options" [value]="opt.key">{{opt.value}}</option>
|
<option *ngFor="let opt of question.options" [value]="opt.key">{{opt.value}}</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="errorMessage" *ngIf="!isValid">{{question.label}} is required</div>
|
<div class="errorMessage" *ngIf="!isValid">{{question.label}} is required</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { QuestionBase } from './question-base';
|
||||||
templateUrl: './dynamic-form-question.component.html'
|
templateUrl: './dynamic-form-question.component.html'
|
||||||
})
|
})
|
||||||
export class DynamicFormQuestionComponent {
|
export class DynamicFormQuestionComponent {
|
||||||
@Input() question: QuestionBase<any>;
|
@Input() question: QuestionBase<string>;
|
||||||
@Input() form: FormGroup;
|
@Input() form: FormGroup;
|
||||||
get isValid() { return this.form.controls[this.question.key].valid; }
|
get isValid() { return this.form.controls[this.question.key].valid; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { QuestionControlService } from './question-control.service';
|
||||||
})
|
})
|
||||||
export class DynamicFormComponent implements OnInit {
|
export class DynamicFormComponent implements OnInit {
|
||||||
|
|
||||||
@Input() questions: QuestionBase<any>[] = [];
|
@Input() questions: QuestionBase<string>[] = [];
|
||||||
form: FormGroup;
|
form: FormGroup;
|
||||||
payLoad = '';
|
payLoad = '';
|
||||||
|
|
||||||
|
@ -23,6 +23,6 @@ export class DynamicFormComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
this.payLoad = JSON.stringify(this.form.value);
|
this.payLoad = JSON.stringify(this.form.getRawValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ export class QuestionBase<T> {
|
||||||
required: boolean;
|
required: boolean;
|
||||||
order: number;
|
order: number;
|
||||||
controlType: string;
|
controlType: string;
|
||||||
|
type: string;
|
||||||
|
options: {key: string, value: string}[];
|
||||||
|
|
||||||
constructor(options: {
|
constructor(options: {
|
||||||
value?: T,
|
value?: T,
|
||||||
|
@ -13,7 +15,8 @@ export class QuestionBase<T> {
|
||||||
label?: string,
|
label?: string,
|
||||||
required?: boolean,
|
required?: boolean,
|
||||||
order?: number,
|
order?: number,
|
||||||
controlType?: string
|
controlType?: string,
|
||||||
|
type?: string
|
||||||
} = {}) {
|
} = {}) {
|
||||||
this.value = options.value;
|
this.value = options.value;
|
||||||
this.key = options.key || '';
|
this.key = options.key || '';
|
||||||
|
@ -21,5 +24,6 @@ export class QuestionBase<T> {
|
||||||
this.required = !!options.required;
|
this.required = !!options.required;
|
||||||
this.order = options.order === undefined ? 1 : options.order;
|
this.order = options.order === undefined ? 1 : options.order;
|
||||||
this.controlType = options.controlType || '';
|
this.controlType = options.controlType || '';
|
||||||
|
this.type = options.type || '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { QuestionBase } from './question-base';
|
||||||
export class QuestionControlService {
|
export class QuestionControlService {
|
||||||
constructor() { }
|
constructor() { }
|
||||||
|
|
||||||
toFormGroup(questions: QuestionBase<any>[] ) {
|
toFormGroup(questions: QuestionBase<string>[] ) {
|
||||||
let group: any = {};
|
let group: any = {};
|
||||||
|
|
||||||
questions.forEach(question => {
|
questions.forEach(question => {
|
||||||
|
|
|
@ -4,15 +4,15 @@ import { Injectable } from '@angular/core';
|
||||||
import { DropdownQuestion } from './question-dropdown';
|
import { DropdownQuestion } from './question-dropdown';
|
||||||
import { QuestionBase } from './question-base';
|
import { QuestionBase } from './question-base';
|
||||||
import { TextboxQuestion } from './question-textbox';
|
import { TextboxQuestion } from './question-textbox';
|
||||||
|
import { of } from 'rxjs';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class QuestionService {
|
export class QuestionService {
|
||||||
|
|
||||||
// TODO: get from a remote source of question metadata
|
// TODO: get from a remote source of question metadata
|
||||||
// TODO: make asynchronous
|
|
||||||
getQuestions() {
|
getQuestions() {
|
||||||
|
|
||||||
let questions: QuestionBase<any>[] = [
|
let questions: QuestionBase<string>[] = [
|
||||||
|
|
||||||
new DropdownQuestion({
|
new DropdownQuestion({
|
||||||
key: 'brave',
|
key: 'brave',
|
||||||
|
@ -42,6 +42,6 @@ export class QuestionService {
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
return questions.sort((a, b) => a.order - b.order);
|
return of(questions.sort((a, b) => a.order - b.order));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue