<!DOCTYPE html>
<html>

  <head>
    <base href="./" />
    <title>angular2 bootstrap modals</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

    <script src="https://unpkg.com/core-js@2.4.1/client/shim.min.js"></script>
    <script src="https://unpkg.com/zone.js/dist/zone.js"></script>
    <script src="https://unpkg.com/zone.js/dist/long-stack-trace-zone.js"></script>
    <script src="https://unpkg.com/reflect-metadata@0.1.3/Reflect.js"></script>
    <script src="https://unpkg.com/systemjs@0.19.31/dist/system.js"></script>
    <script src="config.js"></script>
    <script>
    System.import('app')
      .catch(console.error.bind(console));
  </script>
  </head>

  <body>
    <app>
    loading...
    </app>
  </body>

</html>
#Demo For Angular2 Bootstrap Modal Service

It is a library to make usage of bootstrap modal plugin easier in Angular2. 
It makes managing dialogs painless and more clear.

##Installation
```npm
npm install ng2-bootstrap-modal
```

##Quickstart

### Step 1. import '**BootstrapModalModule**' module

app.module.ts:
```typescript
import { NgModule} from '@angular/core';
import { CommonModule } from "@angular/common";
import { BrowserModule } from '@angular/platform-browser';
import { BootstrapModalModule } from 'ng2-bootstrap-modal';
import { AppComponent } from './app.component';
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    CommonModule,
    BrowserModule,
    BootstrapModalModule
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}
```

###Step 2. Create your modal dialog component
Your modal dialog is expected to be extended from **DialogComponent**.
Therefore **DialogService** is supposed to be a constructor argument of **DialogComponent**.

confirm.component.ts:
```typescript
import { Component } from '@angular/core';
import { DialogComponent, DialogService } from "ng2-bootstrap-modal";

@Component({  selector: 'confirm',
  template: `<div class="modal-content">
                   <div class="modal-header">
                     <button type="button" class="close" (click)="close()" >&times;</button>
                     <h4 class="modal-title">{{title || 'Confirm'}}</h4>
                   </div>
                   <div class="modal-body">
                     <p>{{message || 'Are you sure?'}}</p>
                   </div>
                   <div class="modal-footer">
                     <button type="button" class="btn btn-primary" (click)="confirm()">OK</button>
                     <button type="button" class="btn btn-default" (click)="close()" >Cancel</button>
                   </div>
                 </div>`
})
export class ConfirmComponent extends DialogComponent {
  constructor(dialogService: DialogService) {
    super(dialogService);
  }
  confirm() {
    // we set dialog result as true on click on confirm button, 
    // then we can get dialog result from caller code 
    this.result = true;
    this.close();
  }
}
```

###Step 3. Register created component to module
Add component to **declarations** and **entryComponents** section because component
will be created dynamically.

app.module.ts:
```typescrit
    import { NgModule} from '@angular/core';
    import { CommonModule } from "@angular/common";
    import { BrowserModule } from '@angular/platform-browser';
    import { BootstrapModalModule } from 'ng2-bootstrap-modal';
    import { ConfirmComponent } from './confirm.component';
    import { AppComponent } from './app.component';
    @NgModule({
      declarations: [
        AppComponent,
        ConfirmComponent
      ],
      imports: [
        CommonModule,
        BrowserModule,
        BootstrapModalModule
      ],
      //Don't forget to add the component to entryComponents section
      entryComponents: [
        ConfirmComponent
      ],
      bootstrap: [AppComponent]
    })
    export class AppModule {}
```

###Step 4. Usage

app.component.ts
```typescript
    import { Component } from '@angular/core';
    import { ConfirmComponent } from './confirm.component';
    import { DialogService } from "ng2-bootstrap-modal";
    
    @Component({
      selector: 'app',
      template: `
        <div class="container">
          <button class="btn btn-default" (click)=showConfirm()>Show confirm</button>
        </div>
      `
    })
    export class AppComponent {
        constructor(private dialogService:DialogService) {}
        showConfirm() {
            let disposable = this.dialogService.addDialog(ConfirmComponent, {
                title:'Confirm title', 
                message:'Confirm message'})
                .subscribe((isConfirmed)=>{
                    //We get dialog result
                    if(isConfirmed) {
                        alert('accepted');
                    }
                    else {
                        alert('declined');
                    }
                });
            //We can close dialog calling disposable.unsubscribe();
            //If dialog was not closed manually close it by timeout
            setTimeout(()=>{
                disposable.unsubscribe();
            },10000);
        }
    }
```

##Documentation

###DialogComponent
Super class of all modal components.

####Class Overview
```typescript
abstract class DialogComponent {
    /**
    * Constructor
    * @param {DialogService} dialogService - instance of DialogService
    */
    constructor(dialogService: DialogService)
    
    /**
    * Dialog result 
    * @type {any}
    */
    protected result:any
    
    /**
    * Closes dialog
    */
    public close:Function
}
```

###DialogService 
Service to show dialogs

###Class Overview
```typescript
class DialogService {
    /**
    * Adds dialog
    * @param {Type<DialogComponent>} component - Modal dialog component
    * @param {any?} data - Initialization data for component (optional) to add to component instance and can be used in component code or template 
    * @param {number?} index - Dialog index (optional) to set order of modals
    * @return {Observable<any>} - returns Observable to get dialog result
    */
    public addDialog:(component:Type<DialogComponent>, data?:any, index?:number) => {}
}
```
System.config({
  //use typescript for compilation
  transpiler: 'typescript',
  //typescript compiler options
  typescriptOptions: {
    emitDecoratorMetadata: true
  },
  paths: {
    'npm:': 'https://unpkg.com/'
  },
  //map tells the System loader where to look for things
  map: {
    
    'app': './src',
    
    '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
    '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
    '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
    '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
    '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
    '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
    '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
    '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
    
    '@angular/core/testing': 'npm:@angular/core/bundles/core-testing.umd.js',
    '@angular/common/testing': 'npm:@angular/common/bundles/common-testing.umd.js',
    '@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js',
    '@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js',
    '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js',
    '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js',
    '@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js',
    'ng2-bootstrap-modal': 'npm:ng2-bootstrap-modal',
    
    'rxjs': 'npm:rxjs',
    'typescript': 'npm:typescript@2.0.2/lib/typescript.js'
  },
  //packages defines our app package
  packages: {
    app: {
      main: './main.ts',
      defaultExtension: 'ts'
    },
    rxjs: {
      main: 'Rx.js',
      defaultExtension: 'js'
    },
    'ng2-bootstrap-modal': {
      main: 'index.js',
      defaultExtension: 'js'
    }
  }
});
//main entry point
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {AppModule} from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule)
import { NgModule} from '@angular/core';
import { CommonModule } from "@angular/common";
import { BrowserModule } from "@angular/platform-browser";
import { BootstrapModalModule } from 'ng2-bootstrap-modal';
import { ConfirmComponent } from './confirm.component';
import { AlertComponent } from './alert.component';
import { PromptComponent } from './prompt.component';
import { ParentDialogComponent } from './parent-dialog.component';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
  declarations: [
    AppComponent,
    AlertComponent,
    ConfirmComponent,
    PromptComponent,
    ParentDialogComponent
  ],
  imports: [
    CommonModule,
    BrowserModule,
    FormsModule,
    BootstrapModalModule
  ],
  //Don't forget add component to entryComponents section
  entryComponents: [
    AlertComponent,
    ConfirmComponent,
    PromptComponent,
    ParentDialogComponent
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}
import { Component } from '@angular/core';
import { AlertComponent } from './alert.component';
import { ConfirmComponent } from './confirm.component';
import { PromptComponent } from './prompt.component';
import { ParentDialogComponent } from './parent-dialog.component';
import { DialogService } from "ng2-bootstrap-modal";
import Timer = NodeJS.Timer;

@Component({
  selector: 'app',
  template: `<div class="container" >
  <h1 class="text-center">ng2-bootstrap-modal demo</h1>
  <br>
  <br>
  <div class="row">
    <div class="col-sm-4 text-right">
      <b>Alert example: </b>
    </div>
    <div class="col-sm-4">
      <button class="btn btn-default btn-block" (click)=showAlert()>Show alert</button>
    </div>
  </div>
  <br>
  <br>
  <div class="row">
    <div class="col-sm-4 text-right">
      <b>Confirm example: </b>
    </div>
    <div class="col-sm-4">
      <button class="btn btn-default btn-block" (click)=showConfirm()>Show confirm</button>
    </div>
    <div class="col-sm-4" *ngIf="confirmResult != null">
      <span>Result: </span>
      <b [ngClass]="{'text-danger': !confirmResult, 'text-success': confirmResult}">{{confirmResult ? 'Accepted': 'Declined'}}</b>
    </div>
  </div>
  <br>
  <br>
  <div class="row">
    <div class="col-sm-4 text-right">
      <b>Prompt example: </b>
    </div>
    <div class="col-sm-4">
      <button class="btn btn-default btn-block" (click)=showPrompt()>Show prompt</button>
    </div>
    <div class="col-sm-4" *ngIf="promptMessage">
      <span>Your name: </span>
      <b>{{promptMessage}}</b>
    </div>
  </div>
  <br>
  <br>
  <div class="row">
    <div class="col-sm-4 text-right">
      <b>Close dialog by click outside example: </b>
    </div>
    <div class="col-sm-4">
      <button class="btn btn-default btn-block" (click)=showAlert2()>Show alert</button>
    </div>
  </div>
  <br>
  <br>
  <div class="row">
    <div class="col-sm-4 text-right">
      <b>Close dialog by timeout example: </b>
    </div>
    <div class="col-sm-4">
      <button class="btn btn-default btn-block" (click)=showAlert3()>Show alert</button>
    </div>
  </div>
  <br>
  <br>
  <div class="row">
    <div class="col-sm-4 text-right">
      <b>Custom backdrop color example: </b>
    </div>
    <div class="col-sm-4">
      <button class="btn btn-default btn-block" (click)=showAlert4()>Show alert</button>
    </div>
  </div>
  <br>
  <br>
  <div class="row">
    <div class="col-sm-4 text-right">
      <b>Show dialog from dialog: </b>
    </div>
    <div class="col-sm-4">
      <button class="btn btn-default btn-block" (click)=showParentDialog()>Show dialog</button>
    </div>
  </div>
</div>
  `
})
export class AppComponent {
  confirmResult:boolean = null;
  promptMessage:string = '';

  constructor(private dialogService:DialogService) {}

  showAlert() {
    this.dialogService.addDialog(AlertComponent, {title:'Alert title!', message:'Alert message!!!'});
  }

  showConfirm() {
    this.dialogService.addDialog(ConfirmComponent, {
      title:'Confirmation',
      message:'Bla bla confirm some action?'})
      .subscribe((isConfirmed)=>{
        //Get dialog result
        this.confirmResult = isConfirmed;
    });
  }

  showPrompt() {
    this.dialogService.addDialog(PromptComponent, {
      title:'Name dialog',
      question:'What is your name?: '})
      .subscribe((message)=>{
        //We get dialog result
        this.promptMessage = message;
      });
  }

  showAlert2() {
    this.dialogService.addDialog(AlertComponent, { message:'Click outside to close dialog' }, { closeByClickingOutside:true });
  }

  showAlert3() {
    this.dialogService.addDialog(AlertComponent, { message:'Wait 5 seconds and dialog will be closed automatically' }, { autoCloseTimeout:5000 });
  }

  showAlert4() {
    this.dialogService.addDialog(AlertComponent, { message:'Dialog with red backdrop' }, { backdropColor: 'rgba(255, 0, 0, 0.5)' });
  }
  showParentDialog() {
    this.dialogService.addDialog(ParentDialogComponent);
  }
}
import { Component } from '@angular/core';
import { DialogComponent, DialogService } from "ng2-bootstrap-modal";

export interface ConfirmModel {
  title:string;
  message:string;
}

@Component({
  selector: 'confirm',
  template: `<div class="modal-dialog">
                <div class="modal-content">
                   <div class="modal-header">
                     <button type="button" class="close" (click)="close()" >&times;</button>
                     <h4 class="modal-title">{{title || 'Confirm'}}</h4>
                   </div>
                   <div class="modal-body">
                     <p>{{message || 'Are you sure?'}}</p>
                   </div>
                   <div class="modal-footer">
                     <button type="button" class="btn btn-primary" (click)="confirm()">OK</button>
                     <button type="button" class="btn btn-default" (click)="cancel()">Cancel</button>
                   </div>
                 </div>
                </div>`
})
export class ConfirmComponent extends DialogComponent<ConfirmModel, boolean> implements ConfirmModel {
  title: string;
  message: string;
  constructor(dialogService: DialogService) {
    super(dialogService);
  }
  confirm() {
    // on click on confirm button we set dialog result as true,
    // ten we can get dialog result from caller code
    this.result = true;
    this.close();
  }
  cancel() {
    this.result = false;
    this.close();
  }
}
import { Component } from '@angular/core';
import { DialogComponent, DialogService } from 'ng2-bootstrap-modal';

export interface AlertModel {
  title: string;
  message: string;
}

@Component({
  selector: 'alert',
  template: `<div class="modal-dialog">
                <div class="modal-content">
                   <div class="modal-header">
                     <button type="button" class="close" (click)="close()" >&times;</button>
                     <h4 class="modal-title">{{title || 'Alert!'}}</h4>
                   </div>
                   <div class="modal-body">
                     <p>{{message || 'TADAA-AM!'}}</p>
                   </div>
                   <div class="modal-footer">
                     <button type="button" class="btn btn-primary" (click)="close()">OK</button>
                   </div>
                </div>
             </div>`
})
export class AlertComponent extends DialogComponent<AlertModel, null> implements AlertModel {
  title: string;
  message: string;
  constructor(dialogService: DialogService) {
    super(dialogService);
  }
}
import { Component } from '@angular/core';
import { DialogComponent, DialogService } from "ng2-bootstrap-modal";

export interface PromptModel {
  title:string;
  question:string;
}

@Component({
  selector: 'prompt',
  template: `<div class="modal-dialog">
                <div class="modal-content">
                   <div class="modal-header">
                     <button type="button" class="close" (click)="close()">&times;</button>
                     <h4 class="modal-title">{{title || 'Prompt'}}</h4>
                   </div>
                   <div class="modal-body">
                    <label>{{question}}</label><input type="text" class="form-control" [(ngModel)]="message" name="name" >
                   </div>
                   <div class="modal-footer">
                     <button type="button" class="btn btn-primary" (click)="apply()">OK</button>
                     <button type="button" class="btn btn-default" (click)="close()" >Cancel</button>
                   </div>
                 </div>
                </div>`
})
export class PromptComponent extends DialogComponent<PromptModel, string> implements PromptModel {
  title: string;
  question: string;
  message: string = '';
  constructor(dialogService: DialogService) {
    super(dialogService);
  }
  apply() {
    this.result = this.message;
    this.close();
  }
}
import { Component } from '@angular/core';
import { DialogComponent, DialogService } from 'ng2-bootstrap-modal';
import { ConfirmComponent } from "./confirm.component";


@Component({
  selector: 'parent-dialog',
  template: `<div class="modal-dialog" style="width: 800px;">
                <div class="modal-content" >
                   <div class="modal-header">
                     <button type="button" class="close" (click)="close()" >&times;</button>
                     <h4 class="modal-title">Parent dialog</h4>
                   </div>
                   <div class="modal-body">
                     <p>bla-bla</p>
                     <p>bla-bla</p>
                     <p>bla-bla</p>
                   </div>
                   <div class="modal-footer">
                     <button type="button" class="btn btn-primary" (click)="confirm()">Close</button>
                   </div>
                </div>
             </div>`
})
export class ParentDialogComponent extends DialogComponent<null, null>  {

  constructor(dialogService: DialogService) {
    super(dialogService);
  }

  confirm() {
    this.dialogService.addDialog(ConfirmComponent, {title: 'Confirm', message: 'Are you sure you want close dialog?'}).subscribe((isConfirmed)=>{
      if(isConfirmed) {
        this.close();
      }
    });
  }
}