ngconf
Published in

ngconf

Multi-Step Forms in Angular

tldr;

Multi-Step Form Container

$ ng g c form-container
type Step = 'personalInfo' | 'loginInfo';export class FormContainerComponent implements OnInit {
private currentStepBs: BehaviorSubject<Step> = new BehaviorSubject<Step>('personalInfo');
public currentStep$: Observable<Step> = this.currentStepBs.asObservable();
public userForm: FormGroup;constructor(private _fb: FormBuilder) {}ngOnInit() {
this.userForm = this._fb.group({
personalInfo: null,
loginInfo: null
});
}
subformInitialized(name: string, group: FormGroup) {
this.userForm.setControl(name, group);
}
changeStep(currentStep: string, direction: 'forward' | 'back') {
switch(currentStep) {
case 'personalInfoStep':
if (direction === 'forward') {
this.currentStepBs.next('loginInfo');
}
break;
case 'loginInfoStep':
if (direction === 'back') {
this.currentStepBs.next('personalInfo');
}
break;
}
}
submitForm() {
const formValues = this.userForm.value;
// submit the form with a service
}
}
<ng-container [ngSwitch]="currentStep$ | async">
<app-personal-info
*ngSwitchCase="'personalInfo'"
[startingForm]="userForm.get('personalInfo').value"
(subformInitialized)="subformInitialized('personalInfo', $event)"
(changeStep)="changeStep('personalInfoStep', $event)"
></app-personal-info>
<app-login-info
*ngSwitchCase="'loginInfo'"
[startingForm]="userForm.get('loginInfo').value"
(subformInitialized)="subformInitialized('loginInfo', $event)"
(changeStep)="changeStep('loginInfoStep', 'back')"
(submitForm)="submitForm()"
></app-login-info>
</ng-container>

Individual Steps

$ ng g c personal-info
export class PersonalInfoComponent implements OnInit {
@Input() startingForm: FormGroup;
@Output() subformInitialized: EventEmitter<FormGroup> = new EventEmitter<FormGroup>();
@Output() changeStep: EventEmitter<boolean> = new EventEmitter<boolean>();
public personalInfoForm: FormGroup;
constructor(private _fb: FormBuilder) {}ngOnInit() {
if (this.startingForm) {
this.personalInfoForm = this.startingForm;
} else {
this.personalInfoForm = this._fb.group({
firstName: '',
lastName: '',
// ... continue with the other fields
})
}
this.subformInitialized.emit(this.personalInfoForm);
}
doChangeStep(direction: 'forward') {
this.changeStep.emit(direction);
}
}

Conclusion

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store