Angular Service

The DialogService is an Angular service that provides API calls which are used to create Dialog instances dynamically.

This means that the service helps create Dialog instances from TypeScript based on user interactions and without the need to define the component in a template.

Getting Started

The Angular dependency injection injects the Dialog service automatically in the constructors of the component. To create new Dialogs, use the open method and subscribe to the result event stream to determine the choice of the user.

The following example demonstrates how to use the Dialog service.

import { Component } from '@angular/core';
import {
  DialogService,
  DialogRef,
  DialogCloseResult
} from '@progress/kendo-angular-dialog';

@Component({
  selector: 'my-app',
  template: `
    <div class="example-wrapper">
      <div class="example-config" *ngIf="result">
        Dialog result: {{ result }}
      </div>
      <button (click)="showConfirmation()" class="k-button">Please confirm</button>
    </div>

    <div kendoDialogContainer></div>
  `
})
export class AppComponent {
  constructor( private dialogService: DialogService ) {}

  public result;

  public showConfirmation() {
      const dialog: DialogRef = this.dialogService.open({
          title: 'Please confirm',
          content: 'Are you sure?',
          actions: [
              { text: 'No' },
              { text: 'Yes', primary: true }
          ],
          width: 450,
          height: 200,
          minWidth: 250
      });

      dialog.result.subscribe((result) => {
          if (result instanceof DialogCloseResult) {
              console.log('close');
          } else {
              console.log('action', result);
          }

          this.result = JSON.stringify(result);
      });
  }
}

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppComponent } from './app.component';
import { DialogModule } from '@progress/kendo-angular-dialog';

@NgModule({
    bootstrap:    [ AppComponent ],
    declarations: [ AppComponent ],
    imports: [
      DialogModule,
      BrowserModule,
      BrowserAnimationsModule
    ]
})
export class AppModule {}
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

Rendering the Content

You can render the content of the Dialog by:

Using Templates

The Dialog allows the use of template expressions in its content area. To enable this behavior, pass a TemplateRef instance.

import { Component, TemplateRef } from '@angular/core';
import { DialogService, DialogCloseResult } from '@progress/kendo-angular-dialog';

@Component({
  selector: 'my-app',
  template: `
    <div class="example-wrapper">
      <ng-template #itemListRef>
          <p>This action will affect {{ items.length }} items:</p>

          <ul>
              <li *ngFor="let item of items">{{ item }}</li>
          </ul>
      </ng-template>

      <button (click)="showConfirmation(itemListRef)" class="k-button">Please confirm</button>
    </div>

    <div kendoDialogContainer></div>
  `
})
export class AppComponent {
  public items = [ 'Item #2', 'Item #3', 'Item #5', 'Item #8' ];

  constructor( private dialogService: DialogService ) {}

  public showConfirmation(template: TemplateRef<any>) {
      this.dialogService.open({
          title: 'Please confirm',
          content: template,
          actions: [
              { text: 'No' },
              { text: 'Yes', primary: true }
          ]
      });
  }
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppComponent } from './app.component';
import { DialogModule } from '@progress/kendo-angular-dialog';

@NgModule({
    bootstrap:    [ AppComponent ],
    declarations: [ AppComponent ],
    imports: [
      DialogModule,
      BrowserModule,
      BrowserAnimationsModule
    ]
})
export class AppModule {}
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

Using Components

Using Components in Content Area Only

The Dialog allows the rendering of component types in its content area. To enable this behavior, pass the class of the child component in the content option.

Verify that all dynamically created components are registered as entryComponents in the NgModule of the application. If the components are not registered, Angular throws a runtime error that a component factory for the component does not exist.

import { Component } from '@angular/core';
import { UserInfoComponent } from './user-info.component';
import { DialogService, DialogCloseResult } from '@progress/kendo-angular-dialog';

@Component({
  selector: 'my-app',
  template: `
    <div class="example-wrapper">
      <button (click)="showConfirmation()" class="k-button k-button-icontext k-primary">
        <span class="k-icon k-i-delete"></span> Delete user
      </button>
    </div>

    <div kendoDialogContainer></div>
  `
})
export class AppComponent {
  constructor( private dialogService: DialogService ) {}

  public result;

  public showConfirmation() {
      const dialogRef = this.dialogService.open({
          title: 'Please confirm',

          // Show component
          content: UserInfoComponent,

          actions: [
              { text: 'Cancel' },
              { text: 'Delete', primary: true }
          ]
      });

      const userInfo = dialogRef.content.instance;
      userInfo.name = 'admin';
      userInfo.age = 42;
  }
}
import { Component, Input } from '@angular/core';

@Component({
  selector: 'user-info',
  template: `
    <div class="container-fluid">
      <dl class="row">
          <dt class="col-sm-6">Username:</dt>
          <dd class="col-sm-6">{{ name }}</dd>

          <dt class="col-sm-6">Age:</dt>
          <dd class="col-sm-6">{{ age }}</dd>
      </dl>
    </div>
  `
})
export class UserInfoComponent {
    @Input() public name: string;

    @Input() public age: number;
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppComponent } from './app.component';
import { UserInfoComponent } from './user-info.component';

import { DialogModule } from '@progress/kendo-angular-dialog';

@NgModule({
    bootstrap:       [ AppComponent ],
    declarations:    [ UserInfoComponent, AppComponent ],
    // Register the component that will be created dynamically
    entryComponents: [ UserInfoComponent ],
    imports: [
      DialogModule,
      BrowserModule,
      BrowserAnimationsModule
    ]
})
export class AppModule {}
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

To access and close the Dialog from the child component, use a constructor parameter of the DialogRef type. The parameter will receive the Dialog instance.

@Component({
    template: `
        <button (click)="dialog.close()">Close</button>
    `
})
class ChildComponent {
    constructor(
        public dialog : DialogRef
    ) {}
}

Passing Title, Content, and Actions as a Single Component

To provide all building blocks of the Dialog (title bar, content, and actions) as a single component, pass the class of this component in the content option. You have to include the configuration markup for the title bar and actions in the component template.

The Dialog content component needs to extend the DialogContentBase class that provides the necessary logic for gluing together the respective title bar and button actions and events.

Provide the title and actions configuration either in the DialogSettings configuration object or in the component's template markup, but not both to avoid rendering of multiple title/action components.

@Component({
selector: 'my-dialog-content-component',
template: `
<!–– Title bar markup -->
<kendo-dialog-titlebar>
    <div style="font-size: 18px; line-height: 1.3em;">
        <span class="k-icon k-i-print"></span> from content {{formGroup.get('name').value}}
    </div>
</kendo-dialog-titlebar>
<!–– Content section -->
<div class="container">
    <h1>Hero Form</h1>
    <form [formGroup]="formGroup">
        <div class="form-group">
            <label for="name">Name</label>
            <input type="text" class="form-control" id="name" [formControl]="formGroup.get('name')" required>
        </div>
        <div class="form-group">
            <label for="age">Age</label>
            <input type="number" class="form-control" id="age" [formControl]="formGroup.get('age')">
        </div>
    </form>
</div>
<!–– Actions markup -->
<kendo-dialog-actions>
    <button kendoButton (click)="onCancelAction()">Cancel</button>
    <button kendoButton (click)="onConfirmAction()" [primary]="true" [disabled]="!formGroup.valid">Submit</button>
</kendo-dialog-actions>
`
})

You can provide the buttons for the configuration of the actions in either of the following ways:

  • As standalone Kendo UI Buttons.

    <kendo-dialog-actions>
       <button kendoButton (click)="onCancelAction()">Cancel</button>
       <button kendoButton (click)="onConfirmAction()" [primary]="true" [disabled]="!formGroup.valid">Submit</button>
    </kendo-dialog-actions>
  • As an array of objects that is bound to the actions property.

    <kendo-dialog-actions [actions]="[{text: 'Cancel'}, {text: 'Confirm', primary: true}]">
    </kendo-dialog-actions>
import { Component } from '@angular/core';
import { UserInfoComponent } from './user-info.component';
import { DialogService } from '@progress/kendo-angular-dialog';

@Component({
  selector: 'my-app',
  template: `
    <div class="example-wrapper">
      <button (click)="openDialogForm()" class="k-button k-button-icontext k-primary">
        <span class="k-icon k-i-form-element"></span> User form
      </button>
    </div>

    <div kendoDialogContainer></div>
  `
})
export class AppComponent {
    constructor( private dialogService: DialogService ) {}

    public openDialogForm() {
        const dialogRef = this.dialogService.open({
            content: UserInfoComponent,
        });

        const userInfo = dialogRef.content.instance;
            userInfo.name = 'admin';
            userInfo.age = 42;

        dialogRef.result.subscribe(r => {
            console.log(r);
            if (r.primary) {
                console.log(`Form: ${JSON.stringify(userInfo.formGroup.value)}`);
            }
        });
    }
}
import { Component, Input } from '@angular/core';
import { DialogRef, DialogContentBase } from '@progress/kendo-angular-dialog';
import { FormControl, FormGroup } from '@angular/forms';

@Component({
  selector: 'user-info',
  template: `
  <kendo-dialog-titlebar>
          <div style="font-size: 18px; line-height: 1.3em;">
            <span class="k-icon k-i-form-element"></span> User Form
          </div>
        </kendo-dialog-titlebar>
        <div class="container">
    <form [formGroup]="formGroup">
      <div class="form-group">
        <label for="name">Name</label>
        <input type="text" class="form-control" id="name" [formControl]="formGroup.get('name')" required>
      </div>
      <div class="form-group">
        <label for="age">Age</label>
        <input type="number" class="form-control" id="age" [formControl]="formGroup.get('age')">
      </div>
    </form>
</div>
    <kendo-dialog-actions>
        <button kendoButton (click)="onCancelAction()">Cancel</button>
        <button kendoButton (click)="onConfirmAction()" [primary]="true" [disabled]="!formGroup.valid">Submit</button>
    </kendo-dialog-actions>
  `
})
export class UserInfoComponent extends DialogContentBase {
    @Input() public age: number;
    @Input() public name: string;

    public formGroup: FormGroup = new FormGroup({
        age: new FormControl(this.age),
        name: new FormControl(this.name)
    });

    constructor(private dialog: DialogRef) {
        super(dialog);
    }

    public onCancelAction(): void {
        this.dialog.close({text: 'Cancel'});
    }

    public onConfirmAction(): void {
        this.dialog.close({text: 'Submit', primary: true});
    }
}
import { ReactiveFormsModule } from '@angular/forms';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppComponent } from './app.component';
import { UserInfoComponent } from './user-info.component';
import { ButtonsModule } from '@progress/kendo-angular-buttons';

import { DialogModule } from '@progress/kendo-angular-dialog';

@NgModule({
    bootstrap:       [ AppComponent ],
    declarations:    [ UserInfoComponent, AppComponent ],
    // Register the component that will be created dynamically
    entryComponents: [ UserInfoComponent ],
    imports: [
      DialogModule,
      BrowserModule,
      BrowserAnimationsModule,
      ButtonsModule,
      ReactiveFormsModule
    ]
})
export class AppModule {}
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

Specifying Custom Actions

The Dialog allows you to show custom actions to the user. To enable this behavior, pass a TemplateRef instance for the actions.

import { Component, TemplateRef, ViewEncapsulation } from '@angular/core';
import { DialogService, DialogCloseResult } from '@progress/kendo-angular-dialog';

@Component({
  selector: 'my-app',
  template: `
    <div class="example-wrapper">

      <ng-template #dialogActions>
          <button kendoButton (click)="close()" [disabled]="isLoading">No</button>
          <button kendoButton (click)="custom()" [disabled]="isLoading" [icon]="loadingIcon">Yes</button>
      </ng-template>

      <button (click)="showConfirmation(dialogActions)" class="k-button">Please confirm</button>

    </div>

    <div kendoDialogContainer></div>
  `,
  encapsulation: ViewEncapsulation.None,
  styles: [ '.k-dialog-close { display: none; }' ]
})
export class AppComponent {
  public loadingIcon = '';

  constructor( private dialogService: DialogService ) {}

  private dialog;

  public showConfirmation(actionTemplate: TemplateRef) {
      this.dialog = this.dialogService.open({
          title: 'Please confirm',
          content: 'Are you sure? This action will take about 3 seconds.',
          actions: actionTemplate
      });
  }

  public close() {
    if (this.dialog) {
      this.dialog.close();
    }
  }

  public get isLoading(): boolean {
    return this.loadingIcon !== '';
  }

  public custom() {
    this.loadingIcon = 'loading';

    // Mock async action
    window.setTimeout(() => {
      this.loadingIcon = '';
      this.close();
    }, 3000);
  }
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppComponent } from './app.component';
import { DialogModule } from '@progress/kendo-angular-dialog';
import { ButtonsModule } from '@progress/kendo-angular-buttons';

@NgModule({
    bootstrap:    [ AppComponent ],
    declarations: [ AppComponent ],
    imports: [
      DialogModule,
      // Import the ButtonsModule for the kendoButton directive
      ButtonsModule,
      BrowserModule,
      BrowserAnimationsModule
    ]
})
export class AppModule {}
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

Specifying the Dialog Container

You can specify the container for the newly created Dialogs by using either of the following approaches:

  • Include an element with the kendoDialogContainer directive in your application.

    <div kendoDialogContainer></div>
  • When you call the DialogService.open method, pass a ViewContainerRef instance to the appendTo property.

    import { Component, ViewChild, ViewContainerRef } from '@angular/core';
    
    import { DialogService } from '@progress/kendo-angular-dialog';
    
    @Component({
     selector: 'my-app',
     template: `
       <button kendoButton (click)="open()">Open dialog</button>
    
       <ng-container #container></ng-container>
     `
    })
    export class AppComponent {
     constructor(private dialogService: DialogService) { }
    
     @ViewChild("container", { read: ViewContainerRef })
     public containerRef: ViewContainerRef;
    
     public open() {
       this.dialogService.open({
         appendTo: this.containerRef,
    
         title: "Please confirm",
         content: "Are you sure?",
         actions: [ { text: "Yes" }, { text: "No" } ]
       });
     }
    }

In this article