Search code examples
angulartypescriptwizardformgroups

form group in wizard (check validation of some elements)


I have a 2 steps wizard with a form group in it, and in first step on clicking next page button i want to check the validity of that formgroup elements those are in first step. my question is :

1 - is it better to use 2 different forms in every wizard step or use one formgroup in all steps of wizard?

2 - if i use one formgroup how can i check the part of form validity in every step?

My template code :

<wizard #wizard navBarLayout="large-empty-symbols">
    <wizard-step [canExit]="moveDirection.bind(this, formGroup.valid)" navigationSymbol="1">
        <form [formGroup]="formGroup">
            <input-form-control
                    [required]="true"
                    [group]="formGroup"
                    label="Name"
                    name="name"
                    controlId="name"
                    helpText="Enter the Server Unit Name"
            >
            </input-form-control>
            <input-form-control
                    [required]="true"
                    [group]="formGroup"
                    label="Label"
                    name="label"
                    controlId="label"
                    helpText="Enter the Server Unit Label"
            >
            </input-form-control>
            <input-form-control
                    [required]="false"
                    [group]="formGroup"
                    label="Description"
                    name="description"
                    controlId="description"
                    helpText="Enter the Server Unit Description"
            >
            </input-form-control>
            <div class="m-portlet__foot m-portlet__foot--fit">
                <div class="m-form__actions m-form__actions">
                    <div class="row justify-content-center">
                        <div class="col-lg-9 ml-lg-auto">
                            <button routerLink="/asset/server-unit" class="btn btn-secondary">
                                Cancel
                            </button>
                            <button class="btn btn-primary" (click)="checkFormValidity()"
                                    id="next-step" type="button" nextStep>
                                Next
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        </form>
    </wizard-step>
    <wizard-step [canExit]="moveDirection.bind(this, formGroup.valid)" navigationSymbol="2">
        <form [formGroup]="step2formGroup">
            <switch-form-control
                    label="Enable Execution"
                    controlName="execution"
                    controlId="enable-execution"
                    helpText="Set Job Enable Execution state"
            >
            </switch-form-control>
            <div class="m-portlet__foot m-portlet__foot--fit">
                <div class="m-form__actions m-form__actions">
                    <div class="row justify-content-center">
                        <div class="col-lg-9 ml-lg-auto">
                            <button routerLink="/asset/server-unit" class="btn btn-secondary">
                                Cancel
                            </button>
                            <button class="btn btn-primary" id="previous-step" type="button" previousStep>
                                Previous
                            </button>
                            <button class="btn btn-success" (click)="registerItem()" id="submit" type="button" [loadingBtn]="promise">
                                {{isEdit ? "Update" : "Add"}}
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        </form>
    </wizard-step>
</wizard>

Solution

  • in my app i used multiple forms for every wizard step and it worked well then i decided to post my experience to help others that have my problem:

    my html:

    <wizard #wizard navBarLayout="large-empty-symbols">
                    <wizard-step [canExit]="moveDirection.bind(this, formGroups.step1formGroup.valid)" navigationSymbol="1">
                        <form [formGroup]="formGroups.step1formGroup">
                            <input-form-control
                                    [required]="true"
                                    [group]="formGroups.step1formGroup"
                                    label="Name"
                                    name="name"
                                    controlId="name"
                                    helpText="Enter the Server Unit Name"
                            >
                            </input-form-control>
                            <div class="m-portlet__foot m-portlet__foot--fit">
                                <div class="m-form__actions m-form__actions">
                                    <div class="row justify-content-center">
                                        <div class="col-lg-9 ml-lg-auto">
                                            <button routerLink="/asset/server-unit" class="btn btn-secondary">
                                                Cancel
                                            </button>
                                            <button class="btn btn-primary" (click)="checkFormValidity('step1formGroup')" id="next-step" type="button" nextStep>
                                                Next
                                            </button>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </form>
                    </wizard-step>
                    <wizard-step [canExit]="moveDirection.bind(this, formGroups.step2formGroup.valid)" navigationSymbol="2">
                        <form [formGroup]="formGroups.step2formGroup">
                            <switch-form-control
                                    label="Enable Execution"
                                    controlName="execution"
                                    id="enable-execution"
                                    helpText="Set Job Enable Execution state"
                            >
                            </switch-form-control>
                            <div class="m-portlet__foot m-portlet__foot--fit">
                                <div class="m-form__actions m-form__actions">
                                    <div class="row justify-content-center">
                                        <div class="col-lg-9 ml-lg-auto">
                                            <button routerLink="/asset/server-unit" class="btn btn-secondary">
                                                Cancel
                                            </button>
                                            <button class="btn btn-primary" id="previous-step" type="button" previousStep>
                                                Previous
                                            </button>
                                            <button class="btn btn-success" (click)="registerItem('step2formGroup')" id="submit" type="button" [loadingBtn]="promise">
                                                {{isEdit ? "Update" : "Add"}}
                                            </button>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </form>
                    </wizard-step>
                </wizard>
    

    my component:

    export class AppComponent  {
    
      constructor(formBuilder: FormBuilder) {
    
                  let controlsConfig = { step1formGroup: {
                        "name": ['', Validators.required]
                    },
                    step2formGroup: {
                        "execution": [true]
    
                    }
                }
    
                for (let item in this.controlsConfig) {
                this.formGroups[item] = this.formBuilder.group(controlsConfig[item]);
            }
      }
    
      moveDirection = (validityStatus, direction) => {
            if (direction === MovingDirection.Backwards) {
                return true;
            }
            return validityStatus;
        };
    
        storeData(dataType, data) {
            console.log(dataType);
            if (!this.formGroups.step1formGroup.controls[dataType] && !this.formGroups.step2formGroup.controls[dataType]) {
                return;
            }
            let formGroup: string = '';
            if (this.formGroups.step1formGroup.controls[dataType]) {
                formGroup = 'step1formGroup';
            } else {
                formGroup = 'step2formGroup';
            }
            this.formGroups[formGroup].controls[dataType].setValue(data.value);
        }
    
          registerItem(index) {
    
            if (!this.formGroups[index].valid) {
                this.checkFormValidity(index);
                return;
            }
            this.submit().then(() => {
                this.notificationService.setNotifies({
                    message: this.isEdit ? 'Device Edited Successfully.' : 'Device Added Successfully.',
                    type: 'success'
                });
                this.router.navigate([this.url]);
            }, error => {
                this.notificationService.setNotifies({
                    message: this.errorMapperService.mapper(error.errorCode || ''),
                    type: 'danger'
                });
            });
        }
    
        addItem() {
            let formData = Object.assign({});
            for (let formGroup in this.formGroups) {
                formData = Object.assign(formData, this.formGroups[formGroup].value);
            }
            return this.deviceDataService.registerDevice(this.responseMapper(formData, 'isInAdd'), this.assetName);
        }
    
        updateItem() {
            let formData = Object.assign({});
            for (let formGroup in this.formGroups) {
                formData = Object.assign(formData, this.formGroups[formGroup].value);
            }
            return this.deviceDataService.updateDevice(this.responseMapper(formData, 'isInUpdate'), this.assetName);
        }
    
        checkFormValidity(index) {
            for (let item in this.formGroups[index].controls) {
                this.formGroups[index].controls[item].markAsTouched();
            }
        }
    }
    

    i used ng2-archwizard, hope this answer helps.