diff --git a/src/toast.component.ts b/src/toast.component.ts index c60e26f..1a6a523 100644 --- a/src/toast.component.ts +++ b/src/toast.component.ts @@ -2,36 +2,48 @@ // This project is licensed under the terms of the MIT license. // https://github.com/akserg/ng2-toasty -import { Component, Input, Output, EventEmitter } from '@angular/core'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; import { ToastData } from './toasty.service'; +import { isFunction } from 'util'; /** * A Toast component shows message with title and close button. */ @Component({ - selector: 'ng2-toast', - template: ` -
+ selector: 'ng2-toast', + template: ` +
-
+
` }) export class ToastComponent { - @Input() toast: ToastData; - @Output('closeToast') closeToastEvent = new EventEmitter(); + @Input() toast: ToastData; + @Output('closeToast') closeToastEvent = new EventEmitter(); - /** - * Event handler invokes when user clicks on close button. - * This method emit new event into ToastyContainer to close it. - */ - close($event: any) { - $event.preventDefault(); - this.closeToastEvent.next(this.toast); - } + /** + * Event handler invokes when user clicks on close button. + * This method emit new event into ToastyContainer to close it. + */ + close($event: any) { + $event.preventDefault(); + this.closeToastEvent.next(this.toast); + } + + /** + * Event handler invokes when user clicks on Toast button. + * This method emit new event into ToastyContainer to close it. + */ + click($event: any) { + $event.preventDefault(); + if (this.toast.onClick && isFunction(this.toast.onClick)) { + this.toast.onClick.call(this, this.toast); + } + } } diff --git a/src/toasty.service.ts b/src/toasty.service.ts index 1930f3a..cc7dbe0 100644 --- a/src/toasty.service.ts +++ b/src/toasty.service.ts @@ -3,23 +3,24 @@ // https://github.com/akserg/ng2-toasty import { Injectable } from '@angular/core'; -import { isString, isNumber, isFunction } from './toasty.utils'; +import { isFunction, isNumber, isString } from './toasty.utils'; -import {Subject} from 'rxjs/Subject'; -import {Observable} from 'rxjs/Observable'; +import { Subject } from 'rxjs/Subject'; +import { Observable } from 'rxjs/Observable'; /** * Options to configure specific Toast */ @Injectable() export class ToastOptions { - title: string; - msg?: string; - showClose?: boolean; - theme?: string; - timeout?: number; - onAdd?: Function; - onRemove?: Function; + title: string; + msg?: string; + showClose?: boolean; + theme?: string; + timeout?: number; + onAdd?: Function; + onRemove?: Function; + onClick?: Function; } /** @@ -27,16 +28,16 @@ export class ToastOptions { */ @Injectable() export class ToastData { - id: number; - title: string; - msg: string; - showClose: boolean; - type: string; - theme: string; - timeout: number; - onAdd: Function; - onRemove: Function; - onClick: Function; + id: number; + title: string; + msg: string; + showClose: boolean; + type: string; + theme: string; + timeout: number; + onAdd: Function; + onRemove: Function; + onClick: Function; } /** @@ -45,33 +46,34 @@ export class ToastData { @Injectable() export class ToastyConfig { - // Maximum number of toasties to show at once - limit: number = 5; + // Maximum number of toasties to show at once + limit: number = 5; - // Whether to show the 'X' icon to close the toast - showClose: boolean = true; + // Whether to show the 'X' icon to close the toast + showClose: boolean = true; - // The window position where the toast pops up - position: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'top-center' | 'bottom-center' | 'center-center' = 'bottom-right'; + // The window position where the toast pops up + position: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'top-center' | 'bottom-center' | 'center-center' = 'bottom-right'; - // How long (in miliseconds) the toasty shows before it's removed. Set to null/0 to turn off. - timeout: number = 5000; + // How long (in miliseconds) the toasty shows before it's removed. Set to null/0 to turn off. + timeout: number = 5000; - // What theme to use - theme: 'default' | 'material' | 'bootstrap' = 'default'; + // What theme to use + theme: 'default' | 'material' | 'bootstrap' = 'default'; } export enum ToastyEventType { - ADD, - CLEAR, - CLEAR_ALL + ADD, + CLEAR, + CLEAR_ALL } export class ToastyEvent { - constructor(public type:ToastyEventType, public value?:any) {} + constructor(public type: ToastyEventType, public value?: any) { + } } -export function toastyServiceFactory(config: ToastyConfig): ToastyService { +export function toastyServiceFactory(config: ToastyConfig): ToastyService { return new ToastyService(config); } @@ -80,161 +82,163 @@ export function toastyServiceFactory(config: ToastyConfig): ToastyService { */ @Injectable() export class ToastyService { - // Allowed THEMES - static THEMES: Array = ['default', 'material', 'bootstrap']; - // Init the counter - uniqueCounter: number = 0; - // ToastData event emitter - // private toastsEmitter: EventEmitter = new EventEmitter(); - // Clear event emitter - // private clearEmitter: EventEmitter = new EventEmitter(); - - private eventSource: Subject = new Subject(); - public events: Observable = this.eventSource.asObservable(); - - constructor(private config: ToastyConfig) {} - - /** - * Get list of toats - */ - // getToasts(): Observable { - // return this.toastsEmitter.asObservable(); - // } - - // getClear(): Observable { - // return this.clearEmitter.asObservable(); - // } - - /** - * Create Toast of a default type - */ - default(options: ToastOptions|string|number): void { - this.add(options, 'default'); - } - - /** - * Create Toast of info type - * @param {object} options Individual toasty config overrides - */ - info(options: ToastOptions|string|number): void { - this.add(options, 'info'); - } - - /** - * Create Toast of success type - * @param {object} options Individual toasty config overrides - */ - success(options: ToastOptions|string|number): void { - this.add(options, 'success'); - } - - /** - * Create Toast of wait type - * @param {object} options Individual toasty config overrides - */ - wait(options: ToastOptions|string|number): void { - this.add(options, 'wait'); - } - - /** - * Create Toast of error type - * @param {object} options Individual toasty config overrides - */ - error(options: ToastOptions|string|number): void { - this.add(options, 'error'); - } - - /** - * Create Toast of warning type - * @param {object} options Individual toasty config overrides - */ - warning(options: ToastOptions|string|number): void { - this.add(options, 'warning'); - } - - - // Add a new toast item - private add(options: ToastOptions|string|number, type: string) { - let toastyOptions: ToastOptions; - - if (isString(options) && options !== '' || isNumber(options)) { - toastyOptions = { - title: options.toString() - }; - } else { - toastyOptions = options; + // Allowed THEMES + static THEMES: Array = ['default', 'material', 'bootstrap']; + // Init the counter + uniqueCounter: number = 0; + // ToastData event emitter + // private toastsEmitter: EventEmitter = new EventEmitter(); + // Clear event emitter + // private clearEmitter: EventEmitter = new EventEmitter(); + + private eventSource: Subject = new Subject(); + public events: Observable = this.eventSource.asObservable(); + + constructor(private config: ToastyConfig) { + } + + /** + * Get list of toats + */ + // getToasts(): Observable { + // return this.toastsEmitter.asObservable(); + // } + + // getClear(): Observable { + // return this.clearEmitter.asObservable(); + // } + + /** + * Create Toast of a default type + */ + default(options: ToastOptions | string | number): void { + this.add(options, 'default'); + } + + /** + * Create Toast of info type + * @param {object} options Individual toasty config overrides + */ + info(options: ToastOptions | string | number): void { + this.add(options, 'info'); + } + + /** + * Create Toast of success type + * @param {object} options Individual toasty config overrides + */ + success(options: ToastOptions | string | number): void { + this.add(options, 'success'); } - if (!toastyOptions || !toastyOptions.title && !toastyOptions.msg) { - throw new Error('ng2-toasty: No toast title or message specified!'); + /** + * Create Toast of wait type + * @param {object} options Individual toasty config overrides + */ + wait(options: ToastOptions | string | number): void { + this.add(options, 'wait'); } - type = type || 'default'; + /** + * Create Toast of error type + * @param {object} options Individual toasty config overrides + */ + error(options: ToastOptions | string | number): void { + this.add(options, 'error'); + } - // Set a unique counter for an id - this.uniqueCounter++; + /** + * Create Toast of warning type + * @param {object} options Individual toasty config overrides + */ + warning(options: ToastOptions | string | number): void { + this.add(options, 'warning'); + } - // Set the local vs global config items - let showClose = this._checkConfigItem(this.config, toastyOptions, 'showClose'); + // Clear all toasts + clearAll() { + // this.clearEmitter.next(null); + this.emitEvent(new ToastyEvent(ToastyEventType.CLEAR_ALL)); + } - // If we have a theme set, make sure it's a valid one - let theme: string; - if (toastyOptions.theme) { - theme = ToastyService.THEMES.indexOf(toastyOptions.theme) > -1 ? toastyOptions.theme : this.config.theme; - } else { - theme = this.config.theme; + // Clear the specific one + clear(id: number) { + // this.clearEmitter.next(id); + this.emitEvent(new ToastyEvent(ToastyEventType.CLEAR, id)); } - let toast: ToastData = { - id : this.uniqueCounter, - title : toastyOptions.title, - msg : toastyOptions.msg, - showClose: showClose, - type : 'toasty-type-' + type, - theme : 'toasty-theme-' + theme, - onAdd : toastyOptions.onAdd && isFunction(toastyOptions.onAdd) ? toastyOptions.onAdd : null, - onRemove : toastyOptions.onRemove && isFunction(toastyOptions.onRemove) ? toastyOptions.onRemove : null - }; - - // If there's a timeout individually or globally, set the toast to timeout - // Allows a caller to pass null/0 and override the default. Can also set the default to null/0 to turn off. - toast.timeout = toastyOptions.hasOwnProperty('timeout') ? toastyOptions.timeout : this.config.timeout; - - // Push up a new toast item - // this.toastsSubscriber.next(toast); - // this.toastsEmitter.next(toast); - this.emitEvent(new ToastyEvent(ToastyEventType.ADD, toast)); - // If we have a onAdd function, call it here - if (toastyOptions.onAdd && isFunction(toastyOptions.onAdd)) { - toastyOptions.onAdd.call(this, toast); + // Add a new toast item + private add(options: ToastOptions | string | number, type: string) { + let toastyOptions: ToastOptions; + + if (isString(options) && options !== '' || isNumber(options)) { + toastyOptions = { + title: options.toString() + }; + } else { + toastyOptions = options; + } + + if (!toastyOptions || !toastyOptions.title && !toastyOptions.msg) { + throw new Error('ng2-toasty: No toast title or message specified!'); + } + + type = type || 'default'; + + // Set a unique counter for an id + this.uniqueCounter++; + + // Set the local vs global config items + let showClose = this._checkConfigItem(this.config, toastyOptions, 'showClose'); + + // If we have a theme set, make sure it's a valid one + let theme: string; + if (toastyOptions.theme) { + theme = ToastyService.THEMES.indexOf(toastyOptions.theme) > -1 ? toastyOptions.theme : this.config.theme; + } else { + theme = this.config.theme; + } + + let toast: ToastData = { + id: this.uniqueCounter, + title: toastyOptions.title, + msg: toastyOptions.msg, + showClose: showClose, + type: 'toasty-type-' + type, + theme: 'toasty-theme-' + theme, + onAdd: toastyOptions.onAdd && isFunction(toastyOptions.onAdd) ? toastyOptions.onAdd : null, + onRemove: toastyOptions.onRemove && isFunction(toastyOptions.onRemove) ? toastyOptions.onRemove : null, + onClick: toastyOptions.onClick && isFunction(toastyOptions.onClick) ? toastyOptions.onClick : null + }; + + // If there's a timeout individually or globally, set the toast to timeout + // Allows a caller to pass null/0 and override the default. Can also set the default to null/0 to turn off. + toast.timeout = toastyOptions.hasOwnProperty('timeout') ? toastyOptions.timeout : this.config.timeout; + + // Push up a new toast item + // this.toastsSubscriber.next(toast); + // this.toastsEmitter.next(toast); + this.emitEvent(new ToastyEvent(ToastyEventType.ADD, toast)); + // If we have a onAdd function, call it here + if (toastyOptions.onAdd && isFunction(toastyOptions.onAdd)) { + toastyOptions.onAdd.call(this, toast); + } } - } - - // Clear all toasts - clearAll() { - // this.clearEmitter.next(null); - this.emitEvent(new ToastyEvent(ToastyEventType.CLEAR_ALL)); - } - - // Clear the specific one - clear(id: number) { - // this.clearEmitter.next(id); - this.emitEvent(new ToastyEvent(ToastyEventType.CLEAR, id)); - } - - // Checks whether the local option is set, if not, - // checks the global config - private _checkConfigItem(config: any, options: any, property: string) { - if (options[property] === false) { - return false; - } else if (!options[property]) { - return config[property]; - } else { - return true; + + // Checks whether the local option is set, if not, + + // checks the global config + private _checkConfigItem(config: any, options: any, property: string) { + if (options[property] === false) { + return false; + } else if (!options[property]) { + return config[property]; + } else { + return true; + } } - } - private emitEvent(event: ToastyEvent) { + private emitEvent(event: ToastyEvent) { if (this.eventSource) { // Push up a new event this.eventSource.next(event);