Topic: Stepper in Modal: long form in first step bug

akrolis pro asked 2 years ago


Expected behavior

Complete Form inside the first step stepper is visible

Actual behavior

If the form in the fist step is formatted to be more than 2 rows, it doesn't show complete unless you focus on one input

Resources (screenshots, code snippets etc.)

html:

<button type="button" mdbBtn color="primary" class="relative waves-light" (click)="basicModal.show()" mdbWavesEffect>Launch demo modal</button>
    <div mdbModal #basicModal="mdbModal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myBasicModalLabel" aria-hidden="true">
      <div class="modal-dialog modal-lg modal-dialog-centered" role="document">
            <div class="modal-content">
              <div class="modal-header">
                <button type="button" class="close pull-right" aria-label="Close" (click)="basicModal.hide()">
                      <span aria-hidden="true">×</span>
                </button>
                 <h4 class="modal-title w-100" id="myModalLabel">Modal title</h4>
              </div>
              <div class="modal-body">
  <mdb-stepper #stepper>
     <mdb-step name="Step 1" [stepForm]="firstFormGroup">
          <form [formGroup]="firstFormGroup">
               <div class="container-fluid">
                    <div class="row">
                          <div class="col">
                               <div class="md-form">
                                   <input type="text" class="form-control" mdbInput mdbValidate formControlName="name">
                                   <label for="">Name</label>
                                    <mdb-error *ngIf="name.invalid && (name.dirty || name.touched)">Input invalid</mdb-error>
                                   <mdb-success *ngIf="name.valid && (name.dirty || name.touched)">Input valid</mdb-success>
                                </div>
                              </div>
                      <div class="col">
                            <div class="md-form">
                              <input type="text" class="form-control" mdbInput mdbValidate formControlName="surname">
                              <label for="">Surname</label>
                              <mdb-error *ngIf="surname.invalid && (surname.dirty || surname.touched)">Input invalid</mdb-error>
                              <mdb-success *ngIf="surname.valid && (surname.dirty || surname.touched)">Input valid</mdb-success>
                            </div>
                      </div>
                </div>
            <div class="row">
              <div class="col">
                <div class="md-form">
                  <input type="text" class="form-control" mdbInput mdbValidate formControlName="address">
                  <label for="">Address</label>
                </div>
              </div>
              <div class="col">
                <div class="md-form">
                  <input type="text" class="form-control" mdbInput mdbValidate formControlName="province">
                  <label for="">Province</label>
                </div>
              </div>
            </div>
            <div class="row">
              <div class="col">
                <div class="md-form">
                  <input type="text" class="form-control" mdbInput mdbValidate formControlName="phone1">
                  <label for="">Phone1</label>
                </div>
              </div>
              <div class="col">
                <div class="md-form">
                  <input type="text" class="form-control" mdbInput mdbValidate formControlName="phone2">
                  <label for="">Phone2</label>
                </div>
              </div>
            </div>
          </div>
        </form>
        <button mdbBtn size="sm" color="primary" (click)="stepper.next()">CONTINUE</button>
      </mdb-step>
      <mdb-step name="Step 2" [stepForm]="secondFormGroup">
        <form [formGroup]="secondFormGroup">
          <div class="md-form">
            <input type="password" class="form-control" mdbInput mdbValidate formControlName="password">
            <label for="">Password</label>
            <mdb-error *ngIf="password.invalid && (password.dirty || password.touched)">Input invalid</mdb-error>
            <mdb-success *ngIf="password.valid && (password.dirty || password.touched)">Input valid</mdb-success>
          </div>
        </form>
        <button mdbBtn size="sm" color="primary" (click)="stepper.next()">CONTINUE</button>
        <button mdbBtn size="sm" color="secondary" (click)="stepper.previous()">BACK</button>
      </mdb-step>
      <mdb-step name="Step 3" label="Step 3 label">
        <p class="pl-2">Finish!</p>
        <div class="step-actions">
          <button mdbBtn  size="sm" color="primary" (click)="onSubmit()">SUBMIT</button>
        </div>
      </mdb-step>
    </mdb-stepper>
</div>
   </div>

.ts

firstFormGroup: FormGroup;
  secondFormGroup: FormGroup;

ngOnInit() {
this.firstFormGroup = new FormGroup({
  name: new FormControl('', [Validators.required]),
  surname: new FormControl('', [Validators.required]),
  address: new FormControl('', [Validators.required]),
  provice: new FormControl('', [Validators.required]),
  phone1: new FormControl('', [Validators.required]),
  phone2: new FormControl('', [Validators.required]),
});
this.secondFormGroup = new FormGroup({
  password: new FormControl('', Validators.required)
});
  }

get name() { return this.firstFormGroup.get('name'); }
  get surname() { return this.firstFormGroup.get('surname'); }
  get password() { return this.secondFormGroup.get('password'); }

  onSubmit() {
    // do something here
  }

screenshots: enter image description here

enter image description here


Arkadiusz Idzikowski staff answered 2 years ago


It looks like in static modal stepper component is initialized before modal is opened and before step content is added to the DOM. In this case it is difficult to update the step height correctly.

Please try to use dynamic modal and add small delay for stepper init like in the following example (this is html/ts code of the dynamic modal):

https://mdbootstrap.com/docs/angular/modals/basic/#dynamic

HTML:

<mdb-stepper #stepper *ngIf="visible">
  <mdb-step name="Step 1" [stepForm]="firstFormGroup">
    <form [formGroup]="firstFormGroup">
      <div class="container-fluid">
        <div class="row">
          <div class="col">
            <div class="md-form">
              <input type="text" class="form-control" mdbInput mdbValidate formControlName="name" />
              <label for="">Name</label>
              <mdb-error *ngIf="name?.invalid && (name?.dirty || name?.touched)"
                >Input invalid</mdb-error
              >
              <mdb-success *ngIf="name?.valid && (name?.dirty || name?.touched)"
                >Input valid</mdb-success
              >
            </div>
          </div>
          <div class="col">
            <div class="md-form">
              <input
                type="text"
                class="form-control"
                mdbInput
                mdbValidate
                formControlName="surname"
              />
              <label for="">Surname</label>
              <mdb-error *ngIf="surname?.invalid && (surname?.dirty || surname?.touched)"
                >Input invalid</mdb-error
              >
              <mdb-success *ngIf="surname?.valid && (surname?.dirty || surname?.touched)"
                >Input valid</mdb-success
              >
            </div>
          </div>
        </div>
        <div class="row">
          <div class="col">
            <div class="md-form">
              <input
                type="text"
                class="form-control"
                mdbInput
                mdbValidate
                formControlName="address"
              />
              <label for="">Address</label>
            </div>
          </div>
          <div class="col">
            <div class="md-form">
              <input
                type="text"
                class="form-control"
                mdbInput
                mdbValidate
                formControlName="province"
              />
              <label for="">Province</label>
            </div>
          </div>
        </div>
        <div class="row">
          <div class="col">
            <div class="md-form">
              <input
                type="text"
                class="form-control"
                mdbInput
                mdbValidate
                formControlName="phone1"
              />
              <label for="">Phone1</label>
            </div>
          </div>
          <div class="col">
            <div class="md-form">
              <input
                type="text"
                class="form-control"
                mdbInput
                mdbValidate
                formControlName="phone2"
              />
              <label for="">Phone2</label>
            </div>
          </div>
        </div>
      </div>
    </form>
    <button mdbBtn size="sm" color="primary" (click)="stepper.next()">CONTINUE</button>
  </mdb-step>
  <mdb-step name="Step 2" [stepForm]="secondFormGroup">
    <form [formGroup]="secondFormGroup">
      <div class="md-form">
        <input
          type="password"
          class="form-control"
          mdbInput
          mdbValidate
          formControlName="password"
        />
        <label for="">Password</label>
        <mdb-error *ngIf="password?.invalid && (password?.dirty || password?.touched)"
          >Input invalid</mdb-error
        >
        <mdb-success *ngIf="password?.valid && (password?.dirty || password?.touched)"
          >Input valid</mdb-success
        >
      </div>
    </form>
    <button mdbBtn size="sm" color="primary" (click)="stepper.next()">CONTINUE</button>
    <button mdbBtn size="sm" color="secondary" (click)="stepper.previous()">BACK</button>
  </mdb-step>
  <mdb-step name="Step 3" label="Step 3 label">
    <p class="pl-2">Finish!</p>
    <div class="step-actions">
      <button mdbBtn size="sm" color="primary" (click)="onSubmit()">SUBMIT</button>
    </div>
  </mdb-step>
</mdb-stepper>

TS:

  firstFormGroup: FormGroup;
  secondFormGroup: FormGroup;

  visible = false;

  ngOnInit() {
    this.firstFormGroup = new FormGroup({
      name: new FormControl('', [Validators.required]),
      surname: new FormControl('', [Validators.required]),
      address: new FormControl('', [Validators.required]),
      province: new FormControl('', [Validators.required]),
      phone1: new FormControl('', [Validators.required]),
      phone2: new FormControl('', [Validators.required]),
    });
    this.secondFormGroup = new FormGroup({
      password: new FormControl('', Validators.required),
    });

    setTimeout(() => {
      this.visible = true;
    }, 0);
  }

  get name() {
    return this.firstFormGroup.get('name');
  }
  get surname() {
    return this.firstFormGroup.get('surname');
  }
  get password() {
    return this.secondFormGroup.get('password');
  }

  onSubmit() {
    // do something here
  }


Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Answered

Specification of the issue

  • ForumUser: Pro
  • Premium support: No
  • Technology: MDB Angular
  • MDB Version: MDB4 11.1.0
  • Device: Desktop
  • Browser: Chrome
  • OS: Windows
  • Provided sample code: No
  • Provided link: No