UNPKG

bmsdave-ngalertify

Version:
560 lines (481 loc) 24.1 kB
angular.module("ngAlertify", []).factory("alertify", function() { "use strict"; // A quick hack to avoid exposing alertify to the window scope. var module = { exports: true }; // Don't the line below as the alertif.js contents are // automatically injected here based on the string contents. (function() { "use strict"; var TRANSITION_FALLBACK_DURATION = 500; var hideElement = function(el) { if (! el) { return; } var removeThis = function() { if (el && el.parentNode) { el.parentNode.removeChild(el); } }; el.classList.remove("show"); el.classList.add("hide"); el.addEventListener("transitionend", removeThis); // Fallback for no transitions. setTimeout(removeThis, TRANSITION_FALLBACK_DURATION); }; function Alertify() { /** * Alertify private object * @type {Object} */ var _alertify = { parent: document.body, version: "1.0.11", defaultOkLabel: "Ok", okLabel: "Ok", defaultCancelLabel: "Cancel", cancelLabel: "Cancel", defaultMaxLogItems: 2, maxLogItems: 2, promptValue: "", promptPlaceholder: "", closeLogOnClick: false, closeLogOnClickDefault: false, delay: 5000, defaultDelay: 5000, logContainerClass: "alertify-logs", logContainerDefaultClass: "alertify-logs", dialogs: { buttons: { holder: "<nav>{{buttons}}</nav>", ok: "<button class='ok' tabindex='0'>{{ok}}</button>", cancel: "<button class='cancel' tabindex='0'>{{cancel}}</button>" }, input: "<input type='text'>", message: "<p class='msg'>{{message}}</p>", log: "<div class='{{class}}'>{{message}}</div>" }, defaultDialogs: { buttons: { holder: "<nav>{{buttons}}</nav>", ok: "<button class='ok' tabindex='0'>{{ok}}</button>", cancel: "<button class='cancel' tabindex='0'>{{cancel}}</button>" }, input: "<input type='text'>", message: "<p class='msg'>{{message}}</p>", log: "<div class='{{class}}'>{{message}}</div>" }, /** * Build the proper message box * * @param {Object} item Current object in the queue * * @return {String} An HTML string of the message box */ build: function(item) { var btnTxt = this.dialogs.buttons.ok; var html = "<div class='dialog'>" + "<div onclick='event.stopPropagation()'>" + this.dialogs.message.replace("{{message}}", item.message); if(item.type === "confirm" || item.type === "prompt") { btnTxt = this.dialogs.buttons.ok + this.dialogs.buttons.cancel; } if (item.type === "prompt") { html += this.dialogs.input; } html = (html + this.dialogs.buttons.holder + "</div>" + "</div>") .replace("{{buttons}}", btnTxt) .replace("{{ok}}", this.okLabel) .replace("{{cancel}}", this.cancelLabel); return html; }, setCloseLogOnClick: function(bool) { this.closeLogOnClick = !! bool; }, /** * Close the log messages * * @param {Object} elem HTML Element of log message to close * @param {Number} wait [optional] Time (in ms) to wait before automatically hiding the message, if 0 never hide * * @return {undefined} */ close: function(elem, wait) { if (this.closeLogOnClick) { elem.addEventListener("click", function() { hideElement(elem); }); } wait = wait && !isNaN(+wait) ? +wait : this.delay; if (wait < 0) { hideElement(elem); } else if(wait > 0) { setTimeout(function() { hideElement(elem); }, wait); } }, /** * Create a dialog box * * @param {String} message The message passed from the callee * @param {String} type Type of dialog to create * @param {Function} onOkay [Optional] Callback function when clicked okay. * @param {Function} onCancel [Optional] Callback function when cancelled. * * @return {Object} */ dialog: function(message, type, onOkay, onCancel) { return this.setup({ type: type, message: message, onOkay: onOkay, onCancel: onCancel }); }, /** * Show a new log message box * * @param {String} message The message passed from the callee * @param {String} type [Optional] Optional type of log message * @param {Number} wait [Optional] Time (in ms) to wait before auto-hiding the log * * @return {Object} */ log: function(message, type, click) { var existing = document.querySelectorAll(".alertify-logs > div"); if (existing) { var diff = existing.length - this.maxLogItems; if (diff >= 0) { for (var i = 0, _i = diff + 1; i < _i; i++) { this.close(existing[i], -1); } } } this.notify(message, type, click); }, setLogPosition: function(str) { this.logContainerClass = "alertify-logs " + str; }, setupLogContainer: function() { var elLog = document.querySelector(".alertify-logs"); var className = this.logContainerClass; if (! elLog) { elLog = document.createElement("div"); elLog.className = className; this.parent.appendChild(elLog); } // Make sure it's positioned properly. if (elLog.className !== className) { elLog.className = className; } return elLog; }, /** * Add new log message * If a type is passed, a class name "{type}" will get added. * This allows for custom look and feel for various types of notifications. * * @param {String} message The message passed from the callee * @param {String} type [Optional] Type of log message * @param {Number} wait [Optional] Time (in ms) to wait before auto-hiding * * @return {undefined} */ notify: function(message, type, click) { var elLog = this.setupLogContainer(); var log = document.createElement("div"); log.className = (type || "default"); if (_alertify.logTemplateMethod) { log.innerHTML = _alertify.logTemplateMethod(message); } else { log.innerHTML = message; } // Add the click handler, if specified. if ("function" === typeof click) { log.addEventListener("click", click); } elLog.appendChild(log); setTimeout(function() { log.className += " show"; }, 10); this.close(log, this.delay); }, /** * Initiate all the required pieces for the dialog box * * @return {undefined} */ setup: function(item) { var el = document.createElement("div"); el.className = "alertify hide"; el.innerHTML = this.build(item); var btnOK = el.querySelector(".ok"); var btnCancel = el.querySelector(".cancel"); var input = el.querySelector("input"); var label = el.querySelector("label"); // Set default value/placeholder of input if (input) { if (typeof this.promptPlaceholder === "string") { // Set the label, if available, for MDL, etc. if (label) { label.textContent = this.promptPlaceholder; } else { input.placeholder = this.promptPlaceholder; } } if (typeof this.promptValue === "string") { input.value = this.promptValue; } } function setupHandlers(resolve) { if ("function" !== typeof resolve) { // promises are not available so resolve is a no-op resolve = function () {}; } function okHandler(ev) { if (item.onOkay && "function" === typeof item.onOkay) { if (input) { item.onOkay(input.value, ev); } else { item.onOkay(ev); } } if (input) { resolve({ buttonClicked: "ok", inputValue: input.value, event: ev }); } else { resolve({ buttonClicked: "ok", event: ev }); } hideElement(el); } function cancelHandler(ev) { if (item.onCancel && "function" === typeof item.onCancel) { item.onCancel(ev); } resolve({ buttonClicked: "cancel", event: ev }); hideElement(el); } if (btnOK) { btnOK.addEventListener("click", okHandler); } if (btnCancel) { btnCancel.addEventListener("click", cancelHandler); el.addEventListener("click", cancelHandler); } else { el.addEventListener("click", okHandler); } if (input) { input.addEventListener("keyup", function(ev) { if (ev.currentTarget.value === "") { btnOK.setAttribute("disabled", "true"); } else { btnOK.removeAttribute("disabled"); } if (ev.which === 13) { btnOK.click(); } }); } } var promise; if (typeof Promise === "function") { promise = new Promise(setupHandlers); } else { setupHandlers(); } this.parent.appendChild(el); setTimeout(function() { el.classList.remove("hide"); if(input && item.type && item.type === "prompt") { input.select(); input.focus(); } else { if (btnOK) { btnOK.focus(); } } }, 100); return promise; }, okBtn: function(label) { this.okLabel = label; return this; }, setDelay: function(time) { time = time || 0; this.delay = isNaN(time) ? this.defaultDelay : parseInt(time, 10); return this; }, cancelBtn: function(str) { this.cancelLabel = str; return this; }, setMaxLogItems: function(num) { this.maxLogItems = parseInt(num || this.defaultMaxLogItems); }, theme: function(themeStr) { switch(themeStr.toLowerCase()) { case "bootstrap": this.dialogs.buttons.ok = "<button class='ok btn btn-primary' tabindex='0'>{{ok}}</button>"; this.dialogs.buttons.cancel = "<button class='cancel btn btn-default' tabindex='0'>{{cancel}}</button>"; this.dialogs.input = "<input type='text' class='form-control'>"; break; case "purecss": this.dialogs.buttons.ok = "<button class='ok pure-button' tabindex='0'>{{ok}}</button>"; this.dialogs.buttons.cancel = "<button class='cancel pure-button' tabindex='0'>{{cancel}}</button>"; break; case "mdl": case "material-design-light": this.dialogs.buttons.ok = "<button class='ok mdl-button mdl-js-button mdl-js-ripple-effect' tabindex='0'>{{ok}}</button>"; this.dialogs.buttons.cancel = "<button class='cancel mdl-button mdl-js-button mdl-js-ripple-effect' tabindex='0'>{{cancel}}</button>"; this.dialogs.input = "<div class='mdl-textfield mdl-js-textfield'><input class='mdl-textfield__input'><label class='md-textfield__label'></label></div>"; break; case "angular-material": this.dialogs.buttons.ok = "<button class='ok md-primary md-button' tabindex='0'>{{ok}}</button>"; this.dialogs.buttons.cancel = "<button class='cancel md-button' tabindex='0'>{{cancel}}</button>"; this.dialogs.input = "<div layout='column'><md-input-container md-no-float><input type='text'></md-input-container></div>"; break; case "default": default: this.dialogs.buttons.ok = this.defaultDialogs.buttons.ok; this.dialogs.buttons.cancel = this.defaultDialogs.buttons.cancel; this.dialogs.input = this.defaultDialogs.input; break; } }, reset: function() { this.parent = document.body; this.theme("default"); this.okBtn(this.defaultOkLabel); this.cancelBtn(this.defaultCancelLabel); this.setMaxLogItems(); this.promptValue = ""; this.promptPlaceholder = ""; this.delay = this.defaultDelay; this.setCloseLogOnClick(this.closeLogOnClickDefault); this.setLogPosition("bottom left"); this.logTemplateMethod = null; }, injectCSS: function() { if (!document.querySelector("#alertifyCSS")) { var head = document.getElementsByTagName("head")[0]; var css = document.createElement("style"); css.type = "text/css"; css.id = "alertifyCSS"; css.innerHTML = ".alertify-logs>*{padding:12px 24px;color:#fff;box-shadow:0 2px 5px 0 rgba(0,0,0,.2);border-radius:1px;transition:all .2s;display:block!important}.alertify-logs>*,.alertify-logs>.default{background:rgba(0,0,0,.8)}.alertify-logs>.error{background:rgba(244,67,54,.8)}.alertify-logs>.success{background:rgba(76,175,80,.9)}.alertify{position:fixed;background-color:rgba(0,0,0,.3);left:0;right:0;top:0;bottom:0;width:100%;height:100%;z-index:1}.alertify.hide{opacity:0;pointer-events:none}.alertify,.alertify.show{box-sizing:border-box;transition:all .33s cubic-bezier(.25,.8,.25,1)}.alertify,.alertify *{box-sizing:border-box}.alertify .dialog{padding:12px}.alertify .alert,.alertify .dialog{width:100%;margin:0 auto;position:relative;top:50%;transform:translateY(-50%)}.alertify .alert>*,.alertify .dialog>*{width:400px;max-width:95%;margin:0 auto;text-align:center;padding:12px;background:#fff;box-shadow:0 2px 4px -1px rgba(0,0,0,.14),0 4px 5px 0 rgba(0,0,0,.098),0 1px 10px 0 rgba(0,0,0,.084)}.alertify .alert .msg,.alertify .dialog .msg{padding:12px;margin-bottom:12px;margin:0;text-align:left}.alertify .alert input:not(.form-control),.alertify .dialog input:not(.form-control){margin-bottom:15px;width:100%;font-size:100%;padding:12px}.alertify .alert input:not(.form-control):focus,.alertify .dialog input:not(.form-control):focus{outline-offset:-2px}.alertify .alert nav,.alertify .dialog nav{height:40px;text-align:right}.alertify .alert nav button,.alertify .dialog nav button{float:right;background:transparent;box-sizing:border-box;color:rgba(0,0,0,.87);position:relative;outline:0;border:0;display:block;-ms-flex-align:center;align-items:center;padding:0 6px;margin:6px 8px;line-height:36px;min-height:36px;white-space:nowrap;min-width:88px;text-align:center;text-transform:uppercase;font-size:14px;text-decoration:none;cursor:pointer;border:1px solid transparent;border-radius:2px}.alertify .alert nav button:active,.alertify .alert nav button:hover,.alertify .dialog nav button:active,.alertify .dialog nav button:hover{background-color:rgba(0,0,0,.05)}.alertify .alert nav button:focus,.alertify .dialog nav button:focus{border:1px solid rgba(0,0,0,.1)}.alertify .alert nav button.btn,.alertify .dialog nav button.btn{margin:6px 4px}.alertify .alert nav button[disabled].ok,.alertify .dialog nav button[disabled].ok{color:grey!important}.alertify .alert nav button[disabled].ok:active,.alertify .alert nav button[disabled].ok:hover,.alertify .dialog nav button[disabled].ok:active,.alertify .dialog nav button[disabled].ok:hover{background-color:#fff!important}.alertify .alert nav button[disabled].ok:focus,.alertify .dialog nav button[disabled].ok:focus{border:1px solid #fff!important}.alertify-logs{position:fixed;z-index:1}.alertify-logs.bottom,.alertify-logs:not(.top){bottom:16px}.alertify-logs.left,.alertify-logs:not(.right){left:16px}.alertify-logs.left>*,.alertify-logs:not(.right)>*{float:left;transform:translateZ(0);height:auto}.alertify-logs.left>.show,.alertify-logs:not(.right)>.show{left:0}.alertify-logs.left>*,.alertify-logs.left>.hide,.alertify-logs:not(.right)>*,.alertify-logs:not(.right)>.hide{left:-110%}.alertify-logs.right{right:16px}.alertify-logs.right>*{float:right;transform:translateZ(0)}.alertify-logs.right>.show{right:0;opacity:1}.alertify-logs.right>*,.alertify-logs.right>.hide{right:-110%;opacity:0}.alertify-logs.top{top:0}.alertify-logs>*{box-sizing:border-box;transition:all .4s cubic-bezier(.25,.8,.25,1);position:relative;clear:both;-webkit-backface-visibility:hidden;backface-visibility:hidden;perspective:1000;max-height:0;margin:0;padding:0;overflow:hidden;opacity:0;pointer-events:none}.alertify-logs>.show{margin-top:12px;opacity:1;max-height:1000px;padding:12px;pointer-events:auto}"; head.insertBefore(css, head.firstChild); } }, removeCSS: function() { var css = document.querySelector("#alertifyCSS"); if (css && css.parentNode) { css.parentNode.removeChild(css); } } }; _alertify.injectCSS(); return { _$$alertify: _alertify, parent: function(elem) { _alertify.parent = elem; }, reset: function() { _alertify.reset(); return this; }, alert: function(message, onOkay, onCancel) { return _alertify.dialog(message, "alert", onOkay, onCancel) || this; }, confirm: function(message, onOkay, onCancel) { return _alertify.dialog(message, "confirm", onOkay, onCancel) || this; }, prompt: function(message, onOkay, onCancel) { return _alertify.dialog(message, "prompt", onOkay, onCancel) || this; }, log: function(message, click) { _alertify.log(message, "default", click); return this; }, theme: function(themeStr) { _alertify.theme(themeStr); return this; }, success: function(message, click) { _alertify.log(message, "success", click); return this; }, error: function(message, click) { _alertify.log(message, "error", click); return this; }, cancelBtn: function(label) { _alertify.cancelBtn(label); return this; }, okBtn: function(label) { _alertify.okBtn(label); return this; }, delay: function(time) { _alertify.setDelay(time); return this; }, placeholder: function(str) { _alertify.promptPlaceholder = str; return this; }, defaultValue: function(str) { _alertify.promptValue = str; return this; }, maxLogItems: function(num) { _alertify.setMaxLogItems(num); return this; }, closeLogOnClick: function(bool) { _alertify.setCloseLogOnClick(!! bool); return this; }, logPosition: function(str) { _alertify.setLogPosition(str || ""); return this; }, setLogTemplate: function(templateMethod) { _alertify.logTemplateMethod = templateMethod; return this; }, clearLogs: function() { _alertify.setupLogContainer().innerHTML = ""; return this; }, version: _alertify.version }; } // AMD, window, and NPM support if ("undefined" !== typeof module && !! module && !! module.exports) { // Preserve backwards compatibility module.exports = function() { return new Alertify(); }; var obj = new Alertify(); for (var key in obj) { module.exports[key] = obj[key]; } } else if (typeof define === "function" && define.amd) { define(function() { return new Alertify(); }); } else { window.alertify = new Alertify(); } }()); var Alertify = module.exports; return new Alertify(); });