0

I use angular material stepper. I take data from backend and according to this data I should set specific step. I use [selectedIndex] directive, but selectedIndex is not applied to value, that I pass to that. setTimeout I tried, it does not work for me. SelectedIndex is equal 0. Why selectedIndex is not applied to currentStep? And how to fix that?

    <mat-horizontal-stepper
    #stepper
    [selectedIndex]="currentStep"
    [linear]="true"
>
    <mat-step #step1 [completed]="step1.interacted || 0 < currentStep" [stepControl]="stepConfirmation.formGroup">
        <ng-template matStepLabel>Contact Info</ng-template>
        <fo-new-customer-confirmation-info #stepConfirmation></fo-new-customer-confirmation-info>
    </mat-step>
    <mat-step #step2 [completed]="step2.interacted || 1 < currentStep" [stepControl]="stepBusiness.formGroup">
        <ng-template matStepLabel>Business Info</ng-template>
        <fo-new-customer-business-info #stepBusiness></fo-new-customer-business-info>
    </mat-step>
    <mat-step #step3 [completed]="step3.interacted || 2 < currentStep" [stepControl]="stepApplicant.formGroup">
        <ng-template matStepLabel>Applicant Info</ng-template>
        <fo-new-customer-applicant-info #stepApplicant></fo-new-customer-applicant-info>
    </mat-step>
    <mat-step #step4 [completed]="step4.interacted || 3 < currentStep" [stepControl]="stepFinancial.formGroup">
        <ng-template matStepLabel>Financial Review</ng-template>
        <fo-new-customer-financial-review-info #stepFinancial></fo-new-customer-financial-review-info>
    </mat-step>
</mat-horizontal-stepper>
<footer class="row">
    {{stepper.selectedIndex}}
    <div>
        <button
            mat-button
            mat-flat-button
            *ngIf="stepper.selectedIndex !== 0"
            (click)="preview()"
            color="accent">
            Previous
        </button>
        <button
            class="mb-3 mb-sm-0 ml-auto"
            mat-button
            mat-flat-button
            color="primary"
            [ladda]="isDataUploading"
            *ngIf="stepper.selectedIndex !== stepper.steps?.length-1"
            (click)="next()">
            Next
        </button>
    </div>
</footer>

export class NewCustomerStepperComponent implements AfterViewInit {
    public stepperManager: StepperManager = {
        steps: {
            [StepperState.ContactInfoOrganic]: {
                control: null,
            },
            [StepperState.BusinessInfoOrganic]: {
                control: null,
            },
            [StepperState.ApplicantInfoOrganic]: {
                control: null,
            },
            [StepperState.FinancialReviewOrganic]: {
                control: null,
            },
        },
    };
public currentStep: number;
    public emptyGuid: string = '00000000-0000-0000-0000-000000000000';
    public isStepperStateWasChanged: boolean = false;
    public isDataUploading: boolean = false;
    @ViewChild('stepper', {static: true})
    public stepper: MatStepper;

    @ViewChild('stepConfirmation', {static: true})
    public stepConfirmationInfo: NewCustomerConfirmationInfoComponent;

    @ViewChild('stepBusiness', {static: true})
    public stepBusinessInfo: NewCustomerBusinessInfoComponent;

    @ViewChild('stepApplicant', {static: true})
    public stepApplicantInfo: NewCustomerApplicantInfoComponent;

    @ViewChild('stepFinancial', {static: true})
    public stepFinancialInfo: NewCustomerFinancialReviewInfoComponent;

    constructor(
        private readonly notificationService: NotificationService,
        private readonly formService: FormService,
        private readonly dataService: NewCustomerFormStepperDataService,
        private readonly authService: AuthService,
        private readonly navigationService: NavigationService,
    ) {
    }

    public ngAfterViewInit(): void {
        this.stepperManager.steps[StepperState.ContactInfoOrganic].control
            = this.stepConfirmationInfo;
        this.stepperManager.steps[StepperState.BusinessInfoOrganic].control
            = this.stepBusinessInfo;
        this.stepperManager.steps[StepperState.ApplicantInfoOrganic].control
            = this.stepApplicantInfo;
        this.stepperManager.steps[StepperState.FinancialReviewOrganic].control
            = this.stepFinancialInfo;
            this.redirectAccordingToStatus();

    }

    // public onStepChange(event: StepperSelectionEvent): void {
    //  // if (!this.isStepperStateWasChanged) {
    //  //  this.isStepperStateWasChanged = true;
    //  //  return;
    //  // }
    //  event.selectedStep.interacted = false;
    //  this.loadStepDataById(event.selectedIndex);
    // }

    public preview(): void {
        this.stepper.previous();
    }

    public next(): void {
        if (this.formService.isFormValid(
            this.stepperManager.steps[this.stepper.selectedIndex].control.formGroup)
        ) {
            this.isDataUploading = true;
            this.stepperManager.steps[this.stepper.selectedIndex].control
                .submit()
                .pipe(
                    take(1),
                )
                .subscribe(
                    () => {
                        this.isDataUploading = false;
                        this.stepper.next();
                        this.loadStepDataById(this.stepper.selectedIndex);
                    },

                );
        }
    }

    public setStepper(index: number): void {
        this.currentStep = index;
        this.stepper.selectedIndex = this.currentStep;
        this.loadStepDataById(index);

    }

    private mapLeadStatusToStepperState(status: LeadStatusRequest): number {
        return StepperState[status.value];
    }

    private loadStepDataById(id: number): void {
        this.stepperManager.steps[id].control
                .getData();
    }

    private getStatus(): Observable<LeadStatusRequest> {
        return this.dataService
            .getStatus()
            .pipe(
                take(1),
            );
    }

    private redirectAccordingToStatus(): void {
        this.getStatus()
            .subscribe(
                status => {
                    const id: number = status.id;

                    switch (id) {
                        case NewCustomerStatus.ContactInfoOrganic:
                        case NewCustomerStatus.BusinessInfoOrganic:
                        case NewCustomerStatus.ApplicantInfoOrganic:
                        case NewCustomerStatus.FinancialReviewOrganic:
                            this.currentStep = this.mapLeadStatusToStepperState(status);
                            this.setStepper(this.currentStep);
                            break;

                        default:
                            this.navigationService.navigateToErrorPage();
                    }
                },

            );
    }

}
developer033
  • 24,267
  • 8
  • 82
  • 108
prolina
  • 185
  • 4
  • 14

1 Answers1

4

Because you have set linear as true, the stepper index wont change. In your ts file, you need to set linear as false, then set index to whatever you wish to and then add a setTimeout and change the linear to true. So:

public setStepper(index: number): void {
    this.stepper.linear = false
    this.currentStep = index;
    this.stepper.selectedIndex = this.currentStep;
    setTimeout(() => {
        this.stepper.linear = true;
    });
    this.loadStepDataById(index);
}

this should do the trick.

Also if you wish that your previous steps be shown as completed if you are directly jumping to a particular step then you would need to do the following:

public setStepper(index: number): void {
    this.stepper.linear = false
    this.currentStep = index;
    while (this.stepper.selectedIndex < this.currentStep) {
        this.stepper.selectedIndex += 1;
    }
    this.stepper.selectedIndex = this.currentStep;
    setTimeout(() => {
        this.stepper.linear = true;
    });
    this.loadStepDataById(index);
}

Here the "while" loop will set all the indexes to selectedIndex prior to your preferred index one by one. This way you are tricking the stepper in believing that it has interacted with all the previous steps and it will mark them as completed.

Arfat
  • 117
  • 1
  • 1
  • 9