From c3bddbe7c7401f7886501fe8f986b63a0b2014f4 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 18 Nov 2023 20:08:55 +0000 Subject: [PATCH] Changed test demo layout Changed use of modal JS to close --- bs4-test.html | 453 +++++++++++++++++++++++------------------------ bsdialog4.js | 144 ++++++++------- bsdialog4.min.js | 4 +- 3 files changed, 302 insertions(+), 299 deletions(-) diff --git a/bs4-test.html b/bs4-test.html index 4bd7a36..d2d56b8 100644 --- a/bs4-test.html +++ b/bs4-test.html @@ -30,93 +30,133 @@
-
-
+
+
+

Example. Simple Text Modal

+

Launch a modal with a text body.

-
-

Example. Simple Text Modal

-

Launch an empty modal

-
-
-BSDialog.Show({
+        

+ + + +
+
+ +
+
BSDialog.Show({
   ID: "modalL1",
   Title: "Modal Title",
   Message: "Hello Momo!",
   URL: null,
   Size: "md",
   Colour: "secondary"
-});
-            
-
-

- +});
+
+
-
-

Example. Prompt Modal (Buttons)

-

Launch a prompt modal and wait for a button response

-
-
-let response = await BSDialog.Prompt({
-  Title: "Modal Title",
-  Message: "Are you sure want to wait for a response?",
-  Size: "md",
-  Buttons: [
-    { Label: "Yes", Value: "Yes", Colour: "primary" },
-    { Label: "No", Value: "No", Colour: "secondary" },
-    { Label: "Cancel", Value: "Cancel", Colour: "secondary" }
-  ]
-});
+    
+
-alert(response); -
-
-

- + + }); + +
+
+ +
+
BSDialog.Update({
+  ID: "modalL1",
+  Title: "Modal Changed Title",
+  Body: "Hello momo again!",
+  URL: null,
+  Size: "lg",
+  Footer: null
+});
+
+
-
-

Example. Multiple Modals

-

Launch multiple modals

-
-
-BSDialog.Show({
+    
+
+ +

Example. Multiple Modals (Stack)

+

Launch multiple modals, stacked on top of each other.

+ +

+ + +
+
+
+
BSDialog.Show({
   ID: "modalL3a",
   Title: "Modal A Title",
   Message: "First!",
@@ -132,47 +172,86 @@ BSDialog.Show({
   URL: null,
   Size: "md",
   Colour: "secondary"
-});
-            
-
-

- -
- + }); +
-
+
+
+
let response = await BSDialog.Prompt({
+  Title: "Modal Title",
+  Message: "Are you sure want to wait for a response?",
+  Size: "md",
+  Buttons: [
+    { Label: "Yes", Value: "Yes", Colour: "primary" },
+    { Label: "No", Value: "No", Colour: "secondary" },
+    { Label: "Cancel", Value: "Cancel", Colour: "secondary" }
+  ]
+});
 
-        
-

Example. Prompt Modal (Textbox)

-

Launch a prompt modal and wait for a textbox response

-
-
-let response = await BSDialog.Prompt({
+alert(response);
+
+
+
+ +
+
+ +

Example. Text Prompt (Modal)

+

Launch a modal with a text prompt. Modal waits for a response from the textbox.

+ +

+ +
+
+
+
let response = await BSDialog.Prompt({
   Type: "textbox",
   Title: "Modal Title",
   Message: "Are you sure want to wait for a response?",
@@ -181,152 +260,56 @@ let response = await BSDialog.Prompt({
   Placeholder: ""
 });
 
-alert(response);
-            
-
-

- +alert(response);
+
+
+
+
-
-

Example. Prompt Modal (Textbox)

-

Launch a prompt modal and wait for a textbox response

-
-
-let response = await BSDialog.Prompt({
-  Type: "textbox",
-  Title: "Modal Title",
-  Message: "Are you sure want to wait for a response?",
-  Size: "md",
-  Textbox: {
-    Label: "Textbox Label",
-    LabelSize: 4,
-    Placeholder: "Placeholder",
-    Value: "Default Value",
-    BoxSize: 8
-  }
-});
-
-alert(response);
-            
-
-

- -
- - -
-

Example. Simple Text Modal Deprecated

-

Launch an empty modal

-
-
-BSDialog.Create('abc123', 'My Modal Box 123', 'Hello momo!', 'xl');
-            
-
-

- + }); + + +
+
+
+
BSDialog.Close("modalR1");
+
+
-
-

Example. Empty Modal and Updates. Deprecated

-

Launch an empty modal then update its title, body, footer and size.

-
-
-BSDialog.Create('abc123', 'My Modal Box 123', null, 'sm');
-BSDialog.UpdateTitle('abc123', 'My Modal Box 567');
-BSDialog.UpdateBody('abc123', 'Help, I\'m toast!');
-BSDialog.UpdateFooter('abc123', '');
-BSDialog.UpdateSize('abc123', 'lg');
-            
-
-

- + + }); + + +
+
+
+
BSDialog.Clear();
- - -
-

Example. Toast Modal. Deprecated

-

Show a toast-style modal

-
-
-BSDialog.ShowToast('abc123', 'My Modal Box 123', 'Help! I\'m toast.', 'sm');
-            
-
-

- -
- -
diff --git a/bsdialog4.js b/bsdialog4.js index d20fc8c..95f1a55 100644 --- a/bsdialog4.js +++ b/bsdialog4.js @@ -1,8 +1,7 @@ /** * BSDialog4 - * @version v0.1.5.017 (2023/11/16 17:47) + * @version v0.1.5.038 (2023/11/18 19:40) */ - class BSDialog4 { constructor() { } @@ -43,7 +42,7 @@ class BSDialog4 { ID: null, Title: null, Body: null, - BodyURL: null, + URL: null, Footer: null, Size: null } @@ -58,6 +57,16 @@ class BSDialog4 { return document.getElementsByTagName("body")[0]; } + get #sizeList() { + return [ + "modal-sm", + "modal-md", + "modal-lg", + "modal-xl", + "modal-xxl" + ]; + } + async Show(options) { const a = this; @@ -70,14 +79,10 @@ class BSDialog4 { show: true }); - if (!a.#isNullOrWhitespace(_options.URL)) { - if (_options.URL.startsWith("http://") || _options.URL.startsWith("https://") || _options.URL.startsWith("/")) { - const response = await a.#retrieveURL(_options.URL); + if (a.#isURL(_options.URL)) { + const response = await a.#retrieveURL(_options.URL); - await a.Update({ ID: _options.ID, Body: response }); - } else { - await a.Update({ ID: _options.ID, Body: _options.URL }); - } + await a.Update({ ID: _options.ID, Body: response }); } else { await a.Update({ ID: _options.ID, Body: _options.Message }); } @@ -100,29 +105,25 @@ class BSDialog4 { Clear() { const a = this; - a.#body.querySelectorAll(".modal").forEach(function(e) { - e.parentNode.removeChild(e); + document.querySelectorAll('.modal').forEach(function(e) { + $(e).modal('hide'); }); - - a.#removeBackdrop(); } Close(id) { const a = this; - let modal = a.Find(id); - if (modal === null) { - return; + if (id.toString().startsWith(a.#prefix)) { + id = id.toString().substr(a.#prefix.length); } - modal.Modal.parentNode.removeChild(modal.Modal); + const node = document.getElementById(a.#prefix + id); - modal = a.Find(id); - if (modal !== null) { - return; + if (node) { + $(node).modal('hide'); + + node.parentNode.removeChild(node); } - - a.#removeBackdrop(); } async Update(options) { @@ -142,40 +143,24 @@ class BSDialog4 { a.#html(modal.Body, _options.Body); } - if (!a.#isNullOrWhitespace(_options.BodyURL)) { - if (_options.BodyURL.startsWith("http://") || _options.BodyURL.startsWith("https://") || _options.BodyURL.startsWith("/")) { - // ok - } else { - _options.BodyURL = null; + if (!this.#isNullOrWhitespace(_options.Body)) { + a.#html(modal.Body, _options.Body); + } else { + if (this.#isURL(_options.URL)) { + const response = await a.#retrieveURL(_options.URL); + + await a.Update({ ID: _options.ID, Body: response }); } } - if (!a.#isNullOrWhitespace(_options.BodyURL)) { - const response = await a.#retrieveURL(_options.BodyURL); - - await a.Update({ ID: _options.ID, Body: response }); - } - if (!a.#isNullOrWhitespace(_options.Footer)) { a.#html(modal.Footer, _options.Footer); } if (!a.#isNullOrWhitespace(_options.Size)) { - modal.Modal.querySelectorAll(".modal-dialog").forEach(function(e) { - - e.classList.forEach(function(e2) { - if (e2 == "modal-dialog") { - return; - } - - if (e2.startsWith("modal-")) { - e.classList.remove(e2); - } - }); - - e.classList.add("modal-" + _options.Size); - }); + a.#setSize(_options.ID, "modal-" + _options.Size); } + } Exists(id) { @@ -467,28 +452,63 @@ class BSDialog4 { }); } - #toggleSize(id) { + #isURL(value) { const a = this; - let modal = a.Find(id); + if (a.#isNullOrWhitespace(value)) { + return false; + } + + if (value.startsWith("http://") || value.startsWith("https://") || value.startsWith("/")) { + return true; + } + + return false; + } + + #setSize(id, size) { + const a = this; + + const modal = a.Find(id); if (modal === null) { return; } let modalDialog = modal.Modal.querySelectorAll(".modal-dialog")[0]; - if (modalDialog.classList.contains('modal-sm')) { - a.Update({ ID: id, Size: "md" }); - } else if (modalDialog.classList.contains('modal-md')) { - a.Update({ ID: id, Size: "lg" }); - } else if (modalDialog.classList.contains('modal-lg')) { - a.Update({ ID: id, Size: "xl" }); - } else if (modalDialog.classList.contains('modal-xl')) { - a.Update({ ID: id, Size: "xxl" }); - } else if (modalDialog.classList.contains('modal-xxl')) { - a.Update({ ID: id, Size: "sm" }); - } else { - a.Update({ ID: id, Size: "md" }); + + for (let i=0; i (a.#sizeList.length - 1)) { + pos = 0; + } + + modalDialog.classList.add(a.#sizeList[pos]); } } diff --git a/bsdialog4.min.js b/bsdialog4.min.js index 535c550..8efb97b 100644 --- a/bsdialog4.min.js +++ b/bsdialog4.min.js @@ -1,5 +1,5 @@ /** * BSDialog4 - * @version v0.1.5.017 (2023/11/16 17:47) + * @version v0.1.5.038 (2023/11/18 19:40) */ -class BSDialog4{constructor(){}get Options(){return{ShowModal:{ID:null,Title:"",Message:"",URL:null,Size:"md",Colour:"secondary",ShowFooter:!0,EasyClose:!0},ShowPrompt:{Type:"button",Title:"",Message:"",Size:"md",EasyClose:!0,Buttons:[{Label:"Yes",Value:"Yes",Colour:"primary"},{Label:"No",Value:"No",Colour:"secondary"},{Label:"Cancel",Value:"Cancel",Colour:"secondary"}],Textbox:{Label:"",LabelSize:4,Placeholder:"",Value:"",BoxSize:8}},UpdateModal:{ID:null,Title:null,Body:null,BodyURL:null,Footer:null,Size:null}}}get#e(){return"bsdia4_"}get#t(){return document.getElementsByTagName("body")[0]}async Show(e){const t=this,o=Object.assign(t.Options.ShowModal,e);if(t.addModal(o.ID,o.Title,o.Size,o.ShowFooter,o.Colour),$("#"+t.#e+o.ID).modal({backdrop:o.EasyClose,show:!0}),t.#o(o.URL))await t.Update({ID:o.ID,Body:o.Message});else if(o.URL.startsWith("http://")||o.URL.startsWith("https://")||o.URL.startsWith("/")){const e=await t.#l(o.URL);await t.Update({ID:o.ID,Body:e})}else await t.Update({ID:o.ID,Body:o.URL})}async Prompt(e){const t=this,o=Math.floor(1e4*Math.random())+1e3,l=Object.assign(t.Options.ShowPrompt,e);return"textbox"===l.Type?await t.#a(o,l):await t.#s(o,l)}Clear(){this.#t.querySelectorAll(".modal").forEach((function(e){e.parentNode.removeChild(e)})),this.#i()}Close(e){const t=this;let o=t.Find(e);null!==o&&(o.Modal.parentNode.removeChild(o.Modal),o=t.Find(e),null===o&&t.#i())}async Update(e){const t=this;let o=Object.assign(t.Options.UpdateModal,e);const l=t.Find(o.ID);if(null!==l){if(t.#o(o.Title)||(l.Title.innerHTML=o.Title),t.#o(o.Body)||t.#n(l.Body,o.Body),t.#o(o.BodyURL)||o.BodyURL.startsWith("http://")||o.BodyURL.startsWith("https://")||o.BodyURL.startsWith("/")||(o.BodyURL=null),!t.#o(o.BodyURL)){const e=await t.#l(o.BodyURL);await t.Update({ID:o.ID,Body:e})}t.#o(o.Footer)||t.#n(l.Footer,o.Footer),t.#o(o.Size)||l.Modal.querySelectorAll(".modal-dialog").forEach((function(e){e.classList.forEach((function(t){"modal-dialog"!=t&&t.startsWith("modal-")&&e.classList.remove(t)})),e.classList.add("modal-"+o.Size)}))}}Exists(e){return null!==this.Find(e)}Find(e){const t=this.#t.querySelectorAll("#"+this.#e+e+".modal");return t?t.length<=0?null:{Title:t[0].querySelectorAll(".modal-title")[0],Header:t[0].querySelectorAll(".modal-header")[0],Body:t[0].querySelectorAll(".modal-body")[0],Footer:t[0].querySelectorAll(".modal-footer")[0],Close:t[0].querySelectorAll("[data-dismiss='modal']"),Modal:t[0]}:null}addModal(e,t,o,l,a){const s=this;let i=s.Find(e);if(null!==i)return;let n="";n+='",s.#r(s.#t,n),i=s.Find(e),null!==i&&($("#"+s.#e+e).on("hidden.bs.modal",(function(t){s.Close(e)})),i.Title.addEventListener("dblclick",(function(t){t.stopPropagation(),t.preventDefault(),s.#d(e)})))}async#s(e,t){const o=this;return await new Promise((async(l,a)=>{await o.Show({ID:e,Title:t.Title,Message:t.Message,Size:t.Size,EasyClose:t.EasyClose});let s="";t.Buttons.forEach((function(e){s+='"})),o.Update({ID:e,Footer:s});const i=o.Find(e);i.Footer.querySelectorAll("button").forEach((function(t){t.addEventListener("click",(function(a){a.stopPropagation(),a.preventDefault();const s=t.getAttribute("data-prompt-value");o.Close(e),l(s)}))})),i.Close.forEach((function(t){t.addEventListener("click",(function(t){t.stopPropagation(),t.preventDefault(),o.Close(e),l("")}))}))}))}async#a(e,t){const o=this;return await new Promise((async(l,a)=>{t.Buttons=[{Label:"OK",Value:"",Colour:"primary"},{Label:"Cancel",Value:"",Colour:"secondary"}],await o.Show({ID:e,Title:t.Title,Message:t.Message,Size:t.Size,EasyClose:t.EasyClose});let s="";o.#o(t.Message)||(s+="

"+t.Message+"

"),s+='
',o.#o(t.Textbox.Label)||t.Textbox.LabelSize<=0?(s+='
',s+='',s+="
"):(s+='",s+='
',s+='',s+="
"),s+="
";let i="";t.Buttons.forEach((function(e){i+='"})),o.Update({ID:e,Body:s,Footer:i});const n=o.Find(e),r=n.Footer.querySelectorAll("button");r[0].addEventListener("click",(function(t){t.stopPropagation(),t.preventDefault();const a=n.Body.querySelectorAll("input")[0].value;o.Close(e),l(a)})),r[1].addEventListener("click",(function(t){t.stopPropagation(),t.preventDefault(),o.Close(e),l("")})),n.Close.forEach((function(t){t.addEventListener("click",(function(t){t.stopPropagation(),t.preventDefault(),o.Close(e),l("")}))}))}))}#r(e,t){let o=document.createElement("template");o.innerHTML=t,o=o.content.firstChild,e.appendChild(o)}#n(e,t){jQuery?jQuery(e).html(t):e.innerHTML=t}#o(e){return void 0===e||(null==e||(0==e||e.trim().length<=0))}#i(){const e=this;e.#t.querySelectorAll(".modal-backdrop").length<=0||e.#t.querySelectorAll(".modal").length>0||(e.#t.querySelectorAll(".modal-backdrop").forEach((function(e){e.parentNode.removeChild(e)})),e.#t.classList.remove("modal-open"),e.#t.style.overflow=null)}async#l(e){return await new Promise((async t=>{await fetch(e,{cache:"no-cache",credentials:"same-origin"}).then((e=>e.text())).then((e=>{t(e)})).catch((e=>{t("Error: "+e)}))}))}#d(e){const t=this;let o=t.Find(e);if(null===o)return;let l=o.Modal.querySelectorAll(".modal-dialog")[0];l.classList.contains("modal-sm")?t.Update({ID:e,Size:"md"}):l.classList.contains("modal-md")?t.Update({ID:e,Size:"lg"}):l.classList.contains("modal-lg")?t.Update({ID:e,Size:"xl"}):l.classList.contains("modal-xl")?t.Update({ID:e,Size:"xxl"}):l.classList.contains("modal-xxl")?t.Update({ID:e,Size:"sm"}):t.Update({ID:e,Size:"md"})}}var BSDialog=new BSDialog4; \ No newline at end of file +class BSDialog4{constructor(){}get Options(){return{ShowModal:{ID:null,Title:"",Message:"",URL:null,Size:"md",Colour:"secondary",ShowFooter:!0,EasyClose:!0},ShowPrompt:{Type:"button",Title:"",Message:"",Size:"md",EasyClose:!0,Buttons:[{Label:"Yes",Value:"Yes",Colour:"primary"},{Label:"No",Value:"No",Colour:"secondary"},{Label:"Cancel",Value:"Cancel",Colour:"secondary"}],Textbox:{Label:"",LabelSize:4,Placeholder:"",Value:"",BoxSize:8}},UpdateModal:{ID:null,Title:null,Body:null,URL:null,Footer:null,Size:null}}}get#e(){return"bsdia4_"}get#t(){return document.getElementsByTagName("body")[0]}get#o(){return["modal-sm","modal-md","modal-lg","modal-xl","modal-xxl"]}async Show(e){const t=this,o=Object.assign(t.Options.ShowModal,e);if(t.addModal(o.ID,o.Title,o.Size,o.ShowFooter,o.Colour),$("#"+t.#e+o.ID).modal({backdrop:o.EasyClose,show:!0}),t.#l(o.URL)){const e=await t.#a(o.URL);await t.Update({ID:o.ID,Body:e})}else await t.Update({ID:o.ID,Body:o.Message})}async Prompt(e){const t=this,o=Math.floor(1e4*Math.random())+1e3,l=Object.assign(t.Options.ShowPrompt,e);return"textbox"===l.Type?await t.#s(o,l):await t.#i(o,l)}Clear(){document.querySelectorAll(".modal").forEach((function(e){$(e).modal("hide")}))}Close(e){const t=this;e.toString().startsWith(t.#e)&&(e=e.toString().substr(t.#e.length));const o=document.getElementById(t.#e+e);o&&($(o).modal("hide"),o.parentNode.removeChild(o))}async Update(e){const t=this;let o=Object.assign(t.Options.UpdateModal,e);const l=t.Find(o.ID);if(null!==l){if(t.#n(o.Title)||(l.Title.innerHTML=o.Title),t.#n(o.Body)||t.#r(l.Body,o.Body),this.#n(o.Body)){if(this.#l(o.URL)){const e=await t.#a(o.URL);await t.Update({ID:o.ID,Body:e})}}else t.#r(l.Body,o.Body);t.#n(o.Footer)||t.#r(l.Footer,o.Footer),t.#n(o.Size)||t.#d(o.ID,"modal-"+o.Size)}}Exists(e){return null!==this.Find(e)}Find(e){const t=this.#t.querySelectorAll("#"+this.#e+e+".modal");return t?t.length<=0?null:{Title:t[0].querySelectorAll(".modal-title")[0],Header:t[0].querySelectorAll(".modal-header")[0],Body:t[0].querySelectorAll(".modal-body")[0],Footer:t[0].querySelectorAll(".modal-footer")[0],Close:t[0].querySelectorAll("[data-dismiss='modal']"),Modal:t[0]}:null}addModal(e,t,o,l,a){const s=this;let i=s.Find(e);if(null!==i)return;let n="";n+='",s.#c(s.#t,n),i=s.Find(e),null!==i&&($("#"+s.#e+e).on("hidden.bs.modal",(function(t){s.Close(e)})),i.Title.addEventListener("dblclick",(function(t){t.stopPropagation(),t.preventDefault(),s.#u(e)})))}async#i(e,t){const o=this;return await new Promise((async(l,a)=>{await o.Show({ID:e,Title:t.Title,Message:t.Message,Size:t.Size,EasyClose:t.EasyClose});let s="";t.Buttons.forEach((function(e){s+='"})),o.Update({ID:e,Footer:s});const i=o.Find(e);i.Footer.querySelectorAll("button").forEach((function(t){t.addEventListener("click",(function(a){a.stopPropagation(),a.preventDefault();const s=t.getAttribute("data-prompt-value");o.Close(e),l(s)}))})),i.Close.forEach((function(t){t.addEventListener("click",(function(t){t.stopPropagation(),t.preventDefault(),o.Close(e),l("")}))}))}))}async#s(e,t){const o=this;return await new Promise((async(l,a)=>{t.Buttons=[{Label:"OK",Value:"",Colour:"primary"},{Label:"Cancel",Value:"",Colour:"secondary"}],await o.Show({ID:e,Title:t.Title,Message:t.Message,Size:t.Size,EasyClose:t.EasyClose});let s="";o.#n(t.Message)||(s+="

"+t.Message+"

"),s+='
',o.#n(t.Textbox.Label)||t.Textbox.LabelSize<=0?(s+='
',s+='',s+="
"):(s+='",s+='
',s+='',s+="
"),s+="
";let i="";t.Buttons.forEach((function(e){i+='"})),o.Update({ID:e,Body:s,Footer:i});const n=o.Find(e),r=n.Footer.querySelectorAll("button");r[0].addEventListener("click",(function(t){t.stopPropagation(),t.preventDefault();const a=n.Body.querySelectorAll("input")[0].value;o.Close(e),l(a)})),r[1].addEventListener("click",(function(t){t.stopPropagation(),t.preventDefault(),o.Close(e),l("")})),n.Close.forEach((function(t){t.addEventListener("click",(function(t){t.stopPropagation(),t.preventDefault(),o.Close(e),l("")}))}))}))}#c(e,t){let o=document.createElement("template");o.innerHTML=t,o=o.content.firstChild,e.appendChild(o)}#r(e,t){jQuery?jQuery(e).html(t):e.innerHTML=t}#n(e){return void 0===e||(null==e||(0==e||e.trim().length<=0))}#p(){const e=this;e.#t.querySelectorAll(".modal-backdrop").length<=0||e.#t.querySelectorAll(".modal").length>0||(e.#t.querySelectorAll(".modal-backdrop").forEach((function(e){e.parentNode.removeChild(e)})),e.#t.classList.remove("modal-open"),e.#t.style.overflow=null)}async#a(e){return await new Promise((async t=>{await fetch(e,{cache:"no-cache",credentials:"same-origin"}).then((e=>e.text())).then((e=>{t(e)})).catch((e=>{t("Error: "+e)}))}))}#l(e){return!this.#n(e)&&!!(e.startsWith("http://")||e.startsWith("https://")||e.startsWith("/"))}#d(e,t){const o=this,l=o.Find(e);if(null===l)return;let a=l.Modal.querySelectorAll(".modal-dialog")[0];for(let e=0;et.#o.length-1&&(a=0),l.classList.add(t.#o[a])}}var BSDialog=new BSDialog4; \ No newline at end of file