quick-modal
Version:
Generate a custom modal quickly
1 lines • 7.93 kB
JavaScript
class QuickModal{constructor(t,e){for(this._parameters={darkenBackground:!0,isForm:!0,keepHidden:!1,form:{action:"path/to/your/form",method:"POST",id:"formId",classes:[],submit:"OK"},closeText:"OK",classes:[],attributes:{},header:"<div>QuickModal</div>",body:[{type:"text",text:'This is a basic QuickModal. See the <a href="https://zenoo.github.io/quickModal/">documentation</a> for more.',tag:"p",classes:[]}],footer:[],document:window.document,afterOpen:()=>{},beforeClose:()=>{},onSubmit:()=>{}},this._parameters="string"==typeof t?{...this._parameters,isForm:!1,header:"<div>"+t+"</div>",body:[{type:"text",text:e,tag:"p",classes:[]}],footer:[]}:{...this._parameters,...t},this.id=0;this._parameters.document.getElementById("quick-modal-"+this.id);)this.id++;this._elements={hider:null,body:null,footerLinks:null},this._build(),this._listen(),this.open()}_build(){this._buildFrame(),this._parameters.darkenBackground&&(this._elements.hider=this._parameters.document.createElement("div"),this._elements.hider.id="quick-modal-hider-"+this.id,this._elements.hider.classList.add("quick-modal-hider"),this._parameters.document.body.appendChild(this._elements.hider)),this._buildBody(this._elements.body,this._parameters.body),this._buildFooter(),this._parameters.document.body.append(this.modal)}_buildFrame(){this.modal=this._parameters.document.createElement("section"),this.modal.id="quick-modal-"+this.id,this.modal.classList.add("quick-modal",...this._parameters.classes),Object.entries(this._parameters.attributes).forEach(([t,e])=>{this.modal.setAttribute(t,e)}),this.modal.innerHTML=`\n\t\t\t${this._parameters.isForm?`\n\t\t\t\t<form \n\t\t\t\t\t${Reflect.ownKeys(this._parameters.form).includes("id")?'id="'+this._parameters.form.id+'"':""}\n\t\t\t\t\taction="${Reflect.ownKeys(this._parameters.form).includes("action")?this._parameters.form.action:"#"}"\n\t\t\t\t\tmethod="${Reflect.ownKeys(this._parameters.form).includes("method")?this._parameters.form.method:"POST"}"\n\t\t\t\t>\n\t\t\t`:""}\n\t\t\t<header>\n\t\t\t\t${this._parameters.header}\n\t\t\t\t<aside class="quick-modal-close">x</aside>\n\t\t\t</header>\n\t\t\t<section class="quick-modal-main">\n\n\t\t\t</section>\n\t\t\t<footer>\n\t\t\t\t<ul>\n\t\t\t\t\t${this._parameters.isForm?`\n\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t<input \n\t\t\t\t\t\t\t\ttype="submit" \n\t\t\t\t\t\t\t\tclass="quick-modal-generated-btn quick-modal-submit" \n\t\t\t\t\t\t\t\tvalue="${Reflect.ownKeys(this._parameters.form).includes("submit")?this._parameters.form.submit:"OK"}"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t`:""}\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<a class="quick-modal-generated-btn quick-modal-close" href="">\n\t\t\t\t\t\t\t${this._parameters.closeText}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</li>\n\t\t\t\t</ul>\n\t\t\t</footer>\n\t\t\t${this._parameters.isForm?"</form>":""}\n\t\t`,this._elements.body=this.modal.querySelector(".quick-modal-main"),this._elements.footerLinks=this.modal.querySelector("footer>ul")}_buildBody(t,e){e.forEach(e=>{const s=Reflect.ownKeys(e);if("text"==e.type){const i=this._parameters.document.createElement(e.tag);i.innerHTML=e.text,s.includes("id")&&(i.id=e.id),s.includes("classes")&&i.classList.add(...e.classes),s.includes("attributes")&&Object.entries(e.attributes).forEach(([t,e])=>{i.setAttribute(t,e)}),t.appendChild(i)}else if("form"==e.type)switch(e.tag){case"select":t.append(...this._toNodes(`\n\t\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\t\t${s.includes("label")?`\n\t\t\t\t\t\t\t\t\t<label for="${s.includes("id")?e.id:e.name}">${e.label}</label>\n\t\t\t\t\t\t\t\t`:""}\n\t\t\t\t\t\t\t\t<${e.tag} \n\t\t\t\t\t\t\t\t\tname="${s.includes("name")?e.name:""}" \n\t\t\t\t\t\t\t\t\tid="${s.includes("id")?e.id:e.name}"\n\t\t\t\t\t\t\t\t\tclass="${s.includes("classes")?e.classes.join(" "):""}"\n\t\t\t\t\t\t\t\t\t${s.includes("attributes")?Object.entries(e.attributes).reduce((t,[e,s])=>t+(e+'="')+s+'" ',""):""}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t${e.options.reduce((t,e)=>t+`\n\t\t\t\t\t\t\t\t\t\t<option \n\t\t\t\t\t\t\t\t\t\t\t${Reflect.ownKeys(e).includes("attributes")?Object.entries(e.attributes).reduce((t,[e,s])=>t+(e+'="')+s+'" ',""):""}\n\t\t\t\t\t\t\t\t\t\t\tvalue="${e.value}"\n\t\t\t\t\t\t\t\t\t\t\t${e.selected?"selected":""}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t${e.text}\n\t\t\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t\t`,"")}\n\t\t\t\t\t\t\t\t</${e.tag}>\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t`));break;default:t.append(...this._toNodes(`\n\t\t\t\t\t\t\t${s.includes("inputType")&&"hidden"==e.inputType?"":"<p>"}\n\t\t\t\t\t\t\t\t${s.includes("label")?`\n\t\t\t\t\t\t\t\t\t<label for="${s.includes("id")?e.id:e.name}">${e.label}</label>\n\t\t\t\t\t\t\t\t`:""}\n\t\t\t\t\t\t\t\t<${e.tag} \n\t\t\t\t\t\t\t\t\t${"textarea"==e.tag?"":s.includes("inputType")?'type="'+e.inputType+'"':""}\n\t\t\t\t\t\t\t\t\tname="${s.includes("name")?e.name:""}" \n\t\t\t\t\t\t\t\t\tid="${s.includes("id")?e.id:e.name}"\n\t\t\t\t\t\t\t\t\tclass="${s.includes("classes")?e.classes.join(" "):""}"\n\t\t\t\t\t\t\t\t\t${s.includes("attributes")?Object.entries(e.attributes).reduce((t,[e,s])=>t+(e+'="')+s+'" ',""):""}\n\t\t\t\t\t\t\t\t\tplaceholder="${s.includes("placeholder")?e.placeholder:""}"\n\t\t\t\t\t\t\t\t\tvalue="${s.includes("value")?e.value:""}"\n\t\t\t\t\t\t\t\t></${e.tag}>\n\t\t\t\t\t\t\t${s.includes("inputType")&&"hidden"==e.inputType?"":"</p>"}\n\t\t\t\t\t\t`))}else console.warn(e),console.warn("QuickModal: The above element has an invalid `type` attribute. It has been ignored.");e.children&&this._buildBody(t.lastElementChild,e.children)})}_buildFooter(){this._parameters.footer.forEach(t=>{const e=Reflect.ownKeys(t);this._elements.footerLinks.prepend(...this._toNodes(`\n\t\t\t\t<li\n\t\t\t\t\tid="${e.includes("id")?t.id:""}"\n\t\t\t\t\tclass="${e.includes("classes")?t.classes.join(" "):""}"\n\t\t\t\t\t${e.includes("attributes")?Object.entries(t.attributes).reduce((t,[e,s])=>t+(e+'="')+s+'" ',""):""}\n\t\t\t\t>\n\t\t\t\t\t<a class="quick-modal-generated-btn" href="${t.href}">\n\t\t\t\t\t\t${t.text}\n\t\t\t\t\t</a>\n\t\t\t\t</li>\n\t\t\t`))})}_listen(){const t=t=>{t.preventDefault(),this._parameters.keepHidden?this.close():this.destroy()};if(this._elements.hider.addEventListener("click",t),this.modal.querySelectorAll(".quick-modal-close").forEach(e=>{e.addEventListener("click",t)}),this._parameters.isForm){const t=this.modal.querySelector("form");t.addEventListener("submit",e=>{Reflect.apply(this._parameters.onSubmit,this,[e,t])})}}_toNodes(t){const e=this._parameters.document.createElement("template");return e.innerHTML=t,e.content.childNodes}open(){return setTimeout(()=>{this.modal.classList.remove("done"),this.modal.classList.add("active"),this._parameters.darkenBackground&&(this._elements.hider.classList.remove("done"),this._elements.hider.classList.add("active")),Reflect.apply(this._parameters.afterOpen,this,[this.modal])},20),new Promise(t=>{setTimeout(()=>{t()},500)})}close(){return Reflect.apply(this._parameters.beforeClose,this,[this.modal]),this.modal.classList.remove("active"),this._parameters.darkenBackground&&this._elements.hider.classList.remove("active"),new Promise(t=>{setTimeout(()=>{this.modal.classList.add("done"),this._parameters.darkenBackground&&this._elements.hider.classList.add("done"),t()},500)})}destroy(){this.close().then(()=>{this.modal.remove(),this._parameters.darkenBackground&&this._elements.hider.remove()})}static destroy(t){const e=document.getElementById("quick-modal-"+t);e&&(e.querySelector(".quick-modal-close").dispatchEvent(new Event("click")),setTimeout(()=>{const s=document.getElementById("quick-modal-hider-"+t);e.remove(),s&&s.remove()},500))}}!function(t){"use strict";t.fn.extend({quickModal(t){console.warn("QuickModal: Using `$(...).quickModal(...)` is deprecated. Use `const modal = new QuickModal(...)` instead.");const e=new QuickModal(t);return this.open=()=>{e.open()},this.close=()=>{e.close()},this.destroy=()=>{e.destroy()},this}})}(jQuery);