}
diff --git a/libs/doc-pages/modal/src/lib/demos/service-component/service-component.css b/libs/doc-pages/modal/src/lib/demos/service-component/service-component.css
new file mode 100644
index 0000000000..69ef488b1c
--- /dev/null
+++ b/libs/doc-pages/modal/src/lib/demos/service-component/service-component.css
@@ -0,0 +1,4 @@
+.profit {
+ color: green;
+ font-weight: 700;
+}
diff --git a/libs/doc-pages/modal/src/lib/demos/service-component/service-component.ts b/libs/doc-pages/modal/src/lib/demos/service-component/service-component.ts
index a4ffe465fe..4eb138385c 100644
--- a/libs/doc-pages/modal/src/lib/demos/service-component/service-component.ts
+++ b/libs/doc-pages/modal/src/lib/demos/service-component/service-component.ts
@@ -12,12 +12,14 @@ export class DemoModalServiceFromComponent {
openModalWithComponent() {
const initialState: ModalOptions = {
+ container: 'bs-demo',
initialState: {
list: [
'Open a modal with component',
'Pass your data',
'Do something else',
- '...'
+ '...',
+ 'Push button to find out!'
],
title: 'Modal with component'
}
@@ -32,6 +34,7 @@ export class DemoModalServiceFromComponent {
@Component({
// eslint-disable-next-line @angular-eslint/component-selector
selector: 'modal-content',
+ styleUrls: ['./service-component.css'],
template: `
`
})
-export class ModalContentComponent implements OnInit {
+export class ModalContentComponent {
title?: string;
+ profitBtnPressed: boolean = false;
closeBtnName?: string;
list: any[] = [];
constructor(public bsModalRef: BsModalRef) {}
- ngOnInit() {
- this.list.push('PROFIT!!!');
+ showProfit() {
+ this.profitBtnPressed = true;
+ this.list[this.list.length - 1] = 'PROFIT!!!';
}
}
diff --git a/libs/doc-pages/modal/src/lib/modal-section.list.ts b/libs/doc-pages/modal/src/lib/modal-section.list.ts
index 86d61b8526..2311a1e6cd 100644
--- a/libs/doc-pages/modal/src/lib/modal-section.list.ts
+++ b/libs/doc-pages/modal/src/lib/modal-section.list.ts
@@ -60,6 +60,7 @@ export const demoComponentContent: ContentSection[] = [
anchor: 'service-component',
component: require('!!raw-loader!./demos/service-component/service-component.ts'),
html: require('!!raw-loader!./demos/service-component/service-component.html'),
+ style: require('!!raw-loader!./demos/service-component/service-component.css'),
description: `Creating a modal with component just as easy as it is with template. Just pass your component
in .show()
method as in example, and don't forget to include your component to
entryComponents
of your NgModule
If you passed a component
diff --git a/src/modal/bs-modal.service.ts b/src/modal/bs-modal.service.ts
index a5a253b24a..71da52fc18 100644
--- a/src/modal/bs-modal.service.ts
+++ b/src/modal/bs-modal.service.ts
@@ -110,7 +110,7 @@ export class BsModalService {
if (isBackdropEnabled && isBackdropInDOM) {
this._backdropLoader
.attach(ModalBackdropComponent)
- .to('body')
+ .to(this.config.container)
.show({ isAnimated: this.config.animated });
this.backdropRef = this._backdropLoader._componentRef;
}
@@ -140,7 +140,7 @@ export class BsModalService {
.provide({ provide: ModalOptions, useValue: this.config })
.provide({ provide: BsModalRef, useValue: bsModalRef })
.attach(ModalContainerComponent)
- .to('body');
+ .to(this.config.container);
bsModalRef.hide = () => this.hide(bsModalRef.id);
bsModalRef.setClass = (newClass: string) => {
if (modalContainerRef.instance) {
diff --git a/src/modal/modal-options.class.ts b/src/modal/modal-options.class.ts
index 37ff61e066..392edf6b86 100644
--- a/src/modal/modal-options.class.ts
+++ b/src/modal/modal-options.class.ts
@@ -1,4 +1,4 @@
-import { Injectable, StaticProvider, InjectionToken } from '@angular/core';
+import { ElementRef, Injectable, StaticProvider, InjectionToken } from '@angular/core';
import { ClassName, CloseInterceptorFn, DismissReasons, Selector, TransitionDurations } from './models';
@Injectable({providedIn: 'platform'})
@@ -30,6 +30,10 @@ export class ModalOptions> {
* Css class for opened modal
*/
class?: string;
+ /**
+ * CSS selector or ElementRef to which the modal is appended
+ */
+ container?: string | ElementRef;
/**
* Toggle animation
*/
@@ -63,6 +67,7 @@ export const modalConfigDefaults: ModalOptions = {
show: false,
ignoreBackdropClick: false,
class: '',
+ container: 'body',
animated: true,
initialState: {},
closeInterceptor: void 0
diff --git a/src/modal/modal.directive.ts b/src/modal/modal.directive.ts
index 0d72bccf62..4393a4302b 100644
--- a/src/modal/modal.directive.ts
+++ b/src/modal/modal.directive.ts
@@ -337,7 +337,7 @@ export class ModalDirective implements OnDestroy, OnInit {
this.removeBackdrop();
this._backdrop
.attach(ModalBackdropComponent)
- .to('body')
+ .to(this._config.container)
.show({ isAnimated: this._config.animated });
this.backdrop = this._backdrop._componentRef;
diff --git a/src/modal/testing/modal.service.spec.ts b/src/modal/testing/modal.service.spec.ts
index 9c0c6a7409..522b5e8e8e 100644
--- a/src/modal/testing/modal.service.spec.ts
+++ b/src/modal/testing/modal.service.spec.ts
@@ -4,7 +4,9 @@ import { pairwise, tap } from 'rxjs/operators';
import { BsModalService, ModalModule } from '../index';
-@Component({ template: 'Dummy Component
' })
+@Component({
+ selector: 'dummy-component',
+ template: 'Dummy Component
' })
class DummyComponent {
// eslint-disable-next-line @typescript-eslint/no-empty-function,@typescript-eslint/no-unused-vars
constructor(modalService: BsModalService) { }
@@ -130,4 +132,20 @@ describe('Modal service', () => {
jest.runAllTimers();
expect(onHiddenSpy).toHaveBeenCalledWith({ id });
});
+
+ it('should render in element by default', done => {
+ modalService.onShown.subscribe((data) => {
+ expect(document.querySelector('dummy-component modal-container')).toBeDefined();
+ done();
+ })
+ modalService.show(TestModalComponent);
+ })
+
+ it('should render in the container selector provided', done => {
+ modalService.onShown.subscribe((data) => {
+ expect(document.querySelector('dummy-component modal-container')).toBeDefined();
+ done();
+ })
+ modalService.show(TestModalComponent, { container: 'dummy-component'});
+ })
});