Skip to content

Commit 5e98dc0

Browse files
authored
Update README.md
1 parent 5113ca3 commit 5e98dc0

File tree

1 file changed

+231
-0
lines changed

1 file changed

+231
-0
lines changed

README.md

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,233 @@
11
# Dynamically-Loaded-Bootstrap-Modal-Component-by-Angular-6
22
Dynamically Loaded Bootstrap Modal Component by Angular 6
3+
4+
Create the application using the Angular CLI command.
5+
6+
ng new modal
7+
Update the index.html file to reference the Bootstrap Css - using the CDN.
8+
9+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
10+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
11+
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
12+
13+
App Component
14+
Keep two buttons in app.componenet.html for loading two different modal popups.
15+
16+
app.component.html
17+
18+
<div class="col-md-2">
19+
<button type="button"
20+
class="btn btn-success btn-block"
21+
modal-box
22+
[title]='"Demo Modal 1"'
23+
[componentData]="data1"
24+
[componentName]="'Demo1Component'">
25+
Demo Modal 1
26+
</button>
27+
</div>
28+
29+
<div class="col-md-2">
30+
<button type="button"
31+
class="btn btn-danger btn-block"
32+
modal-box
33+
[title]='"Demo Modal 2"'
34+
[componentData]="data2"
35+
[componentName]="'Demo2Component'">
36+
Demo Modal 2
37+
</button>
38+
</div>
39+
app.component.ts
40+
41+
export class AppComponent {
42+
data1 : string;
43+
data2 : string;
44+
45+
46+
ngOnInit() {
47+
this.data1="The content is displayed from Demo1 component";
48+
this.data2="The content is displayed from Demo2 component";
49+
}
50+
51+
}
52+
app.module.ts
53+
54+
import { BrowserModule } from '@angular/platform-browser';
55+
import { NgModule } from '@angular/core';
56+
import { HttpClientModule } from '@angular/common/http';
57+
58+
import { AppComponent } from './app.component';
59+
import { Demo1Component } from './demo1/demo1.component';
60+
import { Demo2Component } from './demo2/demo2.component';
61+
import { ModalDialogComponent } from './modal-dialog/modal-dialog.component';
62+
import { ModalDirective } from './modal.directive';
63+
import { DatacontainerDirective } from './modal-dialog/datacontainer.directive';
64+
import { ComponentLoaderService } from './component-loader.service';
65+
66+
@NgModule({
67+
declarations: [
68+
AppComponent,
69+
Demo1Component,
70+
Demo2Component,
71+
ModalDialogComponent,
72+
ModalDirective,
73+
DatacontainerDirective
74+
],
75+
providers: [ComponentLoaderService],
76+
imports: [
77+
BrowserModule,
78+
HttpClientModule
79+
],
80+
entryComponents: [
81+
Demo1Component,
82+
Demo2Component,
83+
ModalDialogComponent
84+
],
85+
bootstrap: [AppComponent]
86+
})
87+
export class AppModule { }
88+
89+
entryComponent is used for components declaration which will be loaded dynamically.
90+
91+
Modal Directive
92+
modal.directive.ts
93+
94+
import { Directive, Input, Output, EventEmitter, ElementRef, HostListener, Renderer2, ViewContainerRef, ComponentFactoryResolver } from '@angular/core';
95+
import { ModalDialogComponent } from './modal-dialog/modal-dialog.component';
96+
97+
@Directive({
98+
selector: '[modal-box]'
99+
})
100+
export class ModalDirective {
101+
@Input() title: string;
102+
@Input() componentData: string;
103+
@Input() componentName: string;
104+
105+
106+
@HostListener('click', ['$event'])
107+
108+
/* modal create */
109+
openModal() {
110+
this.createModalDialog(ModalDialogComponent);
111+
}
112+
113+
constructor(
114+
private el: ElementRef,
115+
private ren: Renderer2,
116+
private viewContainer: ViewContainerRef,
117+
private componentFactoryResolver: ComponentFactoryResolver
118+
) { }
119+
120+
ngOnInit() {
121+
}
122+
123+
createModalDialog(modalDialogComponent) {
124+
this.viewContainer.clear();
125+
const modalDialogComponentFactory = this.componentFactoryResolver.resolveComponentFactory(modalDialogComponent);
126+
const modalDialogComponentRef = this.viewContainer.createComponent(modalDialogComponentFactory);
127+
modalDialogComponentRef.instance['title'] = this.title;
128+
modalDialogComponentRef.instance['componentData'] = this.componentData;
129+
modalDialogComponentRef.instance['componentName'] = this.componentName;
130+
131+
return modalDialogComponentRef;
132+
}
133+
134+
135+
}
136+
createModalDialog() function is used to create modal dialog componenet dynamically. You have to send modalDialogComponent through resolveComponenetFactory to create factory then will create component using createComponent function. We are fetching values of title, componentData, componentName from buttons which were declared in app.componenet.html. These value sends using modalDialogComponentRef.instance to modal-dialog.componenet.ts.
137+
138+
Modal Dialog Component
139+
modal-dialog.component.css
140+
141+
.modal{
142+
display: block;
143+
}
144+
modal-dialog.component.html
145+
146+
<!-- Modal -->
147+
<div class="modal fade in" role="dialog" tabindex="-1" aria-hidden="true" #thisModal>
148+
<div class="modal-dialog">
149+
150+
<!-- Modal content-->
151+
<div class="modal-content">
152+
<div class="modal-header">
153+
<button type="button" class="close" (click)="closeModal()"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
154+
<h4 class="modal-title">{{ title }}</h4>
155+
</div>
156+
<div class="modal-body">
157+
<div #datacontainer></div>
158+
</div>
159+
<div class="modal-footer">
160+
<button type="button" class="btn btn-default" (click)="closeModal()">Close</button>
161+
</div>
162+
</div>
163+
164+
</div>
165+
166+
modal-dialog.component.ts
167+
168+
import {
169+
Component, Input, OnInit,
170+
ComponentFactoryResolver, ViewContainerRef, ViewChild, ElementRef, Renderer2, AfterContentInit
171+
} from '@angular/core';
172+
import { ComponentLoaderService } from '../component-loader.service';
173+
174+
175+
@Component({
176+
selector: 'modal-dialog',
177+
templateUrl: './modal-dialog.component.html',
178+
styleUrls: ['./modal-dialog.component.css']
179+
})
180+
181+
export class ModalDialogComponent implements OnInit, AfterContentInit {
182+
@Input() title: string;
183+
@Input() componentData: string;
184+
@Input() componentName: any;
185+
public name : any;
186+
187+
@ViewChild('datacontainer', { read: ViewContainerRef }) entry: ViewContainerRef;
188+
189+
constructor(
190+
private el: ElementRef,
191+
private ren: Renderer2,
192+
private viewContainer: ViewContainerRef,
193+
private resolver: ComponentFactoryResolver,
194+
private loaderService :ComponentLoaderService
195+
) {}
196+
197+
public div = this.ren.createElement('div');
198+
199+
ngOnInit() {
200+
201+
}
202+
203+
ngAfterContentInit(){
204+
this.ren.addClass(this.el.nativeElement.ownerDocument.body, 'modal-open');
205+
this.ren.appendChild(this.el.nativeElement, this.div);
206+
this.ren.setAttribute(this.div , 'class', 'modal-backdrop fade in');
207+
this.createModalPopup();
208+
}
209+
210+
createModalPopup(){
211+
const name = this.loaderService.getComponent(this.componentName);
212+
console.log("Component Name => ",name);
213+
const myFactory = this.resolver.resolveComponentFactory(<any>name);
214+
const myRef = this.entry.createComponent(myFactory);
215+
myRef.instance['data'] = this.componentData;
216+
}
217+
218+
closeModal() {
219+
this.ren.removeClass(this.el.nativeElement.ownerDocument.body, 'modal-open');
220+
this.ren.removeChild(this.el.nativeElement, this.div);
221+
this.el.nativeElement.remove();
222+
}
223+
224+
225+
}
226+
227+
this.ren.addClass is used to add 'modal-open' class on creating modal-dialog. this.ren.appendChild is used append div in body. this.ren.setAttribute is used to add class name 'modal-backdrop fade in' in div which shows when modal-dialog opens for overlay.
228+
229+
this.createModalPopup() is called for loading component dynamically. Component is coming from buttons of app.componenet.html page and this.componentName is used to hold componenent name. loaderService is used to pass a component according to the component name. That component is passing to the resolveComponentFactory, createComponent function to create the component accordingly. We are passing the componentData using myRef.instance['data'] to component like demo1 or demo2.
230+
231+
That data is fetching from demo1 and demo2 component using @Input() and displaing it from html file.
232+
233+
closeModal() is used to remove the modal. this.el.nativeElement.remove() is used to remove DOM element.

0 commit comments

Comments
 (0)