среда, 5 марта 2014 г.

Alertbox - не блокирующие Alert, Comfirm, Prompt

Файл alertbox.js

define(function(){

    // Вывод собственных вариантов Alert, Confirm, Prompt
   
    // Примеры использования:
   
    // Замена alert(text')
   
    // AlertBox.alert(
    //        'Внимание!'
    //      , function(returnedValue){
    //          console.log('Alert всегда возвращает значение: ' + returnedValue + '.');
    //       }
    // );
   
    // Замена confirm('text');
   
    // AlertBox.confirm(
    //        'Вы уверены, что хотите выйти?'
    //      , function(returnedValue){console.log('Вы выбрали "Нет", поскольку получено значение: ' + returnedValue + '.');}
    //      , function(returnedValue){console.log('Вы выбрали "Да", поскольку получено значение: ' + returnedValue + '.');}
    // );
   
    // Замена confirm('text', 'default value');
   
    // AlertBox.prompt(
    //       'Сколько будет равно 2+2?'
    //     , '2'
    //     , function(returnedValue){console.log('Вы решили не отвечать на вопрос, поскольку получено значение: ' + returnedValue + '.');}
    //     , function(returnedValue){
    //          returnedValue = parseInt(returnedValue, 10);
    //          if (returnedValue === 4) {
    //              console.log('Ответ правильный.');
    //          } else {
    //              console.log('Ответ неправильный. 2+2=4');
    //          }
    //       }
    // );
   
    // Во всех случаях функции обратного вызова можно не писать.

    var AlertBox = (function(){

        // Constructor
       
        var AlertBox = {};

        // Private variables
       
        var stack = []
            , currentAlertBoxObject = null;
       
        // Private functions
       
        function correctValue (object, property) {
            if (object[property] === undefined || object[property] === null) {
                return '';
            }
            return object[property];
        }
       
        function addMessageToStack (args) {
            var type = correctValue(args, 'type')
                , text = correctValue(args, 'text')
                , inputDefaultValue = correctValue(args, 'inputDefaultValue')
                , cancelFunction = args.cancelFunction || function () {}
                , okFunction = args.okFunction  || function () {}
                , message = {};
            message.type = '' + type;
            message.text = '' + text;
            if (message.type === 'prompt') {
                message.inputDefaultValue = '' + inputDefaultValue;
            }
            message.cancelFunction = cancelFunction;
            if (message.type !== 'alert') {
                message.okFunction = okFunction;
            }
            stack.push(message);
        }
       
        function showMessageFromStack () {
            var alertBoxBlock = document.getElementById('alertbox');
            if (
                    ( alertBoxBlock === null || (alertBoxBlock.offsetWidth <= 0 && alertBoxBlock.offsetHeight <= 0) )
                && stack.length !== 0
            ) {
                currentAlertBoxObject = stack.shift();
                document.body.appendChild(renderAlertBoxTemplate());
                addOnClickFunctions(currentAlertBoxObject);
            }
        }
       
        function renderAlertBoxTemplate () {
            var alertBoxElement = document.createElement('div');
                  alertBoxElement.id = 'alertbox';
            var alertBoxHTML = '<div id="alertbox-opaque-layer"></div>'
                                        + '<div id="alertbox-' + currentAlertBoxObject.type + '">'
                                        + '<div id="alertbox-' + currentAlertBoxObject.type + '-wrapper">'
                                        + '<p id="alertbox-text">' + currentAlertBoxObject.text + '</p>'
                                        + '</div>';
            if (currentAlertBoxObject.type === 'alert') {
                alertBoxHTML += '<div id="alertbox-alert-buttons">'
                                        + '<div id="alertbox-cancel">Ok</div>';
            } else if (currentAlertBoxObject.type === 'confirm') {
                alertBoxHTML += '<div id="alertbox-confirm-buttons">'
                                        + '<div id="alertbox-cancel">Нет</div>'
                                        + '<div id="alertbox-ok">Да</div>';
            } else if (currentAlertBoxObject.type === 'prompt') {
                alertBoxHTML += '<div id="alertbox-input-wrapper">'
                                        + '<input id="alertbox-input" value="' + currentAlertBoxObject.inputDefaultValue + '" />'
                                        + '</div>'
                                        + '<div id="alertbox-prompt-buttons">'
                                        + '<div id="alertbox-cancel">Отмена</div>'
                                        + '<div id="alertbox-ok">Ok</div>';
            }
                alertBoxHTML += '</div>'
                                        + '</div>'
                                        + '</div>';
            alertBoxElement.innerHTML = alertBoxHTML;
            return alertBoxElement;
        }
       
        function onAlertBoxClick (event) {
            if (event.stopPropagation) {event.stopPropagation();}
            event.cancelBubble = true;
        }
       
        function addOnClickFunctions (currentAlertBoxObject) {
            on('click', document.getElementById('alertbox-opaque-layer'), onAlertBoxClick);
            if (currentAlertBoxObject.type === 'alert') {
                on('click', document.getElementById('alertbox-alert'), onAlertBoxClick);
                on('click', document.getElementById('alertbox-alert-buttons'), onAlertBoxClick);
            }
            if (currentAlertBoxObject.type === 'confirm') {
                on('click', document.getElementById('alertbox-confirm'), onAlertBoxClick);
                on('click', document.getElementById('alertbox-confirm-buttons'), onAlertBoxClick);
            }
            if (currentAlertBoxObject.type === 'prompt') {
                on('click', document.getElementById('alertbox-prompt'), onAlertBoxClick);
                on('click', document.getElementById('alertbox-prompt-buttons'), onAlertBoxClick);
            }
            on('click', document.getElementById('alertbox-cancel'), onCancelClick);
            if (currentAlertBoxObject.type !== 'alert') {
                on('click', document.getElementById('alertbox-ok'), onOkClick);
            }
            on('keydown', document, onKeyDown);
        }
       
        function addOffClickFunctions (currentAlertBoxObject) {
            off('click', document.getElementById('alertbox-opaque-layer'), onAlertBoxClick);
            if (currentAlertBoxObject.type === 'alert') {
                off('click', document.getElementById('alertbox-alert'), onAlertBoxClick);
                off('click', document.getElementById('alertbox-alert-buttons'), onAlertBoxClick);
            }
            if (currentAlertBoxObject.type === 'confirm') {
                off('click', document.getElementById('alertbox-confirm'), onAlertBoxClick);
                off('click', document.getElementById('alertbox-confirm-buttons'), onAlertBoxClick);
            }
            if (currentAlertBoxObject.type === 'prompt') {
                off('click', document.getElementById('alertbox-prompt'), onAlertBoxClick);
                off('click', document.getElementById('alertbox-prompt-buttons'), onAlertBoxClick);
            }
            if (currentAlertBoxObject.type !== 'alert') {
                off('click', document.getElementById('alertbox-ok'), onOkClick);
            }
            off('click', document.getElementById('alertbox-cancel'), onCancelClick);
            off('keydown', document, onKeyDown);
        }

        function onCancelClick (event) {
            onAlertBoxClick(event);
            var alertBoxValue;
                       if (currentAlertBoxObject.type === 'alert') {alertBoxValue = undefined;
            } else if (currentAlertBoxObject.type === 'confirm') {alertBoxValue = false;
            } else if (currentAlertBoxObject.type === 'prompt') {alertBoxValue = null;
            }
            currentAlertBoxObject.cancelFunction(alertBoxValue);
            addOffClickFunctions(currentAlertBoxObject);
            document.body.removeChild(document.getElementById('alertbox'));
            showMessageFromStack();
        }

        function onOkClick (event) {
            onAlertBoxClick(event);
            var alertBoxValue;
                       if (currentAlertBoxObject.type === 'alert') {alertBoxValue = undefined;
            } else if (currentAlertBoxObject.type === 'confirm') {alertBoxValue = true;
            } else if (currentAlertBoxObject.type === 'prompt') {alertBoxValue = document.getElementById('alertbox-input').value;
            }
            currentAlertBoxObject.okFunction(alertBoxValue);
            addOffClickFunctions(currentAlertBoxObject);
            document.body.removeChild(document.getElementById('alertbox'));
            showMessageFromStack();
        }
                   
        function onKeyDown (event) {
            onAlertBoxClick(event);
            var alertBoxValue;
            if (event.keyCode === 13 || event.keyCode === 32) { // Enter or Space
                           if (currentAlertBoxObject.type === 'alert') {alertBoxValue = undefined;
                } else if (currentAlertBoxObject.type === 'confirm') {alertBoxValue = true;
                } else if (currentAlertBoxObject.type === 'prompt') {alertBoxValue = document.getElementById('alertbox-input').value;
                }
                if (currentAlertBoxObject.type === 'alert') {
                    currentAlertBoxObject.cancelFunction(alertBoxValue);
                } else {
                    currentAlertBoxObject.okFunction(alertBoxValue);
                }
                addOffClickFunctions(currentAlertBoxObject);
                document.body.removeChild(document.getElementById('alertbox'));
                showMessageFromStack();
            } else if (event.keyCode === 27) { // Escape
                          if (currentAlertBoxObject.type === 'alert') {alertBoxValue = undefined;
                } else if (currentAlertBoxObject.type === 'confirm') {alertBoxValue = false;
                } else if (currentAlertBoxObject.type === 'prompt') {alertBoxValue = null;
                }
                currentAlertBoxObject.cancelFunction(alertBoxValue);
                addOffClickFunctions(currentAlertBoxObject);
                document.body.removeChild(document.getElementById('alertbox'));
                showMessageFromStack();
            }
        }

        function on (type, element, handler) {
            if (document.addEventListener) {
                element.addEventListener(type, handler, false);
            } else {
                element.attachEvent('on' + type, handler);
            }
        }
       
        function off (type, element, handler) {
            if (document.removeEventListener) {
                element.removeEventListener(type, handler, false);
            } else {
                element.detachEvent('on' + type, handler);
            }
        }
       
        // Static functions
       
        AlertBox.alert = function (text, cancelFunction) {
            addMessageToStack({
                  type: 'alert'
                , text: text
                , cancelFunction: cancelFunction
            });
            showMessageFromStack();
        };
       
        AlertBox.confirm = function (text, cancelFunction, okFunction) {
            addMessageToStack({
                  type: 'confirm'
                , text: text
                , cancelFunction: cancelFunction
                , okFunction: okFunction
            });
            showMessageFromStack();
        };

        AlertBox.prompt = function (text, inputDefaultValue, cancelFunction, okFunction) {
            addMessageToStack({
                  type: 'prompt'
                , text: text
                , inputDefaultValue: inputDefaultValue
                , cancelFunction: cancelFunction
                , okFunction: okFunction
            });
            showMessageFromStack();
        };

        // Return constructor

        return AlertBox;
       
    })();
   
    return AlertBox;

});


Файл alertbox.css

/*****************************************************************\
  AlertBox CSS
\*****************************************************************/

#alertbox {
    font-size: 1.4em;
}

#alertbox-opaque-layer {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background: #000000;
    -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)";
    -khtml-opacity: 0.7;
    -moz-opacity: 0.7;
    opacity: 0.7;
    *filter:progid:DXImageTransform.Microsoft.Alpha(opacity = 70);
    z-index: 100000;
}

#alertbox-alert,
#alertbox-confirm,
#alertbox-prompt {
    width: 500px;
    height: 90px;
    position: fixed;
    margin: auto;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 10px;
    background-color: #ffffff;
    border: 1px solid #bbbbbb;
    z-index: 100001;
}

#alertbox-prompt {
    height: 130px;
}

#alertbox-alert-wrapper,
#alertbox-confirm-wrapper,
#alertbox-prompt-wrapper {
    height: 60px;
    overflow-y: auto;
}

#alertbox-prompt-wrapper {
    height: 40px;
}

#alertbox-input-wrapper {
    margin-top: 10px;
    padding: 2px;
    border: 1px solid #bbbbbb;
}

#alertbox-input {
    width: 100%;
    height: 20px;
    line-height: 20px;
    padding: 0;
    border: none;
}

#alertbox-alert-buttons,
#alertbox-confirm-buttons,
#alertbox-prompt-buttons {
    position: absolute;
    width: 186px;
    margin: auto;
    left: 0;
    right: 0;
    bottom: 10px;
}

#alertbox-alert-buttons {
    width: 50px;
}

#alertbox-cancel,
#alertbox-ok {
    display: inline-block;
    width: 50px;
    padding: 3px 9px;
    background-color: #5a8cd3;
    text-align: center;
    color: #ffffff;
    white-space: nowrap;
    cursor: pointer;
}

#alertbox-ok {
    margin-left: 50px;
}

#alertbox-alert-buttons #alertbox-ok {
    margin-left: 0px;
}

#alertbox-cancel:hover,
#alertbox-ok:hover {
    background-color: #29a2fd;
}

Комментариев нет:

Отправить комментарий