valor-software / ngx-bootstrap

Fast and reliable Bootstrap widgets in Angular (supports Ivy engine)
https://valor-software.com/ngx-bootstrap
MIT License
5.53k stars 1.69k forks source link

Close modal make body scrollable #6683

Open frenzymind opened 2 days ago

frenzymind commented 2 days ago

Hello. May be it can be related with this bug getModalsCount issue

Bug description:

With nested modals, when you close upper one, it is make body scrollable again (remove class 'modal-open' from body and inline styles). When modal it self have a content to scroll, it is impossible to scroll modal for now, and this is the issue.

Code that reproduces the issue:

Use example from official docs: Nested modals:

  1. press 'open first modal' button
  2. press 'open seconds modal' button
  3. Check that body have no scroll
  4. press 'close self'
  5. body have scroll from now

Versions of ngx-bootstrap, Angular, and Bootstrap:

ngx-bootstrap: 18.0.2

Angular: 18.2.2

Bootstrap: 4.6.2

Expected behavior

No scroll on body, when there is at least one opened modal exists.

frenzymind commented 2 days ago

I have to manually check count of modals. My workaround:

const BODY_OPEN_MODAL_CLASS = 'modal-open';

@Injectable()
export class NgxCustomBsModalService extends BsModalService {
  private rendererFactory = inject(RendererFactory2);
  private renderer2 = this.rendererFactory.createRenderer(null, null);

  override hide(id?: number | string): void {

    this._hideBackdrop();
    this._hideModal(id);

    const bodyEl = document.querySelector('body')!;
    const openModalsEl = document.querySelectorAll('modal-container');

    if (openModalsEl.length > 0) {
      if (bodyEl.classList.contains(BODY_OPEN_MODAL_CLASS) === false) {
        this.renderer2.addClass(bodyEl, BODY_OPEN_MODAL_CLASS);
      }
    } else {
      this.renderer2.removeClass(bodyEl, BODY_OPEN_MODAL_CLASS);
      this.renderer2.removeStyle(bodyEl, 'padding-right');
      this.renderer2.removeStyle(bodyEl, 'overflow-y');
    }
  }
}

and in my app module file:

  providers: [
    // ...
    { provide: BsModalService, useClass: NgxCustomBsModalService },
  ],
})
export class AppModule {}