jQuery Alert Plugin

jQuery 2013.01.31 10:13

괜찮은 jQuery alert plugin!!

alertify.js 중간에 html5 레이아웃 목적의 태그인 nav, article, section 태그를 생성하고 이용하여 그 부분은 div 로 모두 변경함!!!


참고 사이트 : http://fabien-d.github.com/alertify.js/


/*global define*/

(function (global, undefined) {

"use strict";


var document = global.document,

   Alertify;


Alertify = function () {


var _alertify = {},

   dialogs   = {},

   isopen    = false,

   keys      = { ENTER: 13, ESC: 27, SPACE: 32 },

   queue     = [],

   $, btnCancel, btnOK, btnReset, btnFocus, elCallee, elCover, elDialog, elLog, form, input, getTransitionEvent;


/**

* Markup pieces

* @type {Object}

*/

dialogs = {

buttons : {

holder : "<div class=\"alertify-buttons\">{{buttons}}</div>",

submit : "<button type=\"submit\" class=\"alertify-button alertify-button-ok\" id=\"alertify-ok\">{{ok}}</button>",

ok     : "<a href=\"#\" class=\"alertify-button alertify-button-ok\" id=\"alertify-ok\">{{ok}}</a>",

cancel : "<a href=\"#\" class=\"alertify-button alertify-button-cancel\" id=\"alertify-cancel\">{{cancel}}</a>"

},

input   : "<div class=\"alertify-text-wrapper\"><input type=\"text\" class=\"alertify-text\" id=\"alertify-text\"></div>",

message : "<p class=\"alertify-message\">{{message}}</p>",

log     : "<div class=\"alertify-log{{class}}\">{{message}}</div>"

};


/**

* Return the proper transitionend event

* @return {String}    Transition type string

*/

getTransitionEvent = function () {

var t,

   el = document.createElement("fakeelement"),

   transitions = {

"WebkitTransition" : "webkitTransitionEnd",

"MozTransition"    : "transitionend",

"OTransition"      : "otransitionend",

"transition"       : "transitionend"

};


for (t in transitions) {

if (el.style[t] !== undefined) return transitions[t];

}

};


/**

* Shorthand for document.getElementById()

*

* @param  {String} id    A specific element ID

* @return {Object}       HTML element

*/

$ = function (id) {

return document.getElementById(id);

};


/**

* Alertify private object

* @type {Object}

*/

_alertify = {


/**

* Labels object

* @type {Object}

*/

labels : {

ok     : "OK",

cancel : "Cancel"

},


/**

* Delay number

* @type {Number}

*/

delay : 5000,


/**

* Whether buttons are reversed (default is secondary/primary)

* @type {Boolean}

*/

buttonReverse : false,


/**

* Which button should be focused by default

* @type {String} "ok" (default), "cancel", or "none"

*/

buttonFocus : "ok",


/**

* Set the transition event on load

* @type {[type]}

*/

transition : undefined,


/**

* Set the proper button click events

*

* @param {Function} fn    [Optional] Callback function

*

* @return {undefined}

*/

addListeners : function (fn) {

var hasOK     = (typeof btnOK !== "undefined"),

   hasCancel = (typeof btnCancel !== "undefined"),

   hasInput  = (typeof input !== "undefined"),

   val       = "",

   self      = this,

   ok, cancel, common, key, reset;


// ok event handler

ok = function (event) {

if (typeof event.preventDefault !== "undefined") event.preventDefault();

common(event);

if (typeof input !== "undefined") val = input.value;

if (typeof fn === "function") {

if (typeof input !== "undefined") {

fn(true, val);

}

else fn(true);

}

return false;

};


// cancel event handler

cancel = function (event) {

if (typeof event.preventDefault !== "undefined") event.preventDefault();

common(event);

if (typeof fn === "function") fn(false);

return false;

};


// common event handler (keyup, ok and cancel)

common = function (event) {

self.hide();

self.unbind(document.body, "keyup", key);

self.unbind(btnReset, "focus", reset);

if (hasInput) self.unbind(form, "submit", ok);

if (hasOK) self.unbind(btnOK, "click", ok);

if (hasCancel) self.unbind(btnCancel, "click", cancel);

};


// keyup handler

key = function (event) {

var keyCode = event.keyCode;

if (keyCode === keys.SPACE && !hasInput) ok(event);

if (keyCode === keys.ESC && hasCancel) cancel(event);

};


// reset focus to first item in the dialog

reset = function (event) {

if (hasInput) input.focus();

else if (hasCancel) btnCancel.focus();

else btnOK.focus();

};


// handle reset focus link

// this ensures that the keyboard focus does not

// ever leave the dialog box until an action has

// been taken

this.bind(btnReset, "focus", reset);

// handle OK click

if (hasOK) this.bind(btnOK, "click", ok);

// handle Cancel click

if (hasCancel) this.bind(btnCancel, "click", cancel);

// listen for keys, Cancel => ESC

this.bind(document.body, "keyup", key);

// bind form submit

if (hasInput) this.bind(form, "submit", ok);

if (typeof this.transition === "undefined") {

this.setFocus();

}

},


/**

* Bind events to elements

*

* @param  {Object}   el       HTML Object

* @param  {Event}    event    Event to attach to element

* @param  {Function} fn       Callback function

*

* @return {undefined}

*/

bind : function (el, event, fn) {

if (typeof el.addEventListener === "function") {

el.addEventListener(event, fn, false);

} else if (el.attachEvent) {

el.attachEvent("on" + event, fn);

}

},


/**

* Append button HTML strings

*

* @param {String} secondary    The secondary button HTML string

* @param {String} primary      The primary button HTML string

*

* @return {String}             The appended button HTML strings

*/

appendButtons : function (secondary, primary) {

return this.buttonReverse ? primary + secondary : secondary + primary;

},


/**

* 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 html    = "",

   type    = item.type,

   message = item.message,

   css     = item.cssClass || "";


html += "<div class=\"alertify-dialog\">";


if (_alertify.buttonFocus === "none") html += "<a href=\"#\" id=\"alertify-noneFocus\" class=\"alertify-hidden\"></a>";


if (type === "prompt") html += "<form id=\"alertify-form\">";


html += "<div class=\"alertify-inner\">";

html += dialogs.message.replace("{{message}}", message);


if (type === "prompt") html += dialogs.input;


html += dialogs.buttons.holder;

html += "</div>";


if (type === "prompt") html += "</form>";


html += "<a id=\"alertify-resetFocus\" class=\"alertify-resetFocus\" href=\"#\">Reset Focus</a>";

html += "</div>";


switch (type) {

case "confirm":

html = html.replace("{{buttons}}", this.appendButtons(dialogs.buttons.cancel, dialogs.buttons.ok));

html = html.replace("{{ok}}", this.labels.ok).replace("{{cancel}}", this.labels.cancel);

break;

case "prompt":

html = html.replace("{{buttons}}", this.appendButtons(dialogs.buttons.cancel, dialogs.buttons.submit));

html = html.replace("{{ok}}", this.labels.ok).replace("{{cancel}}", this.labels.cancel);

break;

case "alert":

html = html.replace("{{buttons}}", dialogs.buttons.ok);

html = html.replace("{{ok}}", this.labels.ok);

break;

default:

break;

}


elDialog.className = "alertify alertify-show alertify-" + type + " " + css;

elCover.className  = "alertify-cover";

return html;

},


/**

* 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) {

// Unary Plus: +"2" === 2

var timer = (wait && !isNaN(wait)) ? +wait : this.delay,

   self  = this,

   hideElement, transitionDone;


// set click event on log messages

this.bind(elem, "click", function () {

hideElement(elem);

});

// Hide the dialog box after transition

// This ensure it doens't block any element from being clicked

transitionDone = function (event) {

event.stopPropagation();

// unbind event so function only gets called once

self.unbind(this, self.transition, transitionDone);

// remove log message

elLog.removeChild(this);

if (!elLog.hasChildNodes()) elLog.className += " alertify-logs-hidden";

};

// this sets the hide class to transition out

// or removes the child if css transitions aren't supported

hideElement = function (el) {

// ensure element exists

if (typeof el !== "undefined" && el.parentNode === elLog) {

// whether CSS transition exists

if (typeof self.transition !== "undefined") {

self.bind(el, self.transition, transitionDone);

el.className += " alertify-log-hide";

} else {

elLog.removeChild(el);

if (!elLog.hasChildNodes()) elLog.className += " alertify-logs-hidden";

}

}

};

// never close (until click) if wait is set to 0

if (wait === 0) return;

// set timeout to auto close the log message

setTimeout(function () { hideElement(elem); }, timer);

},


/**

* Create a dialog box

*

* @param  {String}   message        The message passed from the callee

* @param  {String}   type           Type of dialog to create

* @param  {Function} fn             [Optional] Callback function

* @param  {String}   placeholder    [Optional] Default value for prompt input field

* @param  {String}   cssClass       [Optional] Class(es) to append to dialog box

*

* @return {Object}

*/

dialog : function (message, type, fn, placeholder, cssClass) {

// set the current active element

// this allows the keyboard focus to be resetted

// after the dialog box is closed

elCallee = document.activeElement;

// check to ensure the alertify dialog element

// has been successfully created

var check = function () {

if (elDialog && elDialog.scrollTop !== null) return;

else check();

};

// error catching

if (typeof message !== "string") throw new Error("message must be a string");

if (typeof type !== "string") throw new Error("type must be a string");

if (typeof fn !== "undefined" && typeof fn !== "function") throw new Error("fn must be a function");

// initialize alertify if it hasn't already been done

if (typeof this.init === "function") {

this.init();

check();

}


queue.push({ type: type, message: message, callback: fn, placeholder: placeholder, cssClass: cssClass });

if (!isopen) this.setup();


return this;

},


/**

* Extend the log method to create custom methods

*

* @param  {String} type    Custom method name

*

* @return {Function}

*/

extend : function (type) {

if (typeof type !== "string") throw new Error("extend method must have exactly one paramter");

return function (message, wait) {

this.log(message, type, wait);

return this;

};

},


/**

* Hide the dialog and rest to defaults

*

* @return {undefined}

*/

hide : function () {

var transitionDone,

   self = this;

// remove reference from queue

queue.splice(0,1);

// if items remaining in the queue

if (queue.length > 0) this.setup();

else {

isopen = false;

// Hide the dialog box after transition

// This ensure it doens't block any element from being clicked

transitionDone = function (event) {

event.stopPropagation();

elDialog.className += " alertify-isHidden";

// unbind event so function only gets called once

self.unbind(elDialog, self.transition, transitionDone);

};

// whether CSS transition exists

if (typeof this.transition !== "undefined") {

this.bind(elDialog, this.transition, transitionDone);

elDialog.className = "alertify alertify-hide alertify-hidden";

} else {

elDialog.className = "alertify alertify-hide alertify-hidden alertify-isHidden";

}

elCover.className  = "alertify-cover alertify-cover-hidden";

// set focus to the last element or body

// after the dialog is closed

elCallee.focus();

}

},


/**

* Initialize Alertify

* Create the 2 main elements

*

* @return {undefined}

*/

init : function () {

// ensure legacy browsers support html5 tags

// cover

elCover = document.createElement("div");

elCover.setAttribute("id", "alertify-cover");

elCover.className = "alertify-cover alertify-cover-hidden";

document.body.appendChild(elCover);

// main element

elDialog = document.createElement("section");

elDialog.setAttribute("id", "alertify");

elDialog.className = "alertify alertify-hidden";

document.body.appendChild(elDialog);

// log element

elLog = document.createElement("section");

elLog.setAttribute("id", "alertify-logs");

elLog.className = "alertify-logs alertify-logs-hidden";

document.body.appendChild(elLog);

// set tabindex attribute on body element

// this allows script to give it focus

// after the dialog is closed

document.body.setAttribute("tabindex", "0");

// set transition type

this.transition = getTransitionEvent();

// clean up init method

delete this.init;

},


/**

* 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, wait) {

// check to ensure the alertify dialog element

// has been successfully created

var check = function () {

if (elLog && elLog.scrollTop !== null) return;

else check();

};

// initialize alertify if it hasn't already been done

if (typeof this.init === "function") {

this.init();

check();

}

elLog.className = "alertify-logs";

this.notify(message, type, wait);

return this;

},


/**

* Add new log message

* If a type is passed, a class name "alertify-log-{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, wait) {

var log = document.createElement("div");

log.className = "alertify-log" + ((typeof type === "string" && type !== "") ? " alertify-log-" + type : "");

log.innerHTML = message;

// prepend child

elLog.insertBefore(log, elLog.firstChild);

// triggers the CSS animation

setTimeout(function() { log.className = log.className + " alertify-log-show"; }, 50);

this.close(log, wait);

},


/**

* Set properties

*

* @param {Object} args     Passing parameters

*

* @return {undefined}

*/

set : function (args) {

var k;

// error catching

if (typeof args !== "object" && args instanceof Array) throw new Error("args must be an object");

// set parameters

for (k in args) {

if (args.hasOwnProperty(k)) {

this[k] = args[k];

}

}

},


/**

* Common place to set focus to proper element

*

* @return {undefined}

*/

setFocus : function () {

if (input) {

input.focus();

input.select();

}

else btnFocus.focus();

},


/**

* Initiate all the required pieces for the dialog box

*

* @return {undefined}

*/

setup : function () {

var item = queue[0],

   self = this,

   transitionDone;


// dialog is open

isopen = true;

// Set button focus after transition

transitionDone = function (event) {

event.stopPropagation();

self.setFocus();

// unbind event so function only gets called once

self.unbind(elDialog, self.transition, transitionDone);

};

// whether CSS transition exists

if (typeof this.transition !== "undefined") {

this.bind(elDialog, this.transition, transitionDone);

}

// build the proper dialog HTML

elDialog.innerHTML = this.build(item);

// assign all the common elements

btnReset  = $("alertify-resetFocus");

btnOK     = $("alertify-ok")     || undefined;

btnCancel = $("alertify-cancel") || undefined;

btnFocus  = (_alertify.buttonFocus === "cancel") ? btnCancel : ((_alertify.buttonFocus === "none") ? $("alertify-noneFocus") : btnOK),

input     = $("alertify-text")   || undefined;

form      = $("alertify-form")   || undefined;

// add placeholder value to the input field

if (typeof item.placeholder === "string" && item.placeholder !== "") input.value = item.placeholder;

this.addListeners(item.callback);

},


/**

* Unbind events to elements

*

* @param  {Object}   el       HTML Object

* @param  {Event}    event    Event to detach to element

* @param  {Function} fn       Callback function

*

* @return {undefined}

*/

unbind : function (el, event, fn) {

if (typeof el.removeEventListener === "function") {

el.removeEventListener(event, fn, false);

} else if (el.detachEvent) {

el.detachEvent("on" + event, fn);

}

}

};


return {

alert   : function (message, fn, cssClass) { _alertify.dialog(message, "alert", fn, "", cssClass); return this; },

confirm : function (message, fn, cssClass) { _alertify.dialog(message, "confirm", fn, "", cssClass); return this; },

extend  : _alertify.extend,

init    : _alertify.init,

log     : function (message, type, wait) { _alertify.log(message, type, wait); return this; },

prompt  : function (message, fn, placeholder, cssClass) { _alertify.dialog(message, "prompt", fn, placeholder, cssClass); return this; },

success : function (message, wait) { _alertify.log(message, "success", wait); return this; },

error   : function (message, wait) { _alertify.log(message, "error", wait); return this; },

set     : function (args) { _alertify.set(args); },

labels  : _alertify.labels

};

};


// AMD and window support

if (typeof define === "function") {

define([], function () { return new Alertify(); });

} else if (typeof global.alertify === "undefined") {

global.alertify = new Alertify();

}


}(this));


저작자 표시 비영리 변경 금지
신고

'jQuery' 카테고리의 다른 글

jQuery Chart Plugin  (0) 2013.01.31
jQuery Alert Plugin  (0) 2013.01.31
Check All Checkboxes with JQuery  (0) 2011.04.14
jqgrid 에서의 custom validation  (0) 2011.01.11
posted by 소연파파™