diff --git a/js/ui/webui/popupmodal.js b/js/ui/webui/popupmodal.js new file mode 100644 index 0000000..89e4c1c --- /dev/null +++ b/js/ui/webui/popupmodal.js @@ -0,0 +1,548 @@ +'use strict'; + +/* + + popup.prompt( options={ content: 'x', placeholder:'y'}, function (result) { + console.log(result.proceed,result.input_value) + }); + + New: Multi-input forms! + + popup.prompt( { content: ['Columns','Rows','Variables'], placeholder:[2,2,'a,b']}, function (result) { + console.log(result.proceed,result.input_value) + }); + + popup.confirm( { content : string }, function (result) { + console.log(result.proceed,result.input_value) + }) + + New: The options object gets a close attribute assigned that can be called externally to close the popup. + + Version 1.2.3 + +*/ +function _typeof(obj) { + return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj; +} + +var popup; + +(function() { + var modal_created = 0, + modal_hidden = 0, + cb_arr = [], + config_arr = []; + + var keyboard = true, + backdrop_close = true, + backdrop_less = true, + btn_align = 'left', + modal_size = 'small', + bg_overlay_color = '#000', + modal_effect = 'top'; + + var curr_modal = undefined; + var curr_backdrop = 'modal_backdrop'; + var modal_btns = {}; + + var addRemoveModal = function addRemoveModal(config) { + if (config == true) { + ++modal_created; + } else { + --modal_created; + } + + curr_modal = 'popup_modal_' + modal_created; + }; + + var createModal = function createModal() { + addRemoveModal(true); + + var new_modal = document.createElement('div'); + new_modal.id = 'popup_modal_' + modal_created; + new_modal.className = 'popup_modals fade ' + config_arr[config_arr.length - 1].modal_effect; + + var size = config_arr[config_arr.length - 1].modal_size; + if (typeof size === 'string') { + new_modal.className += ' modal_' + config_arr[config_arr.length - 1].modal_size; + } else if (typeof size === 'number') { + new_modal.style.width = size + 'px'; + } + + var modal_content = document.createElement('div'); + modal_content.className = 'modal_content'; + + var modal_buttons = document.createElement('div'); + modal_buttons.className = 'modal_buttons ' + config_arr[config_arr.length - 1].btn_align; + + new_modal.appendChild(modal_content); + new_modal.appendChild(modal_buttons); + + document.body.appendChild(new_modal); + }; + + var hasClass = function hasClass(target, className) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + var iterator = (typeof Symbol == 'undefined'?'iterator':Symbol.iterator); + try { + for (var _iterator = target[iterator](), + _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var this_class = _step.value; + + if (this_class == className) { + return true; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + // Fallback solution + for(var i=0;i1) { + cb_obj.input_value = []; + for(var i=0;i 0; i--) { + document.getElementById('popup_modal_' + i).style.transform = 'translate(-' + (modal_created - i) * 20 + 'px, -' + (modal_created - i) * 20 + 'px)'; + } + + if (!backdrop_less) document.getElementById(curr_backdrop).style.zIndex = modal_created * 10; + + console.log('popup_modal_' + (modal_created - 1) + ' : hidden'); + } + + if (!backdrop_less) document.getElementById(curr_backdrop).style.background = config_arr[config_arr.length - 1].bg_overlay_color; + + setTimeout(function() { + if (modal_created < 2) { + if (!backdrop_less) addClass(document.getElementById(curr_backdrop), 'in'); + } + + setTimeout(function() { + addClass(document.getElementById(curr_modal), 'in'); + console.log(curr_modal + ' : shown'); + + var input_dom = document.getElementById(curr_modal).getElementsByClassName('modal_input')[0]; + if (input_dom) { + input_dom.focus(); + } + + if (!backdrop_less) enableBackdropClose(); + attachKeyboardEvent(); + }, 15); + }, 15); + }; + + var hideModal = function hideModal() { + if (modal_hidden) return; + modal_hidden = 1; + document.removeEventListener('keydown', keydownEvent); + if (!backdrop_less) document.getElementById('modal_backdrop').removeEventListener('click', backdropClose); + + removeClass(document.getElementById(curr_modal), 'in'); + console.log(curr_modal + ' : hidden',modal_hidden); + + setTimeout(function() { + if (modal_created < 2) { + if (!backdrop_less) removeClass(document.getElementById(curr_backdrop), 'in'); + } + + setTimeout(function() { + if (modal_created == 0) return; + document.body.removeChild(document.getElementById(curr_modal)); + + addRemoveModal(false); + + config_arr.pop(); + cb_arr.pop(); + + if (modal_created < 1) { + if (!backdrop_less) document.body.removeChild(document.getElementById(curr_backdrop)); + } else { + if (!!backdrop_less) { + document.getElementById(curr_backdrop).style.background = config_arr[config_arr.length - 1].bg_overlay_color; + document.getElementById(curr_backdrop).style.zIndex = modal_created * 10; + } + for (var i = modal_created; i > 0; i--) { + document.getElementById('popup_modal_' + i).style.transform = 'translate(-' + (modal_created - i) * 20 + 'px, -' + (modal_created - i) * 20 + 'px)'; + + if (i == modal_created) { + if (document.getElementById(curr_modal).style.removeProperty) { + document.getElementById(curr_modal).style.removeProperty('transform'); + } else { + document.getElementById(curr_modal).style.removeAttribute('transform'); + } + } + } + + console.log('popup_modal_' + modal_created + ' : shown'); + + var input_dom = document.getElementById('popup_modal_' + modal_created).getElementsByClassName('modal_input')[0]; + if (input_dom) { + input_dom.focus(); + } + + if (!backdrop_less) enableBackdropClose(); + attachKeyboardEvent(); + } + }, 15); + }, 15); + }; + + var modal = function modal(type, options, callback) { + var input_len = 500, + default_value, + placeholder = "", + content_dom, + user_ok = undefined, + user_cancel = undefined, + content, + i=0, + config = {}, + content_doms = [], + content_label, + done=false; + if (options && options.label) { + content_label = document.createElement('div'); + content_label.innerHTML='

'+options.label+'

'; + content_label.style['margin-bottom']='5px'; + } + while (!done && (++i)<100) { + try { + default_value=null; + content_dom = document.createElement('div'); + content_dom.className='popup_label'; + if (options && (typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') { + + if (options.content) { + if (Utils.isArray(options.content)) { + content=options.content.shift(); + } else { + content=options.content; + options.content=null; + }; + content_dom.innerHTML = content; + if (!options.content || options.content.length==0) done=true; + } else { + throw 'content not specified'; + } + + if (options.placeholder) { + if (Utils.isArray(options.placeholder)) { + placeholder = options.placeholder.shift(); + } else if (typeof options.placeholder === 'string') { + placeholder = options.placeholder; + } else { + throw 'placeholder is not type string'; + } + } + + if (options.default) { + if (Utils.isArray(options.default)) { + default_value = options.default.shift(); + } else if (typeof options.default === 'string') { + default_value = options.default; + } else { + throw 'default is not type string'; + } + } + + if (options.input_length) { + if (typeof options.input_length === 'number') { + input_len = options.input_length; + } else { + throw 'input_length is not type number'; + } + } + + if (done) { + if (options.keyboard !== undefined) { + if (typeof options.keyboard === 'boolean') { + config.keyboard = options.keyboard; + } else { + throw 'keyboard is not type boolean'; + } + } else { + config.keyboard = keyboard; + } + + if (options.backdrop_close !== undefined) { + if (typeof options.backdrop_close === 'boolean') { + config.backdrop_close = options.backdrop_close; + } else { + throw 'backdrop_close is not type boolean'; + } + } else { + config.backdrop_close = backdrop_close; + } + if (options.default_btns) { + if (_typeof(options.default_btns) === 'object') { + var _options$default_btns = options.default_btns; + user_ok = _options$default_btns.ok; + user_cancel = _options$default_btns.cancel; + } else { + throw 'default_btns is not type object'; + } + } + + modal_btns = { + ok: { + btn_id: 'btn_ok', + btn_class: 'btn btn_pmry', + inner_text: user_ok || 'Ok' + }, + cancel: { + btn_id: 'btn_cancel', + btn_class: 'btn btn_sdry', + inner_text: user_cancel || 'Cancel' + } + }; + + if (options.custom_btns) { + if (_typeof(options.custom_btns) === 'object') { + var ext_count = 0; + + for (var attr in options.custom_btns) { + modal_btns[attr] = { + btn_id: 'btn_extra_' + ++ext_count, + btn_class: 'btn btn_extra', + inner_text: options.custom_btns[attr] + }; + } + } else { + throw 'custom_btns is not type object'; + } + } + + if (options.btn_align) { + if (!(options.btn_align === 'left' || options.btn_align === 'right')) { + throw 'btn_align is not type string and only accepts value of "left" or "right"'; + } + } + config.btn_align = options.btn_align || btn_align; + } + + + + if (options.modal_size) { + if (!(typeof options.modal_size === 'number' || options.modal_size === 'large' || options.modal_size === 'medium' || options.modal_size === 'small')) { + throw 'modal_size is not type number / string and only accepts value of "small", "medium" or "large"'; + } + } + config.modal_size = options.modal_size || modal_size; + + if (options.bg_overlay_color) { + if (typeof options.bg_overlay_color !== 'string') { + throw 'bg_overlay_color is not type string'; + } + } + config.bg_overlay_color = options.bg_overlay_color || bg_overlay_color; + + if (options.effect) { + if (!(options.effect === 'top' || options.effect === 'bottom' || options.effect === 'right' || options.effect === 'left' || options.effect === 'none')) { + throw 'effect is not type string and onlty accepts value of "top", "bottom", "right", "left" or "none"'; + } + } + config.modal_effect = options.effect || modal_effect; + } else { + throw 'No content specified.'; + } + } catch (err) { + console.warn(err + '. Rollback.'); + return; + } + + content_doms.push(content_dom); + + if (type == 'prompt') { + var modal_input = document.createElement('input'); + modal_input.type = 'text'; + modal_input.className = 'modal_input'; + modal_input.placeholder = placeholder; + modal_input.maxLength = input_len; + modal_input.style.width = '100%'; + if (default_value) modal_input.value=default_value; + + content_doms.push(modal_input); + } + } + config_arr.push(config); + + if (callback) { + cb_arr.push(callback); + } else { + cb_arr.push(null); + } + + createModal(); + + if (content_label) + document.getElementById(curr_modal).getElementsByClassName('modal_content')[0].appendChild(content_label); + var form_wrapper = document.createElement('div'); + form_wrapper.className='popup_form'; + document.getElementById(curr_modal).getElementsByClassName('modal_content')[0].appendChild(form_wrapper); + content_doms.forEach(function (dom) { + form_wrapper.appendChild(dom); + }) + + loadButtons(type); + options.close = function () { hideModal() }; // external close request + showModal(); + /* jquery-ui breaks panel! draggable disables + $('.modal_buttons').attr('draggable','true'); + $('#'+curr_modal).draggable({cancel: '.scrollable'}); + $('.modal_content').addClass('scrollable'); + */ + + }; + + var alert = function alert(options, callback) { + modal('alert', options, callback); + }; + + var confirm = function confirm(options, callback) { + modal('confirm', options, callback); + }; + + var prompt = function prompt(options, callback) { + modal('prompt', options, callback); + }; + + var custom = function prompt(options, callback) { + modal('custom', options, callback); + }; + + popup = { + alert: alert, + prompt: prompt, + confirm: confirm, + custom: custom + }; + +})();