jam/js/ui/webui/popupmodal.js

549 lines
20 KiB
JavaScript

'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;i<target.length;i++)
if (target[i]==className) return true;
return false; // throw _iteratorError;
}
}
}
return false;
};
var addClass = function addClass(target, className) {
target.className += ' ' + className;
};
var removeClass = function removeClass(target, className) {
var regex = new RegExp('(?:^|\\s)' + className + '(?!\\S)', 'g');
target.className = target.className.replace(regex, '');
};
var loadCallback = function loadCallback(e) {
var callback = cb_arr[cb_arr.length - 1],
cb_obj = {
e: e,
proceed: false
};
if (e.type == 'click') {
if (hasClass(e.currentTarget.classList, 'btn_pmry')) {
cb_obj.proceed = true;
console.log('Click proceed : true');
} else {
console.log('Click proceed : false');
}
} else if (e.type == 'keydown') {
if (e.keyCode == 13) {
cb_obj.proceed = true;
console.log('Keydown proceed : true');
} else {
console.log('Keydown proceed : false');
}
}
if (!modal_hidden && callback) {
var input_doms = document.getElementById(curr_modal).getElementsByClassName('modal_input');
if (input_doms && input_doms.length==1)
cb_obj.input_value = input_doms[0].value;
else if (input_doms && input_doms.length>1) {
cb_obj.input_value = [];
for(var i=0;i<input_doms.length;i++) cb_obj.input_value.push(input_doms[i].value||input_doms[i].placeholder||'');
} else
cb_obj.input_value = null;
setTimeout(function() {
callback(cb_obj);
}, 350);
}
hideModal();
};
var loadButtons = function loadButtons(popup_type) {
for (var keys in modal_btns) {
if (popup_type == 'alert' && Object.keys(modal_btns).indexOf(keys) == 1) {
continue;
}
var this_btn = modal_btns[keys];
var this_btn_id = undefined;
var btn_dom = document.createElement('a');
btn_dom.id = this_btn_id = this_btn.btn_id + '_' + modal_created;
btn_dom.className = this_btn.btn_class;
btn_dom.innerHTML = this_btn.inner_text;
document.getElementById(curr_modal).getElementsByClassName('modal_buttons')[0].appendChild(btn_dom);
document.getElementById(this_btn_id).addEventListener('click', function(e) {
loadCallback(e);
});
}
};
var keydownEvent = function keydownEvent(e) {
if (e.keyCode == 13 || e.keyCode == 27) {
loadCallback(e);
}
};
var backdropClose = function backdropClose(e) {
loadCallback(e);
};
var enableBackdropClose = function enableBackdropClose() {
document.getElementById('modal_backdrop').removeEventListener('click', backdropClose);
if (config_arr[config_arr.length - 1].backdrop_close) {
document.getElementById(curr_backdrop).addEventListener('click', backdropClose);
}
};
var attachKeyboardEvent = function attachKeyboardEvent() {
document.removeEventListener('keydown', keydownEvent);
if (config_arr[config_arr.length - 1].keyboard) {
document.addEventListener('keydown', keydownEvent);
}
};
var showModal = function showModal() {
modal_hidden = 0;
if (!backdrop_less) {
var backdrop_dom = document.createElement('div');
backdrop_dom.id = curr_backdrop;
backdrop_dom.className = 'modal_backdrop fade';
}
document.getElementById(curr_modal).style.zIndex = 5 + modal_created * 10;
if (modal_created < 2) {
if (!backdrop_less) document.body.appendChild(backdrop_dom);
} else {
for (var i = modal_created - 1; 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='<h3>'+options.label+'</h3>';
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
};
})();