How do I pass html to a template dialog component using Material with Angular 2/4
Updates
Update #1
The below code blocks are now updated to the latest version of @angular/material
.
There is also a new example on how to pass custom HTML and it now shows how to pass the data to the dialog.
Update #2
DomSanitizer#sanitize
should be used instead of DomSanitizer#bypassSecurityTrustHtml
. (Thanks @binarylobster!)
Method 1 (Pipe
)
To pass custom HTML, simply add an [innerHtml]="htmlContent"
attribute with htmlContent
as the sanitized version of HTML (in this case, a @Pipe()
) to the selector (such as span
):
my-dialog.component.html
:
<h3 matDialogTitle>My Dialog</h3>
<mat-dialog-content>
<div [innerHtml]="htmlContent | safeHtml"></div>
</mat-dialog-content>
<mat-dialog-actions>
<button mat-button matDialogClose>Close Dialog</button>
</mat-dialog-actions>
my-dialog.component.ts
:
import {Component} from '@angular/core';
// Other imports here
@Component({
selector: 'my-dialog',
templateUrl: 'my-dialog.component.html'
})
export class MyDialog {
htmlContent: string;
}
safehtml.pipe.ts
:
import { DomSanitizer } from '@angular/platform-browser';
import { Pipe, PipeTransform, SecurityContext } from '@angular/core';
@Pipe({ name: 'safeHtml'})
export class SafeHtmlPipe implements PipeTransform {
constructor(private dom: DomSanitizer) {}
transform(value) {
// NOTE: Consider using DomSanitizer#sanitize instead of DomSanitizer#bypassSecurityTrustHtml, which executes code in `<script>` tags
return this.dom.sanitize(SecurityContext.HTML, value);
}
}
app.component.ts
(Or wherever you would like to place the function):
import { MyDialog } from './my-dialog/my-dialog.component';
import { MatDialog } from '@angular/material/dialog';
export class AppComponent {
constructor(private dialog: MatDialog){}
htmlContent: string = '<p>Content goes here</p>';
openDialog() {
let dialogRef = this.dialog.open(MyDialog);
dialogRef.componentInstance.htmlContent = this.htmlContent;
}
}
Afterwards, declare the pipe in your module file:
@NgModule({
declarations: [
// Other declarations here
SafeHtmlPipe
]
})
export class AppModule {}
Method 2 (DomSanitizer
)
UPDATE: Another way to sanitize the HTML is as follows:
my-dialog.component.html
:
<h3 matDialogTitle>My Dialog</h3>
<mat-dialog-content>
<div [innerHtml]="htmlContent"></div>
</mat-dialog-content>
<mat-dialog-actions>
<button mat-button matDialogClose>Close Dialog</button>
</mat-dialog-actions>
my-dialog.component.ts
:
import { Component, OnInit } from '@angular/core';
import { SafeHtml } from '@angular/platform-browser';
@Component({
selector: 'my-dialog',
templateUrl: './my-dialog.component.html'
})
export class MyDialog {
htmlContent: string;
}
app.component.ts
:
import { MyDialog } from './my-dialog/my-dialog.component';
import { MatDialog } from '@angular/material/dialog';
import { DomSanitizer } from '@angular/platform-browser';
import { SecurityContext } from '@angular/core';
// ...
export class AppComponent {
htmlContent: string = '<p>Content goes here</p>';
constructor(private dialog: MatDialog, private dom: DomSanitizer){}
openDialog() {
let dialogRef = this.dialog.open(MyDialog);
dialogRef.componentInstance.htmlContent = this.dom.sanitize(SecurityContext.HTML, this.htmlContent);
}
}
Stackblitz demo (showcases both examples)
purplePanda
Updated on June 05, 2022Comments
-
purplePanda about 2 years
I want to pass custom html from a specific page to a template component for dialog created using Material (MdDialog). Untill now I can pass simple data to the template like so:
import { Component, OnInit, Input, TemplateRef } from '@angular/core'; import { MdDialog, MdDialogConfig, MdDialogRef } from '@angular/material'; import { DialogComponent } from './dialog.component'; @Component({ selector: 'app-commoncontent', template: ' <div class="row pull-right"> <button md-raised-button (click)="open()" >{{"addButton" | translate}} </button> </div>', styleUrls: ['./commoncontent.component.css'] }) export class CommoncontentComponent implements OnInit { constructor(public dialog : MdDialog) { } ngOnInit() { } open() { let config = new MdDialogConfig() let dialogRef:MdDialogRef<DialogComponent> = this.dialog.open(DialogComponent, config); dialogRef.componentInstance.content = "Hello Angular" } } import { Component, OnInit, Input, TemplateRef } from '@angular/core'; import { MdDialogRef } from '@angular/material' import { CommoncontentComponent } from './commoncontent.component' @Component({ selector: 'dialog-common', template: ' <md-dialog-content class="accent-color"> <form class="form-horizontal" name="dialogForm"> {{content}} </form> </md-dialog-content>', styleUrls: ['./dialog.component.css'] }) export class DialogComponent { //@Input() templateDialog: TemplateRef<any> content:string; constructor(public dialogRef: MdDialogRef<DialogComponent>) {} }
but I am unable to pass html. I know I can use ng-content for that but I couldn't manage to make it work.
-
binary lobster about 6 yearsYou should only use
bypassSecurityTrustHtml
if you really really need <script> content to be evaluated. If you're just trying to pass simple html like formatting, modify the above examples to usethis.dom.sanitize(SecurityContext.HTML, this.htmlContent)
. -
binary lobster about 6 yearsAlso,
sanitize
returns a string, so there should be no reason to declarehtmlContent
in the dialog component asSafeHtml
. -
harsh almost 6 yearsHi @Edric Thanks for above solution. However, what about passing complete html from component to dialog. example: <mat-form-field> <input matInput [(ngModel)]="name" placeholder="name" maxlength="4" required> </mat-form-field> In this case it still works however material css didn't get apply.
-
Edric almost 6 years@harsh You can try using a
DomPortalHost
or a portal from the Angular CDK. -
Edric over 5 yearsThanks for the tip @binarylobster! I didn't know that there was a
sanitize
method. Although the description for theDomSanitizer
API does show: angular.io/api/platform-browser/DomSanitizer#sanitize