| 12 |
- /* Copyright 2021 Carlos A. (https://github.com/dealfonso); License: http://www.apache.org/licenses/LICENSE-2.0 */
- (function(exports){"use strict";if(typeof exports==="undefined"){var exports=window}exports.powerButtons=function(t,n=null,e=null){let i=null;let o=[];let s={};function l(t){for(let e in PowerButtons.actionsRegistered){if(t.toLocaleLowerCase()===e.toLocaleLowerCase()){return e}}return null}if(typeof t==="string"){i=l(t);if(i===null){o=document.querySelectorAll(t);if(o.length===0){console.error(`Parameter ${t} is neither the name of a registered plugin nor a valid selector`);return}if(arguments.length>2){console.warn(`Ignoring extra parameters`)}s=n}else{let t=false;if(typeof n==="string"){o=document.querySelectorAll(n);t=true}else if(n instanceof HTMLElement){o=[n];t=true}else if(n.length!==undefined){t=true;for(let e in n){if(!(n[e]instanceof HTMLElement)){t=false;break}}if(t){o=n}}if(!t){console.error(`Parameter ${n} is neither a valid selector, a list of elements or an HTMLElement`);return}s=e}}else if(t instanceof HTMLElement){o=[t]}else if(t.length!==undefined){for(let e in t){if(!(t[e]instanceof HTMLElement)){console.error(`Parameter ${t} is neither a valid selector, a list of elements or an HTMLElement`);return}}o=t}else{console.error(`Parameter ${t} is neither a valid selector, a list of elements or an HTMLElement`);return}if(s===null){s={}}if(typeof s!=="object"){console.error(`Options parameter must be an object`);return}if(i!==null){let t=PowerButtons.actionsRegistered[i];for(let e of o){t.initialize(e,s)}}else{PowerButtons.discover(o,s)}};exports.powerButtons.version="2.1.0";exports.powerButtons.plugins=function(){return Object.keys(PowerButtons.actionsRegistered)};exports.powerButtons.discoverAll=function(){PowerButtons.discoverAll()};exports.powerButtons.discover=function(e,t){PowerButtons.discover(e,t)};if(document.addEventListener!==undefined){document.addEventListener("DOMContentLoaded",function(e){PowerButtons.discoverAll()})}if(exports.$!==undefined){exports.$.fn.powerButtons=function(e,t={}){exports.powerButtons(e,this,t);return this};exports.$.fn.powerButtons.version=exports.powerButtons.version;exports.$.fn.powerButtons.plugins=exports.powerButtons.plugins}function pascalToSnake(e){return e.replace(/[A-Z]/g,e=>`_${e.toLowerCase()}`).replace(/^_*/,"")}function pascalToKebab(e){return e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`).replace(/^-*/,"")}function snakeCaseToCamel(e){return e.replace(/-([a-z])/g,e=>e[1].toUpperCase())}function pascalToCamel(e){return e.charAt(0).toLowerCase()+e.slice(1)}function CamelToCamel(e){return e.charAt(0).toUpperCase()+e.slice(1)}function isElement(e){return e instanceof Element||e instanceof HTMLDocument}function parseBoolean(e){if(typeof e==="boolean"){return e}if(typeof e==="string"){e=e.toLowerCase();if(e==="true"||e==="yes"||e==="1"){return true}return false}return!!e}function createTag(e,t={},n=null){let i=e.split("#");let o=null;if(i.length==1){e=i[0]}else{i[1]=i[1].split(".");o=i[1][0];e=[i[0],...i[1].slice(1)].join(".")}let s=e.split(".");e=s[0];if(e===""){e="div"}if(typeof t==="string"){n=t;t={}}if(n!==null){t.innerHTML=n}if(o!==null){t.id=o}t.className=[t.className,...s.slice(1)].filter(function(e){return`${e}`.trim()!==""}).join(" ");let l=document.createElement(e);for(let e in t){if(l[e]!==undefined){l[e]=t[e]}else{l.setAttribute(e,t[e])}}return l}function appendToElement(e,...t){let n=t.filter(e=>e!==null&&e!==undefined);e.append(...n);return e}function searchForm(e){let t=null;if(e!==null){t=document.forms[e];if(t===undefined){t=document.querySelector(e);if(t===null){console.warn(`form ${e} not found`)}}}if(t!==null){if(t.tagName.toLowerCase()!=="form"){console.warn(`form ${e} is not a form`)}}return t}function getValueWithJavascriptSupport(value,context=null){if(typeof value==="function"){return value.bind(context)}if(typeof value==="string"){let internalValue=value.trim();if(internalValue.startsWith("javascript:")){try{let f=internalValue.substring(11);value=function(){return eval(f)}.bind(context)}catch(e){console.error(`Error executing javascript code ${internalValue.substring(11)}, error: ${e}`);value=null}}}return value}function promiseForEvent(e,t){let n=null;let i=new Promise(e=>{n=e});let o=function(){e.removeEventListener(t,o);n()};e.addEventListener(t,o);return i}function isEmpty(e){if(e===null||e===undefined){return true}if(e instanceof Array){return e.length===0}if(e instanceof Object){return Object.keys(e).length===0}if(typeof e==="string"){return e.trim()===""}return false}class DialogLegacy{DEFAULTS={message:"Main message",buttonCount:2};constructor(e={},t=null,n=null){this.options={...this.DEFAULTS,...e};this.buttonCount=this.options.buttons.length;this.options.buttons=["Accept","Cancel"];this.result=null;this.onButton=t;this.onHidden=n}dispose(){}show(e=null,t=null){if(e!==null){this.onButton=e}if(t!==null){this.onHidden=t}switch(this.buttonCount){case 0:case 1:alert(this.message);this.result=0;break;case 2:this.result=confirm(this.options.message)?0:1;break;default:throw`Unsupported button count ${this.buttonCount}`}if(this.onButton!==null){this.onButton(this.result,{button:this.result,text:this.options.buttons[this.result]},null)}if(this.onHidden!==null){this.onHidden(this.result,{button:this.result,text:this.options.buttons[this.result]},null)}}}class Dialog{static create(e={},t=null,n=null){if(exports.bootstrap===undefined||exports.bootstrap.Modal===undefined){return new DialogLegacy(e,t,n)}if(e.selector!==undefined&&e.selector!==null||e.dialogFunction!==undefined&&e.dialogFunction!==null){throw new Error("not implemented, yet")}return new Dialog(e,t,n)}DEFAULTS={title:"Title",message:"Main message",customContent:null,buttons:["Accept"],buttonClasses:["btn-primary","btn-secondary"],buttonPanelClasses:["text-end"],escapeKeyCancels:true,header:true,footer:true,body:true,close:true};dialog=null;options=null;modal=null;onButton=null;result=null;onHidden=null;onButton=null;constructor(e={},t=null,n=null){if(exports.bootstrap===undefined||exports.bootstrap.Modal===undefined){throw new Error("Bootstrap is required to use this class")}this.options={...this.DEFAULTS,...e};let i=[];for(let t=0;t<this.options.buttons.length;t++){let e=this.options.buttons[t];if(typeof e==="string"){e={text:e}}else{if(e.text===undefined){e.text=`Button ${t}`}}if(e.class===undefined){e.class=this.options.buttonClasses[Math.min(t,this.options.buttonClasses.length-1)]}i.push(e)}this.options.buttons=i;this.dialog=null;this.modal=null;this.result=null;this.onButton=t;this.onHidden=n;this._hiddenHandler=this._hiddenHandler.bind(this)}_hiddenHandler(){this.dialog.removeEventListener("hidden.bs.modal",this._hiddenHandler);if(this.onHidden!==null){if(this.result!==null&&this.result>=0){this.onHidden(this.result,{button:this.result,text:this.options.buttons[this.result]})}else{this.onHidden(this.result,null)}}}dispose(){if(this.modal!==null){this.modal.dispose();this.modal=null}this.dialog.remove();this.dialog=null}show(e=null,t=null){if(this.dialog===null){this.dialog=this._build_dialog(this.options)}if(this.modal===null){this.modal=new bootstrap.Modal(this.dialog,{backdrop:this.options.escapeKeyCancels?true:"static",keyboard:this.options.escapeKeyCancels})}this.dialog.addEventListener("hidden.bs.modal",this._hiddenHandler);this.result=null;if(e!==null){this.onButton=e}if(t!==null){this.onHidden=t}this.modal.show();return promiseForEvent(this.dialog,"shown.bs.modal")}hide(){this.modal.hide();return promiseForEvent(this.dialog,"hidden.bs.modal")}_handleButton(e,t,n){this.result=e;let i=true;if(this.onButton!==null){i=!(this.onButton(e,t,n)===false)}if(i){this.hide()}}_build_dialog(o={}){let e=null;let t=null;if(parseBoolean(o.close)){t=createTag("button.close.btn-close",{type:"button","aria-label":"Close"});t.addEventListener("click",()=>this._handleButton(-1,null,t))}if(parseBoolean(o.header)){e=createTag(".modal-header");if(o.title!==null){e.append(appendToElement(createTag(".modal-title"),appendToElement(createTag("h5",o.title))))}if(parseBoolean(o.close)){e.append(t)}}let s=[];if(o.buttons!==null){for(let i=0;i<o.buttons.length;i++){let e=o.buttons[i];let t=e.class.split(" ").map(e=>e.trim()).filter(e=>e!=="").join(".");if(o.footer===false){t+=".mx-1"}if(t!==""){t="."+t}let n=createTag("button.btn"+t+".button"+i,{type:"button"},e.text);n.addEventListener("click",function(){this._handleButton(i,e,n);if(e.handler!==undefined&&e.handler!==null){e.handler(i,e,n)}}.bind(this));s.push(n)}}let n=null;if(parseBoolean(o.footer)){n=appendToElement(createTag(".modal-footer"),...s)}let i=null;if(parseBoolean(o.body)){i=createTag(".modal-body");if(e===null){if(parseBoolean(o.close)){i.append(appendToElement(createTag(".text-end"),t))}}if(o.message!==null){i.append(createTag("p.message.text-center",o.message))}if(o.customContent!==null){i.append(createTag(".custom-content.mx-auto",o.customContent))}if(n===null){let e=o.buttonPanelClasses.map(e=>e.trim()).filter(e=>e!=="").join(".");if(e!==""){e="."+e}appendToElement(i,appendToElement(createTag(".buttons"+e),...s))}}let l=appendToElement(createTag(".modal.fade",{tabindex:"-1",role:"dialog","aria-hidden":"true","data-keyboard":"false"}),appendToElement(createTag(".modal-dialog.modal-dialog-centered",{role:"document"}),appendToElement(createTag(".modal-content"),e,i,n)));return l}}function confirmDialog(e,t="this action needs confirmation",n=null,i=null,o=true){let s=new Dialog({title:t,message:e,buttons:[{text:"Cancel",class:"btn-secondary",handler:i},{text:"Confirm",class:"btn-primary",handler:n}],escapeKeyCancels:o});s.show();return s}function alertDialog(e,t="Alert",n=null){let i=new Dialog({title:t,message:e,buttons:[{text:"Accept",class:"btn-primary",handler:n}],escapeKeyCancels:true});i.show();return i}function loadingDialog(e,t=null,n=null){if(typeof t==="function"){n=t;t=null}let i=new Dialog({title:null,message:e,buttons:[{text:"Cancel",class:"btn-primary"}],customContent:t,escapeKeyCancels:false,close:false,header:false,footer:false},n);i.show();return i}if(exports.powerButtons.utils===undefined){exports.powerButtons.utils={}}Object.assign(exports.powerButtons.utils,{confirmDialog:confirmDialog,alertDialog:alertDialog,loadingDialog:loadingDialog});class PowerButtons{static actionsRegistered={};static registerAction(e){this.actionsRegistered[e.NAME.toLowerCase()]=e;if(exports.powerButtons===undefined){exports.powerButtons={}}if(exports.powerButtons.defaults===undefined){exports.powerButtons.defaults={}}exports.powerButtons.defaults[e.NAME.toLowerCase()]=Object.assign({},e.DEFAULTS)}static getActionSettings(e,t){if(this.actionsRegistered[e.NAME.toLowerCase()]===undefined){console.error(`The action ${e.NAME} is not registered`);return{}}let n={};if(exports.powerButtons!==undefined&&exports.powerButtons.defaults!==undefined&&exports.powerButtons.defaults[e.NAME.toLowerCase()]!==undefined){n=exports.powerButtons.defaults[e.NAME.toLowerCase()]}return Object.assign({},e.DEFAULTS,n,t)}static addAction(e,t={}){let n=PowerButtons.addActionSupport(e);n.appendAction(t)}static addActionSupport(e){if(e._powerButtons===undefined){e._powerButtons=new PowerButtons(e)}else{e._powerButtons.reset()}return e._powerButtons}el=null;current_action=0;actions=[];back_onclick=null;constructor(e){e._powerButtons=this;this.el=e;this.current_action=0;this.actions=[];this.back_onclick=null;if(e.onclick!==undefined&&e.onclick!==null){this.back_onclick=e.onclick;e.onclick=null}e.addEventListener("click",this.handlerClick.bind(this))}appendAction(e={}){if(e.type===undefined){throw"The type of the action is mandatory"}this.actions.push(e)}handlerClick(e){if(this.current_action>=this.actions.length){this.current_action=0;if(typeof this.back_onclick==="function"){if(!this.back_onclick()){e.preventDefault()}}return}let t=this.actions[this.current_action];e.preventDefault();e.stopImmediatePropagation();let n=function(){this.current_action++;if(this.current_action>=this.actions.length){if(this.el.click!==undefined){this.el.click()}else{this.el.dispatchEvent(new Event(e.type,e))}}else{this.el.dispatchEvent(new Event(e.type,e))}}.bind(this);let i=this.constructor.actionsRegistered[t.type];if(i===undefined){throw`The action ${t.type} is not registered`}i.execute(this.el,t,n,()=>this.reset())}reset(){this.current_action=0}static discoverAll(){Object.entries(this.actionsRegistered).forEach(([e,t])=>{t.discoverAll()})}static discover(n,i={}){Object.entries(this.actionsRegistered).forEach(([e,t])=>{t.discover(n,i)})}}class Action{static NAME=null;static register(){PowerButtons.registerAction(this)}static DEFAULTS={};static extractOptions(n,i=null,o=null){if(i===null){i=this.NAME.toLowerCase()}if(o===null){o={};o[i]=i}let s={};for(let t in this.DEFAULTS){let e=t;if(o[e]!==undefined){e=o[e]}else{e=i+CamelToCamel(e)}if(n.dataset[e]!==undefined){s[t]=n.dataset[e]}}return s}static initialize(e,t={}){PowerButtons.addAction(e,Object.assign({type:this.NAME.toLowerCase()},t))}static discoverAll(){let e=this.NAME.toLowerCase();this.discover(document.querySelectorAll(`[data-${e}]`))}static discover(e,n={},i=true){if(e.length===undefined){e=[e]}let o=this.NAME.toLowerCase();for(let t of e){if(i&&t._powerButtons!==undefined&&t._powerButtons._discover!==undefined&&t._powerButtons._discover.indexOf(o)!==-1){continue}if(t.dataset[o]===undefined){continue}let e=Object.assign(this.extractOptions(t,o),n);this.initialize(t,e);if(t._powerButtons!==undefined){if(t._powerButtons._discover===undefined){t._powerButtons._discover=[]}if(!t._powerButtons._discover.includes(o)){t._powerButtons._discover.push(o)}}}}static execute(e,t,n,i){throw new Error("The execute method must be implemented by the derived class")}}class ActionVerify extends Action{static NAME="Verify";static DEFAULTS={verify:null,form:null,verified:null,notVerified:"The condition for this action is not met",customContentVerified:null,customContentNotVerified:null,titleNotVerified:"The action requires verification",titleVerified:null,buttonAccept:"Accept",buttonClose:false,escapeKey:true,header:true,footer:true};static execute(el,options,onNextAction,onCancelActions){let settings=PowerButtons.getActionSettings(this,options);let result=null;let bindObject=searchForm(settings.form);if(bindObject===null){bindObject=document}try{if(typeof settings.verify==="function"){result=settings.verify.bind(bindObject)()}else if(typeof settings.verify==="string"){result=function(){return eval(settings.verify)}.bind(bindObject)()}else{result=parseBoolean(settings.verify)}}catch(e){console.error("Error executing verification function",e);result=false}let dialog=null;let onVerificationSuccess=onNextAction;let onVerificationFailure=onCancelActions;if(result){if(settings.verified!==null||settings.customContentVerified!==null||settings.titleVerified!==null){dialog=Dialog.create({title:settings.titleVerified,message:settings.verified,customContent:settings.customContentVerified,buttons:[settings.buttonAccept],escapeKeyCancels:settings.escapeKey,close:settings.buttonClose},null,function(e){if(onVerificationSuccess!==null){onVerificationSuccess()}})}}else{if(settings.notVerified!==null||settings.customContentNotVerified!==null||settings.titleNotVerified!==null){dialog=Dialog.create({title:settings.titleNotVerified,message:settings.notVerified,customContent:settings.customContentNotVerified,buttons:[settings.buttonAccept],escapeKeyCancels:settings.escapeKey,close:settings.buttonClose},null,function(e){if(onVerificationFailure!==null){onVerificationFailure()}})}}if(dialog!==null){dialog.show()}else{if(result){if(onVerificationSuccess!==null){onVerificationSuccess()}}else{if(onVerificationFailure!==null){onVerificationFailure()}}}}}ActionVerify.register();class ActionConfirm extends Action{static NAME="Confirm";static DEFAULTS={confirm:"Please confirm this action",customContent:null,title:"The action requires confirmation",buttonConfirm:"Confirm",buttonCancel:"Cancel",buttonClose:true,escapeKey:true};static extractOptions(e,t=null,n=null){let i=super.extractOptions(e,t,n);if(i.confirm.trim()==""){delete i.confirm}return i}static execute(e,t,n,i){let o=PowerButtons.getActionSettings(this,t);let s=Dialog.create({title:o.title,message:o.confirm,customContent:o.customContent,buttons:[o.buttonConfirm,o.buttonCancel],escapeKeyCancels:o.escapeKey,close:o.buttonClose},null,function(e){if(e===0){if(n!==null){n()}}else{if(i!==null){i()}}});s.show()}}ActionConfirm.register();class ActionAsyncTask extends Action{static NAME="AsyncTask";static DEFAULTS={task:null,message:"Please wait...",customContent:null,title:null,buttonCancel:"Cancel",cancel:null,header:true,footer:true};static extractOptions(e,t=null,n=null){return super.extractOptions(e,t,{task:"asynctask"})}static execute(el,options,onNextAction,onCancelActions){let settings=PowerButtons.getActionSettings(this,options);if(settings.task===null){console.error("The task to execute cannot be null");return}let task=null;if(typeof settings.task==="string"){task=async function(){return await eval(settings.task)}}else if(typeof settings.task==="function"){task=settings.task}else{console.error("The task to execute must be either a string or a function");return}let buttons=[];let cancelHandler=null;if(settings.cancel!==null){buttons=[settings.buttonCancel];if(typeof settings.cancel==="string"){cancelHandler=function(){eval(settings.cancel)}}else if(typeof settings.cancel==="function"){cancelHandler=settings.cancel}else{console.error("The cancel handler must be either a string or a function")}}let dialog=Dialog.create({title:settings.title,message:settings.message,customContent:settings.customContent,buttons:buttons,escapeKeyCancels:false,close:false,header:options.header!==undefined?settings.header:settings.title!==null&&settings.title!="",footer:options.footer!==undefined?settings.footer:cancelHandler!==null},function(){cancelHandler();onCancelActions()},function(e){if(onNextAction!==null){onNextAction()}});dialog.show().then(function(){task().finally(function(){dialog.hide()})})}}ActionAsyncTask.register();class ActionShowMessage extends Action{static NAME="ShowMessage";static DEFAULTS={showmessage:"This is a message",customContent:null,title:null,buttonAccept:"Accept",escapeKey:true,buttonClose:true,header:true,footer:true};static execute(e,t,n,i){let o=PowerButtons.getActionSettings(this,t);let s=Dialog.create({title:o.title,message:o.showmessage,customContent:o.customContent,buttons:[o.buttonAccept],escapeKeyCancels:o.escapeKey,close:o.buttonClose,header:t.header!==undefined?o.header:o.title!==null&&o.title!="",footer:t.footer!==undefined?o.footer:o.buttonAccept!==null&&o.buttonAccept!=""},null,function(e){if(n!==null){n()}});s.show()}}ActionShowMessage.register();class ActionFormset extends Action{static NAME="Formset";static DEFAULTS={form:null,fields:{}};static extractOptions(n,i=null,e=null){let t=super.extractOptions(n,i,{form:"formset"});let o={};for(let t in n.dataset){if(t.startsWith(i)){let e=t.substring(i.length);if(e===""){continue}if(e[0]!==e[0].toUpperCase()){continue}e=e.toLocaleLowerCase();o[e]=n.dataset[t]}}if(t.fields===undefined){t.fields={}}Object.assign(t.fields,o);return t}static execute(e,t,n,i){let o=PowerButtons.getActionSettings(this,t);let s=null;let l=[];let r=[];if(o.form==""){if(e.form!==null){s=e.form}else{r=Array.from(document.querySelectorAll("input")).filter(e=>e.form===null)}}else{s=searchForm(o.form);if(s===null){console.error(`Form not found ${o.form}`);return}}if(s!==null){r=Array.from(s.elements)}r.forEach(e=>{if(e.name!==""){l[e.name.toLocaleLowerCase()]=e}if(e.id!==""){l[e.id.toLocaleLowerCase()]=e}});for(let n in o.fields){if(l[n]!==undefined){let t=o.fields[n];let e=getValueWithJavascriptSupport(t,s!==null?s:l);if(typeof e==="function"){try{e=e()}catch(e){console.error(`Error executing ${t}`,e);continue}}l[n].value=e}}n()}}ActionFormset.register();class ActionFormButton extends Action{static NAME="FormButton";static DEFAULTS={formbutton:null,method:"post",formClass:"formbutton",convertCase:"none",formId:null,fields:{}};static extractOptions(n,i=null,e=null){let o=super.extractOptions(n,i,e);let s={};i=i+"Field";for(let t in n.dataset){if(t.startsWith(i)){let e=t.substring(i.length);if(e===""){continue}if(e[0]!==e[0].toUpperCase()){continue}switch(o.convertCase){case"kebab":e=pascalToKebab(e);break;case"snake":e=pascalToSnake(e);break;case"camel":e=pascalToCamel(e);break;case"pascal":break}s[e]=n.dataset[t]}}if(o.fields===undefined){o.fields={}}Object.assign(o.fields,s);return o}static initialize(e,t={}){let n=PowerButtons.getActionSettings(this,t);let i=document.createElement("form");i.method=n.method;if(!isEmpty(n.formbutton)){i.action=n.formbutton}if(n.formId!==null){i.id=n.formId}let o=n.formClass.split(" ");for(var s=0;s<o.length;s++){if(!isEmpty(o[s])){i.classList.add(o[s])}}e.type="submit";let l={};for(let e in n.fields){l[e]=getValueWithJavascriptSupport(n.fields[e],i)}let r={};for(let t in l){let e=document.createElement("input");e.type="hidden";e.name=t;if(typeof l[t]==="function"){e.value="";r[t]=l[t]}else{e.value=l[t]}i.appendChild(e)}e.parentNode.replaceChild(i,e);i.appendChild(e);if(Object.keys(r).length>0){n.fields=r;n._formObject=i;super.initialize(e,n)}}static execute(e,t,n,i){let o=PowerButtons.getActionSettings(this,t);let s=false;for(let t in o.fields){try{let e=o.fields[t]();o._formObject[t].value=e}catch(e){console.error(`Error obtaining value for field ${t}: ${e}`);s=true}}if(s){i()}else{n()}}}ActionFormButton.register()})(window);
|