/** * BSDialog5 * @version v0.2.0.013 (2023/08/21 1945) */ var BSDialog5 = { Default: function() { return { ShowOptions: { ID: null, Title: "", Message: "", URL: null, Size: "md", Colour: "secondary", ShowFooter: true }, PromptOptions: { Title: "", Message: "", Size: "md", Buttons: [ { Label: "Yes", Value: "Yes", Colour: "primary" }, { Label: "No", Value: "No", Colour: "secondary" }, { Label: "Cancel", Value: "Cancel", Colour: "secondary" } ] }, UpdateOptions: { ID: null, Title: null, Body: null, BodyURL: null, Footer: null, Size: null } }; }, Show: async function (options) { const a = this; const _options = Object.assign(a.Default().ShowOptions, options); a.id = _options.ID; a.pfx = "bsdia5_"; a.addBackdrop(); a.addModal(_options.ID, _options.Title, _options.Size, true, _options.Colour); if (_options.URL == null) { await a.Update({ ID: _options.ID, Body: _options.Message }); } else { if (a.isNullOrWhitespace(_options.URL)) { await a.Update({ ID: _options.ID, Body: URL }); } else { if (_options.URL.startsWith("http://") || _options.URL.startsWith("https://") || _options.URL.startsWith("/")) { await a.UpdateBodyRemote(_options.ID, _options.URL); } else { await a.Update({ ID: _options.ID, Body: URL }); } } } }, Prompt: async function (options) { const a = this; const id = "prompt" + Math.floor(Math.random() * 10000) + 1000; const _options = Object.assign(a.Default().PromptOptions, options); return await new Promise(async (resolve) => { await a.Show({ ID: id, Title: _options.Title, Message: _options.Message, Size: _options.Size }); let html = ''; _options.Buttons.forEach(function(e) { html += ''; }); a.Update({ ID: id, Footer: html }); const modal = a.Find(id); modal.Footer[0].querySelectorAll("button").forEach(function(button) { button.addEventListener("click", function(e){ e.stopPropagation(); e.preventDefault(); const value = button.getAttribute("data-prompt-value"); a.Close(id); resolve(value); }); }); modal.Close.forEach(function(sender) { sender.addEventListener("click", function(e){ e.stopPropagation(); e.preventDefault(); a.Close(id); resolve(""); }); }); }); }, Clear: function () { this.GetBody().querySelectorAll(".modal").forEach(function(e) { e.parentNode.removeChild(e); }); this.removeBackdrop(); }, Close: function (id) { let modal = this.Find(id); if (modal === null) { return; } modal.Modal.forEach(function(e) { e.parentNode.removeChild(e); }); modal = this.Find(id); if (modal !== null) { return; } this.removeBackdrop(); }, Update: async function (options) { const a = this; let _options = Object.assign(a.Default().UpdateOptions, options); const modal = a.Find(_options.ID); if (modal === null) { return; } if (!this.isNullOrWhitespace(_options.Title)) { modal.Title.forEach(function(e) { e.innerHTML = _options.Title; }); } if (!this.isNullOrWhitespace(_options.Body)) { modal.Body.forEach(function(e) { a.html(e, _options.Body); }); } if (!this.isNullOrWhitespace(_options.BodyURL)) { if (_options.BodyURL.startsWith("http://") || _options.BodyURL.startsWith("https://") || _options.BodyURL.startsWith("/")) { // ok } else { _options.BodyURL = null; } } if (!this.isNullOrWhitespace(_options.BodyURL)) { await a.UpdateBodyRemote(_options.ID, _options.BodyURL); } if (!this.isNullOrWhitespace(_options.Footer)) { modal.Footer.forEach(function(e) { a.html(e, _options.Footer); }); } if (!this.isNullOrWhitespace(_options.Size)) { modal.Modal.forEach(function(e) { e.classList.remove("modal-sm"); e.classList.remove("modal-md"); e.classList.remove("modal-lg"); e.classList.remove("modal-xl"); e.classList.add("modal-" + _options.Size); }); } }, UpdateBodyRemote: async function (id, url) { const a = this; if (!a.Exists(id)) { return; } await fetch(url, { cache: 'no-cache', credentials: 'same-origin' }).then(data => data.text()).then(data => { a.Update({ ID: id, Body: data }); }).catch((error) => { a.Update({ ID: id, Body: "Error: " + error }); }); }, Exists: function (id) { return (this.Find(id) !== null); }, Find: function (id) { const modal = this.GetBody().querySelectorAll("#" + this.pfx + id + ".modal"); if (!modal) { return null; } if (modal.length <= 0) { return null; } return { Title: modal[0].querySelectorAll(".modal-title"), Body: modal[0].querySelectorAll(".modal-body"), Footer: modal[0].querySelectorAll(".modal-footer"), Close: modal[0].querySelectorAll("[data-bs-dismiss='modal']"), Modal: modal }; }, GetBody: function() { return document.getElementsByTagName("body")[0]; }, addBackdrop: function () { const a = this; // don't allow duplicates if (a.GetBody().querySelectorAll(".modal-backdrop").length > 0) { return; } a.appendHtml(a.GetBody(), ''); // lock background a.GetBody().classList.add("modal-open"); a.GetBody().style.overflow = "hidden"; // close let backdrop = a.GetBody().querySelectorAll(".modal-backdrop")[0]; backdrop.addEventListener("click", function(e){ e.stopPropagation(); e.preventDefault(); a.Clear(); }); }, addModal: function (id, title, size, showFooter, closeColour) { const a = this; // don't allow duplicates let modal = a.Find(id); if (modal !== null) { return; } let html = ""; html += ''; a.appendHtml(a.GetBody(), html); modal = a.Find(id); if (modal === null) { return; } // modal.addEventListener("click", function(e){ // e.stopPropagation(); // e.preventDefault(); // a.Close(id); // }); modal.Close.forEach(function(e){ e.addEventListener("click", function(e){ e.stopPropagation(); e.preventDefault(); a.Close(id); }); e.addEventListener("auxclick", function(e){ e.stopPropagation(); e.preventDefault(); if (e.button === 1) { a.toggleSize(); } }); }); }, appendHtml: function (el, html) { let node = document.createElement('template'); node.innerHTML = html; node = node.content.firstChild; el.appendChild(node); }, html: function (el, newHtml) { /// todo: replace with pure JS if (jQuery) { jQuery(el).html(newHtml); } else { el.innerHTML = newHtml; } }, isNullOrWhitespace: function(e) { if (typeof (e) == "undefined") { return true; } if (e == null) { return true; } if (e == false) { return true; } return (e.trim().length <= 0); }, removeBackdrop: function () { const a = this; if (a.GetBody().querySelectorAll(".modal-backdrop").length <= 0) { return; } if (a.GetBody().querySelectorAll(".modal").length > 0) { return; } let backdrop = a.GetBody().querySelectorAll(".modal-backdrop")[0]; backdrop.parentNode.removeChild(backdrop); // unlock background a.GetBody().classList.remove("modal-open"); a.GetBody().style.overflow = null; }, toggleSize: function () { const a = this; let modal = a.Find(a.id); if (modal === null) { return; } let modalDialog = modal.Modal[0]; if (modalDialog.classList.contains('modal-sm')) { modalDialog.classList.remove("modal-sm"); modalDialog.classList.add("modal-md"); } else if (modalDialog.classList.contains('modal-md')) { modalDialog.classList.remove("modal-md"); modalDialog.classList.add("modal-lg"); } else if (modalDialog.classList.contains('modal-lg')) { modalDialog.classList.remove("modal-lg"); modalDialog.classList.add("modal-xl"); } else if (modalDialog.classList.contains('modal-xl')) { modalDialog.classList.remove("modal-xl"); modalDialog.classList.add("modal-sm"); } else { modalDialog.classList.remove("modal-sm"); modalDialog.classList.remove("modal-md"); modalDialog.classList.remove("modal-lg"); modalDialog.classList.remove("modal-xl"); modalDialog.classList.add("modal-md"); } } };