381 lines
10 KiB
JavaScript
381 lines
10 KiB
JavaScript
import { Webcomponent } from "./webcomponent.js";
|
|
|
|
const config = {
|
|
item: ".tab-item",
|
|
content: ".tab-content"
|
|
};
|
|
|
|
class UiPopup extends Webcomponent {
|
|
constructor() {
|
|
super();
|
|
|
|
this.fetch_template();
|
|
this.message = this.querySelector('.message');
|
|
this.title = this.querySelector('.title');
|
|
|
|
if (!this.message) {
|
|
this.message = document.createElement("div");
|
|
}
|
|
|
|
if (!this.title) {
|
|
this.title = document.createElement("div");
|
|
}
|
|
|
|
this.replaceVarsPlaceholder().attach().render();
|
|
|
|
this.init();
|
|
this.handleOptions();
|
|
}
|
|
|
|
handleOptions() {
|
|
if ( this.options ) {
|
|
if ( ! this.options['skip-keys'] ) {
|
|
document.addEventListener('keyup', function(e) {
|
|
if ( this.visible() ) {
|
|
let trigger, ev;
|
|
|
|
e.preventDefault();
|
|
|
|
// There's no real value in checking if the popup is shown or not.
|
|
switch ( e.keyCode ) {
|
|
// RETURN
|
|
case 13:
|
|
trigger = this.querySelector('[action="confirm"]');
|
|
ev = new CustomEvent('click', { trigger: trigger } );
|
|
|
|
trigger.dispatchEvent(ev);
|
|
break;
|
|
|
|
// ESC
|
|
case 27:
|
|
trigger = this.querySelector('[action="close"]');
|
|
ev = new CustomEvent('click', { trigger: trigger } );
|
|
|
|
trigger.dispatchEvent(ev);
|
|
break;
|
|
}
|
|
}
|
|
}.bind(this));
|
|
}
|
|
}
|
|
}
|
|
|
|
init() {
|
|
document.addEventListener('keyup', function(e) {
|
|
if ( this.visible() ) {
|
|
let trigger, ev, action;
|
|
|
|
e.preventDefault();
|
|
|
|
// There's no real value in checking if the popup is shown or not.
|
|
switch ( e.keyCode ) {
|
|
case 13: // RETURN
|
|
action = "confirm";
|
|
break;
|
|
|
|
case 27: // ESC
|
|
action = "close";
|
|
break
|
|
}
|
|
|
|
if (action) {
|
|
trigger = this.querySelector(`[action="${action}"]`);
|
|
|
|
if ( trigger ) {
|
|
ev = new CustomEvent('click', {trigger: trigger});
|
|
|
|
trigger.dispatchEvent(ev);
|
|
}
|
|
else {
|
|
this.hide();
|
|
}
|
|
}
|
|
}
|
|
}.bind(this));
|
|
}
|
|
|
|
attach() {
|
|
let triggers = document.querySelectorAll('[ui-popup]');
|
|
|
|
if ( triggers.length ) {
|
|
triggers.forEach(function(item) {
|
|
let trigger_args = this._parseTriggerArguments(item);
|
|
|
|
if ( trigger_args.name === this.getAttribute('name') ) {
|
|
item.addEventListener('click', this.triggerAction.bind(this, item, trigger_args));
|
|
}
|
|
|
|
this.options = trigger_args.options;
|
|
}.bind(this));
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
render() {
|
|
this.querySelectorAll('[action]:not(form)').forEach(function(element) {
|
|
element.addEventListener("click", this.action.bind(this, element), false);
|
|
}.bind(this));
|
|
|
|
this.hide();
|
|
}
|
|
|
|
action(element, e) {
|
|
if ( ! element.attributes.action ) {
|
|
throw "A button was clicked onto which no action was bound.";
|
|
}
|
|
|
|
switch(element.attributes.action.value) {
|
|
case "confirm":
|
|
case "yes":
|
|
case "ok":
|
|
let retval = this.actionFollowLink(element) ||
|
|
this.actionClickButton(element);
|
|
|
|
if (! retval) {
|
|
retval = this.actionSendForm(element) ||
|
|
this.actionSendForm(this.trigger) ||
|
|
this.actionSendForm(this.querySelector('[slot="message"] form')) ||
|
|
this.actionSendForm(this.querySelector('[slot="title"] form')) ||
|
|
this.actionSendForm(this.querySelector('[slot="buttons"] form'));
|
|
|
|
if ( ! retval ) {
|
|
throw "No action to trigger automatically on Popup confirmation.";
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case "cancel":
|
|
case "no":
|
|
case "close":
|
|
this.hide();
|
|
break;
|
|
}
|
|
|
|
this.dispatchEvent(new CustomEvent('action:' + element.attributes.action.value));
|
|
this.trigger.dispatchEvent(new CustomEvent('action:' + element.attributes.action.value));
|
|
|
|
if ( element.getAttribute("action") ) {
|
|
e.preventDefault();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
hide() {
|
|
this.classList.remove('visible');
|
|
}
|
|
|
|
show() {
|
|
this.classList.add('visible');
|
|
}
|
|
|
|
visible() {
|
|
return this.classList.contains('visible');
|
|
}
|
|
|
|
actionFollowLink(element) {
|
|
|
|
//if ( element.getAttribute('follow-link') !== null ) {
|
|
// Automatically redirect to given location if it exists.
|
|
if ( this.trigger.tagName === "A" ) {
|
|
let href = this.trigger.getAttribute('href');
|
|
|
|
if ( href ) {
|
|
window.location = href;
|
|
|
|
return true;
|
|
}
|
|
}
|
|
//}
|
|
|
|
return false;
|
|
}
|
|
|
|
actionClickButton(element) {
|
|
|
|
//if ( element.getAttribute('button-click') !== null ) {
|
|
let tag = this.trigger.tagName.toLowerCase();
|
|
|
|
// Automatically redirect to given location if it exists.
|
|
if ( ( tag === "button" || tag === "input" ) && this.trigger.getAttribute("type").toLowerCase() === "submit") {
|
|
this.pause = true;
|
|
|
|
this.trigger.click();
|
|
|
|
this.pause = false;
|
|
|
|
return true;
|
|
}
|
|
//}
|
|
|
|
return false;
|
|
}
|
|
|
|
actionSendForm(element) {
|
|
if ( ! element ) {
|
|
return false;
|
|
}
|
|
|
|
//if ( element.getAttribute('send-form') !== null ) {
|
|
//let form = this.trigger.tagName === "FORM" ? this.trigger : this.trigger.closest('FORM');
|
|
let form = element.tagName === "FORM" ? element : element.closest('FORM');
|
|
|
|
if ( form ) {
|
|
form.addEventListener("submit", e => this.hide, { once: true });
|
|
|
|
let submitBtn = form.querySelector("button[type='submit']");
|
|
|
|
if (submitBtn) {
|
|
submitBtn.click();
|
|
}
|
|
else {
|
|
form.submit();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
//}
|
|
}
|
|
|
|
triggerAction(item, args, e) {
|
|
if (this.pause) {
|
|
return false;
|
|
}
|
|
|
|
e.preventDefault();
|
|
|
|
this.trigger = item;
|
|
|
|
args.vars && Object.keys(args.vars).map(function(objectKey, index) {
|
|
let element = Array.prototype.slice.call( this.message.querySelectorAll(`.${objectKey}`) ).concat(Array.prototype.slice.call(this.title.querySelectorAll(`.${objectKey}`)));
|
|
|
|
element.length ? element.forEach(function(item) {
|
|
item.innerHTML = args.vars[objectKey];
|
|
}) : ( function() {
|
|
console.warn(`Variable '${objectKey}' could not be found within popup's message`);
|
|
} )();
|
|
}.bind(this));
|
|
|
|
if ( args.options ) {
|
|
if (args.options['clear_input']) {
|
|
let skipInput = args.options['clear_input']['skip'] ? args.options['clear_input']['skip'] : [];
|
|
|
|
this.querySelectorAll(`input,textarea`).forEach(function(f) {
|
|
if (! skipInput.includes(f.name)) {
|
|
f.value = "";
|
|
}
|
|
});
|
|
}
|
|
|
|
args.options['input'] && Object.keys(args.options['input']).forEach(
|
|
key => this.querySelectorAll(`[name="${key}"]`).forEach(function(f) {
|
|
console.log(f);
|
|
f.value = args.options['input'][key];
|
|
f.dispatchEvent(new Event("change"));
|
|
})
|
|
);
|
|
|
|
args.options['form_url'] && Object.keys(args.options['form_url']).forEach(
|
|
key => {
|
|
let form = this.querySelector(`form${key}`);
|
|
|
|
if (form) {
|
|
form.setAttribute('action', args.options['form_url'][key]);
|
|
}
|
|
else {
|
|
console.warn(`Form selector '${key}' could not be found within popup.`);
|
|
}
|
|
}
|
|
);
|
|
}
|
|
|
|
this.show();
|
|
|
|
e.stopPropagation();
|
|
return true;
|
|
}
|
|
|
|
replaceVarsPlaceholder() {
|
|
let setVar = function(match, varname) {
|
|
let element = document.createElement('span');
|
|
element.classList.add('variable', varname);
|
|
|
|
return element.outerHTML;
|
|
};
|
|
|
|
this.message.innerHTML = this.message.innerHTML.replace(/{\$(.*?)}/g, setVar);
|
|
this.title.innerHTML = this.title.innerHTML.replace(/{\$(.*?)}/g, setVar);
|
|
|
|
return this;
|
|
}
|
|
|
|
get trigger() {
|
|
return this._trigger;
|
|
}
|
|
|
|
set trigger(value) {
|
|
return this._trigger = value;
|
|
}
|
|
|
|
get pause() {
|
|
return this._pause;
|
|
}
|
|
|
|
set pause(value) {
|
|
return this._pause = value;
|
|
}
|
|
|
|
get message() {
|
|
return this._message;
|
|
}
|
|
|
|
set message(value) {
|
|
return this._message = value;
|
|
}
|
|
|
|
get title() {
|
|
return this._title;
|
|
}
|
|
|
|
set title(value) {
|
|
return this._title = value;
|
|
}
|
|
|
|
get action_func() {
|
|
return this._action_func;
|
|
}
|
|
|
|
set action_func(value) {
|
|
return this._action_func = value;
|
|
}
|
|
|
|
_parseTriggerArguments(item) {
|
|
let attr = item.getAttribute('ui-popup').trim();
|
|
|
|
if ( attr.charAt(0) === '{' ) {
|
|
try {
|
|
return JSON.parse(attr);
|
|
}
|
|
catch(error) {
|
|
console.error("Popup trigger failed on JSON parsing of " + attr + " from object:", item);
|
|
}
|
|
}
|
|
else if ( typeof attr === "string" && attr.length ) {
|
|
return {
|
|
name: attr
|
|
};
|
|
}
|
|
else {
|
|
throw "A popup name must be given to attach this object.";
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
export { UiPopup }
|