I want to be able to create a popup window which will load a certain Angular 4 component of mine when a radio button is selected.
It seems that the methods listed in the answers to this question are only compatible with Angular 2.
I am not sure where to begin and would appreciate any help!
Modals are small pop-up windows which are really handy when you want to display to the user extra content, configuration or consent request. To use modals, just follow the steps below. 1. Import the required ViewChild and Modal directives in app.component.ts.
Approach: Import NgbModal module in the TypeScript file of the corresponding component, and then we have to write code for the popup model by using the above module in the HTML file of the corresponding component. Now, we have to use ng-template to construct the model which will create a popup.
The accepted answer adds a large dependency to swat a fly. Modal (and modeless) dialogs are largely the result of a CSS class or two. Try this "rename..." example:
1) Write the parent and child-modal as if the child wasn't modal at all, but just an inline form with *ngIf attached.
Parent HTML that uses <my-modal>
child:
<div>
A div for {{name}}.
<button type="button" (click)="showModal()">Rename</button>
<my-modal *ngIf="showIt" [oldname]="name" (close)="closeModal($event)"></my-modal>
</div>
Parent class. The @Component
decorator omitted for brevity. (The name
property belongs to the parent class and would exist even if we didn't have a form to alter it.)
export class AppComponent {
name = "old name";
showIt = false;
showModal() {
this.showIt = true;
}
closeModal(newName: string) {
this.showIt = false;
if (newName) this.name = newName;
}
}
Child to-be-modal component. @Component
decorator and imports again omitted.
export class MyModalComponent {
@Input() oldname = "";
@Output() close = new EventEmitter<string>();
newname = "";
ngOnInit() {
// copy all inputs to avoid polluting them
this.newname = this.oldname;
}
ok() {
this.close.emit(this.newname);
}
cancel() {
this.close.emit(null);
}
}
Child HTML before modal-izing it.
<div>
Rename {{oldname}}
<input type="text" (change)="newname = $event.target.value;" />
<button type="button" (click)="ok()">OK</button>
<button type="button" (click)="cancel()">Cancel</button>
</div>
2) Here's the CSS for child, but it can be placed in a global stylesheet for re-use throughout your app. It's a single class called modal
and is intended for a <div>
element.
.modal {
/* detach from rest of the document */
position: fixed;
/* center */
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
/* ensure in front of rest of page -- increase as needed */
z-index: 1001;
/* visual illusion of being in front -- alter to taste */
box-shadow: rgba(0,0,0,0.4) 10px 10px 4px;
/* visual illusion of being a solid object -- alter to taste */
background-color: lightblue;
border: 5px solid darkblue;
/* visual preference of don't crowd the contents -- alter to taste */
padding: 10px;
}
But the modal
CSS class won't prevent interacting with the page underneath it. (So it technically creates a modeless dialog.) So we place an overlay
underneath the modal to absorb and ignore mouse activity. overlay
is also intended for a <div>
element.
.overlay {
/* detach from document */
position: fixed;
/* ensure in front of rest of page except modal */
z-index: 1000;
/* fill screen to catch mice */
top: 0;
left: 0;
width: 9999px;
height: 9999px;
/* dim screen 20% -- alter to taste */
opacity: 0.2;
background-color: black;
}
3) Use the modal
and overlay
in the child HTML.
<div class="modal">
Rename {{oldname}}
<input type="text" (change)="newname = $event.target.value;" />
<button type="button" (click)="ok()">OK</button>
<button type="button" (click)="cancel()">Cancel</button>
</div>
<div class="overlay"></div>
And that's it. Basically 2 CSS classes and you can make any component a modal. In fact you can show a component in-line or as a modal at run-time just by altering the existance of the CSS class with ngClass
or [class.modal]="showAsModalBoolean"
.
You can alter this so the child controls the show/hide logic. Move the *ngIf, showIt, and show() function into the child. In the parent add @ViewChild(MyModalComponent) renameModal: MyModalComponent;
and then the parent can imperatively call this.renameModal.show(this.name);
and re-wire initialization and containing divs as needed.
The child-modal can return info to a parent's function as shown above, or the child's show()
method could instead accept a callback or return a Promise, as per taste.
Two things to know:
this.renameModal.show(..);
won't work if there's an *ngIf on <my-modal>
because it won't exist to expose the function to begin with. *ngIf removes the whole component, show() function and all, so use [hidden]
instead if you need this for some reason.
Modals-on-modals will have z-index issues since they all share the same z-index. This can be solved with [style.z-index]="calculatedValue"
or similar.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With