Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I pass html to a template dialog component using Material with Angular 2/4

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.

like image 811
purplePanda Avatar asked Jul 10 '17 20:07

purplePanda


People also ask

How do you pass data dialog to component in angular materials?

We can pass data to the dialog component by using the data property of the dialog configuration object. As we can see, the whole data object initially passed as part of the dialog configuration object can now be directly injected into the constructor.

How do I import MatDialogModule?

In order to use the dialog component, we need to import the MatDialogModule module into the app module like this. import { MatDialogModule } from '@angular/material/dialog'; After importing the dialog module, the next step is to include it inside the imports array as given below.

How do I use MatDialog?

Approach: First we need to import 'MatDialog' from '@angular/material/dialog' and we need to create an instance for it in the constructor. Using this instance we can open the dialog box component. Now create a separate component for the dialog and write code as per the requirements.

What is MatDialogRef?

The MatDialogRef provides a handle on the opened dialog. It can be used to close the dialog and to receive notifications when the dialog has been closed. Any notification Observables will complete when the dialog closes.


1 Answers

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)

like image 71
Edric Avatar answered Oct 03 '22 19:10

Edric