You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
524 lines
19 KiB
524 lines
19 KiB
(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.10",
|
|
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='1'>{{ok}}</button>",
|
|
cancel: "<button class='cancel' tabindex='2'>{{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='1'>{{ok}}</button>",
|
|
cancel: "<button class='cancel' tabindex='2'>{{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>" + this.dialogs.message.replace("{{message}}", item.message);
|
|
|
|
if(item.type === "confirm" || item.type === "prompt") {
|
|
btnTxt = this.dialogs.buttons.cancel + this.dialogs.buttons.ok;
|
|
}
|
|
|
|
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(ev) {
|
|
hideElement(ev.srcElement);
|
|
});
|
|
}
|
|
|
|
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 () {};
|
|
}
|
|
|
|
if (btnOK) {
|
|
btnOK.addEventListener("click", function(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);
|
|
});
|
|
}
|
|
|
|
if (btnCancel) {
|
|
btnCancel.addEventListener("click", function(ev) {
|
|
if (item.onCancel && "function" === typeof item.onCancel) {
|
|
item.onCancel(ev);
|
|
}
|
|
|
|
resolve({
|
|
buttonClicked: "cancel",
|
|
event: ev
|
|
});
|
|
|
|
hideElement(el);
|
|
});
|
|
}
|
|
}
|
|
|
|
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='1'>{{ok}}</button>";
|
|
this.dialogs.buttons.cancel = "<button class='cancel btn btn-default' tabindex='2'>{{cancel}}</button>";
|
|
this.dialogs.input = "<input type='text' class='form-control'>";
|
|
break;
|
|
case "purecss":
|
|
this.dialogs.buttons.ok = "<button class='ok pure-button' tabindex='1'>{{ok}}</button>";
|
|
this.dialogs.buttons.cancel = "<button class='cancel pure-button' tabindex='2'>{{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='1'>{{ok}}</button>";
|
|
this.dialogs.buttons.cancel = "<button class='cancel mdl-button mdl-js-button mdl-js-ripple-effect' tabindex='2'>{{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='1'>{{ok}}</button>";
|
|
this.dialogs.buttons.cancel = "<button class='cancel md-button' tabindex='2'>{{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 = "/* style.css */";
|
|
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();
|
|
}
|
|
|
|
}());
|
|
|