<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://unpkg.com/ng2-toasty@4.0.0/style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<title>NG2-Toasty Demo</title>
<base href="">
</head>
<body style="padding-top: 5rem;">
<div class="container">
<my-app>
<span class="sr-only">Loading...</span>
</my-app>
</div>
<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(function (err) {
console.error(err);
});
</script>
</body>
</html>
// Copyright (C) 2016-2017 Sergey Akopkokhyants
// This project is licensed under the terms of the MIT license.
// https://github.com/akserg
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',
'rxjs': 'npm:rxjs',
'typescript': 'npm:typescript@2.0.2/lib/typescript.js',
'ng2-toasty': 'npm:ng2-toasty/index.js'
},
//packages defines our app package
packages: {
app: {
main: './main.ts',
defaultExtension: 'ts'
},
rxjs: {
defaultExtension: 'js'
}
}
});
// Copyright (C) 2016-2017 Sergey Akopkokhyants
// This project is licensed under the terms of the MIT license.
// https://github.com/akserg
import { Component, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { ToastComponent } from 'src/toast';
import { ToastyModule } from 'ng2-toasty';
import { ToastCommunicationService } from 'src/toast.service';
@Component({
selector: 'my-app',
template: `
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<a class="navbar-brand" href="https://github.com/akserg/ng2-toasty">NG2-Toasty</a>
</div>
</div>
</nav>
<demo-toast></demo-toast>
<ng2-toasty [position]="toastyComponentPosition"></ng2-toasty>
`,
styles: []
})
export class App {
// Position of Ng2ToastyComponent
private toastyComponentPosition: string;
constructor(private toastCommunicationService: ToastCommunicationService) {
// We listen the position's changes
this.toastCommunicationService.position$.subscribe(pos => this.toastyComponentPosition = pos);
}
}
@NgModule({
imports: [ BrowserModule, ToastyModule.forRoot(), FormsModule ],
declarations: [ App, ToastComponent ],
providers: [ ToastCommunicationService ]
bootstrap: [ App ]
})
export class AppModule {
}
// Copyright (C) 2016-2017 Sergey Akopkokhyants
// This project is licensed under the terms of the MIT license.
// https://github.com/akserg
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {AppModule} from './app';
platformBrowserDynamic().bootstrapModule(AppModule)
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
/**
* Service helps communicate between the ToastComponent and AppComponent.
*/
@Injectable()
export class ToastCommunicationService {
// Observable string sources
private positionSource = new Subject<string>();
// Observable string streams
position$ = this.positionSource.asObservable();
setPosition(position) {
this.positionSource.next(position);
}
}
// Copyright (C) 2016-2017 Sergey Akopkokhyants
// This project is licensed under the terms of the MIT license.
// https://github.com/akserg
import { Component, AfterViewInit } from '@angular/core';
import { Subject, Observable, Subscription } from 'rxjs/Rx';
import { ToastyService, ToastyConfig, ToastOptions, ToastData } from 'ng2-toasty';
import { ToastCommunicationService } from './toast.service';
@Component({
selector: 'demo-toast',
template: `
<div class="container">
<br />
<form>
<div class="row">
<div class="col-md-6">
<div class="input-group">
<label for="title">Title</label>
<input class="form-control" type="text" id="title" [(ngModel)]="options.title" name="title">
</div>
<div class="input-group">
<label for="msg">Message</label>
<input class="form-control" type="text" id="msg" [(ngModel)]="options.msg" name="msg">
</div>
<div class="input-group">
<label for="theme">Theme</label>
<select class="form-control" [(ngModel)]="options.theme" name="theme">
<option *ngFor="let theme of themes" [value]="theme.code">{{theme.name}}</option>
</select>
</div>
<div class="input-group">
<label for="theme">Type</label>
<select class="form-control" [(ngModel)]="options.type" name="type">
<option *ngFor="let type of types" [value]="type.code">{{type.name}}</option>
</select>
</div>
<div class="input-group">
<label for="theme">Position</label>
<select class="form-control" [ngModel]="position" (ngModelChange)="changePosition($event)" name="position">
<option *ngFor="let pos of positions" [value]="pos.code">{{pos.name}}</option>
</select>
</div>
<div class="input-group">
<label for="timeout">Timeout</label>
<input type="text" class="form-control" id="timeout" [(ngModel)]="options.timeout" placeholder="5000" name="timeout"/>
</div>
<div class="input-group">
<label for="showclose">Show Close Icon</label>
<input type="checkbox" class="form-control" id="showclose" [(ngModel)]="options.showClose" name="showClose"/>
</div>
</div>
<div class="col-md-6">
<pre>
<code>toastyService<span ng-if="options.type != 'default'">.{{ options.type }}</span>({{ '{' }}
title: "{{ options.title }}",
msg: "{{ options.msg }}",
showClose: {{ options.showClose }},
timeout: {{ options.timeout || false }},
theme: "{{ options.theme }}"
{{ '}' }});
</code>
<code>toastyConfig({{ '{' }}
position: "{{ position }}"
{{ '}' }});
</code>
</pre>
</div>
</div>
<div class="row">
<button class="btn btn-default" (click)="clearToasties()">Clear All</button>
<button class="btn button-primary" (click)="newToast()">Add</button>
<button class="btn button-success" (click)="newCountdownToast()">Countdown</button>
</div>
<div class="clearfix"></div>
</form>
</div>`
})
export class ToastComponent implements AfterViewInit {
themes = [
{ name: 'Default Theme', code: 'default' },
{ name: 'Material Design', code: 'material' },
{ name: 'Bootstrap 3',code: 'bootstrap' }
];
types = [
{ name: 'Default', code: 'default' },
{ name: 'Info', code: 'info' },
{ name: 'Success', code: 'success' },
{ name: 'Wait', code: 'wait' },
{ name: 'Error', code: 'error' },
{ name: 'Warning', code: 'warning'}
];
positions = [
{ name: 'Top Left', code: 'top-left' },
{ name: 'Top Center', code: 'top-center' },
{ name: 'Top Right', code: 'top-right' },
{ name: 'Bottom Left', code: 'bottom-left' },
{ name: 'Bottom Center', code: 'bottom-center' },
{ name: 'Bottom Right', code: 'bottom-right' },
{ name: 'Center Center', code: 'center-center'}
];
position: string = this.positions[5].code;
options = {
title: 'Toast It!',
msg: 'Mmmm, tasties...',
showClose: true,
timeout: 5000,
theme: this.themes[0].code,
type: this.types[0].code
};
getTitle(num: number): string {
return 'Countdown: ' + num;
}
getMessage(num: number): string {
return 'Seconds left: ' + num;
}
constructor(private toastyService: ToastyService, private toastCommunicationService: ToastCommunicationService) {
}
ngAfterViewInit() {
// this._toastyConfig.theme = 'bootstrap';
let toastOptions: ToastOptions = {
title: 'title',
msg: 'my message',
showClose: true,
timeout: 15000,
theme: "bootstrap",
onAdd: (toast: ToastData) => {
console.log('Toast ' + toast.id + ' has been added!');
},
onRemove: function (toast: ToastData) {
console.log('Toast ' + toast.id + ' has been removed!');
}
};
this.toastyService.success(toastOptions);
}
newToast() {
let toastOptions: ToastOptions = {
title: this.options.title,
msg: this.options.msg,
showClose: this.options.showClose,
timeout: this.options.timeout,
theme: this.options.theme,
onAdd: (toast: ToastData) => {
console.log('Toast ' + toast.id + ' has been added!');
},
onRemove: function(toast: ToastData) {
console.log('Toast ' + toast.id + ' has been removed!');
}
};
switch (this.options.type) {
case 'default': this.toastyService.default(toastOptions); break;
case 'info': this.toastyService.info(toastOptions); break;
case 'success': this.toastyService.success(toastOptions); break;
case 'wait': this.toastyService.wait(toastOptions); break;
case 'error': this.toastyService.error(toastOptions); break;
case 'warning': this.toastyService.warning(toastOptions); break;
}
}
newCountdownToast() {
let interval = 1000;
let seconds = this.options.timeout / 1000;
let subscription: Subscription;
let toastOptions: ToastOptions = {
title: this.getTitle(seconds || 0),
msg: this.getMessage(seconds || 0),
showClose: this.options.showClose,
timeout: this.options.timeout,
theme: this.options.theme,
onAdd: (toast: ToastData) => {
console.log('Toast ' + toast.id + ' has been added!');
// Run the timer with 1 second iterval
let observable = Observable.interval(interval).take(seconds);
// Start listen seconds bit
subscription = observable.subscribe((count: number) => {
// Update title
toast.title = this.getTitle(seconds - count - 1 || 0);
// Update message
toast.msg = this.getMessage(seconds - count - 1 || 0);
});
},
onRemove: function(toast: ToastData) {
console.log('Toast ' + toast.id + ' has been removed!');
// Stop listenning
subscription.unsubscribe();
}
};
switch (this.options.type) {
case 'default': this.toastyService.default(toastOptions); break;
case 'info': this.toastyService.info(toastOptions); break;
case 'success': this.toastyService.success(toastOptions); break;
case 'wait': this.toastyService.wait(toastOptions); break;
case 'error': this.toastyService.error(toastOptions); break;
case 'warning': this.toastyService.warning(toastOptions); break;
}
}
clearToasties() {
this.toastyService.clearAll();
}
changePosition($event) {
this.position = $event;
// Update position of the Toasty Component
this.toastCommunicationService.setPosition(this.position);
}
}