-
Notifications
You must be signed in to change notification settings - Fork 93
How to use the MdlDialogService
Insert the dialog-outlet
element as the last child of the body
element and start using the imperative and declarative dialogs.
<html>
<head>...</head>
<body>
<app-root>...</app-root>
<dialog-outlet></dialog-outlet>
</body>
</html>
The dialog implementation did not touch the dom
directly (for example document.body.appendChild
or something like this)! To got this working every dialog needs an instance of a ViewContainerRef
where the dialog html can be attached to. There are different ways how you can provide an instance of a ViewContainerRef
:
- place the component
dialog-outlet
next to the body element of your html file (as seen above) - place the component
dialog-outlet
anywhere as a child of your root-app element. But be aware that the dialogs and the dialog backdrop may not cover your whole html page and the z-index may not work. - If you already have an instance of a
ViewContainerRef
you can inject theMdlDialogOutletService
and callsetDefaultViewContainerRef
to tell the dialogs where they should be attached.
If you are using the showCustomDialog
function of the MdlDialogService
make sure that the Component
you are using is defined as an EntryComponent
. This means it must be part of the entryComponents
property of an NgModule
Imperative usage means that you are using the MdlDialogService
and create your dialogs from your TypeScript code. There are some built-in Dialogs which can be used by a simple API:
###Alert
let result = this.dialogService.alert('This is a simple Alert');
result.subscribe( () => console.log('alert closed') );
The complete function signature is:
alert(alertMessage: string, okText = 'Ok', title?: string): Observable<void>
An Alert
is always displayed as a modal dialog. The alertMessage
can be a simple text or html. As you can see the title is optional.
let result = this.dialogService.confirm('Would you like a mug of coffee?', 'No', 'Yes');
result.subscribe( () => {
console.log('confirmed');
},
(err: any) => {
console.log('declined');
}
);
The complete function signature is:
public confirm(question: string, declineText = 'Cancel', confirmText = 'Ok'): Observable<void>
A Confirm
is always displayed as a modal dialog. The question
can be a simple text or html.
The Alert
and Confirm
dialog are just a special case of a more general prebuilt dialog:
let pDialog = this.dialogService.showDialog({
title: 'Your choice?',
message: 'What drink do you prefer to your meal?',
actions: [
{
handler: () => { console.log('Coke'); },
text: 'One Coke' ,
isClosingAction: true
},
{
handler: () => { console.log('Vine'); },
text: 'A bottle of vine'
},
{
handler: () => { console.log('Beer'); },
text: 'A pint of beer'
}
],
fullWidthAction: true,
isModal: false
});
pDialog.subscribe( (dialogReference) => console.log('dialog visible', dialogReference) );
The complete function signature is:
showDialog(config: IMdlSimpleDialogConfiguration): Observable<MdlDialogReference>
The parameter of the showDialog
function is an instance of the IMdlSimpleDialogConfiguration
interface. If the dialog is shown the Observable
get fired with a reference to the dialog. You can use this reference to hide the dialog or to be informed if the dialog has been closed.
The Custom Dialog
is the most powerful version of a dialog. angular2-mdl is responsible for showing and hiding the dialog, the backdrop and runs the animations. The whole content of the dialog is up to you. To create a Custom Dialog
you need to provide an angular Component
. The only requirement for such a Component
is that the Component
is defined as EntryComponent
- e.g. you put the Component
in the entryComponents
property of an NgModule
. Suppose we want to create a LoginComponent
that is defined in a reusable LoginModule
module:
@NgModule({
imports: [MdlModule, CommonModule, ReactiveFormsModule],
declarations: [LoginDialogComponent],
entryComponents: [LoginDialogComponent],
providers: [LoginService]
})
export class LoginModule {}
In this case you add your dialog Component
in the declarations
property and in the entryComponents
property. (The LoginService
is used for the business logic.)
The LoginComponent
looks as follow (a little bit shortened):
@Component({
selector: 'login-dialog',
templateUrl: 'login-dialog.component.html'
})
export class LoginDialogComponent implements OnInit {
public form: FormGroup;
public username = new FormControl('', Validators.required);
public password = new FormControl('', Validators.required);
constructor(
private dialog: MdlDialogReference,
private fb: FormBuilder,
private loginService: LoginService,
@Inject( TEST_VALUE) testValue: string) {
}
public ngOnInit() {
this.form = this.fb.group({
'username': this.username,
'password': this.password
});
}
public login() {
// do the business logic
}
@HostListener('keydown.esc')
public onEsc(): void {
this.dialog.hide();
}
}
The html looks as follow:
<form [formGroup]="form">
<h3 class="mdl-dialog__title">App Login</h3>
<div class="mdl-dialog__content">
<mdl-textfield type="text" label="Username" formControlName="username" floating-label></mdl-textfield>
<br/>
<mdl-textfield type="password" label="Password" formControlName="password" floating-label></mdl-textfield>
</div>
<div class="mdl-dialog__actions">
<button
type="button"
mdl-button (click)="login()"
[disabled]="!form.valid"
mdl-button-type="raised"
mdl-colored="primary" mdl-ripple>Login</button>
</div>
</form>
As you can see there are no interface the LoginDialogComponent
must implement or any other dependencies. It's just a plain angular Component
. If this is all done you can show your LoginDialog
:
let pDialog = this.dialogService.showCustomDialog({
component: LoginDialogComponent,
providers: [{provide: TEST_VALUE, useValue: 'Just an example'}],
isModal: true
});
pDialog.subscribe( (dialogReference: MdlDialogReference) => {
console.log('dialog visible', dialogReference);
});
As you can see, it is possible to define an array of providers
. These providers
will be injected in the CustomDialog-Component
. An instance of the MdlDialogReference
is also injected into the Component
. With this MdlDialogReference
you are able to subscribe to a close-event or call hide
from within the dialog.
If you don't want to write TypeScript code to show dialogs you can use the declarative version - e.g mdl-alert
and mdl-dialog
.
###mdl-alert
The mdl-dialog
component let's you define an alert within your html templates:
<button
mdl-button mdl-button-type="raised" mdl-colored="accent"
mdl-ripple (click)="alert.show()">Show Alert</button>
<mdl-alert
#alert="mdlAlert"
message="This is a <em class='mdl-color-text--primary'>simple</em> Alert"
okText="Got it!"
(confirmed)="alertConfirmd()"></mdl-alert>
If the user clicks the Got it!
button teh event confirmed
fires.
The mld-dialog
component let you define a custom dialog in your html. This is somewhat like the Custom Dialog
from above. But you don't need to create a Component
:
<button
mdl-button mdl-button-type="raised" mdl-colored="primary"
mdl-ripple (click)="editUserDialog.show()">Edit User Dialog</button>
<mdl-dialog #editUserDialog [mdl-modal]="false" (show)="onDialogShow($event)" (hide)="onDialogHide()">
<h3 class="mdl-dialog__title">Edit User</h3>
<div class="mdl-dialog__content">
<mdl-textfield type="text" label="Username" [(ngModel)]="editedUsername" floating-label autofocus></mdl-textfield>
</div>
<div class="mdl-dialog__actions">
<button mdl-button (click)="saveUser()" mdl-button-type="raised" mdl-colored="primary" mdl-ripple>Save</button>
<button mdl-button (click)="editUserDialog.close()" mdl-button-type="raised" mdl-ripple>Cancel</button>
</div>
</mdl-dialog>
The mdl-dialog
component can be modal or not modal (mdl-modal
attribute) and fires the events show
and hide
if the dialog get's visible or hidden.
If you are missing some feature just create a github issue.