Compare commits

...

2 Commits

Author SHA1 Message Date
Ray
2aa6f63d0e Merge pull request 'Added toggle size' (#1) from release/0.1.1.x into master
Reviewed-on: #1
2023-08-03 12:39:12 +00:00
Ray
bac3c38113 Added toggle size
Change autodetect for text/url for message
Added test page
2023-08-03 13:25:33 +01:00
3 changed files with 319 additions and 162 deletions

53
bs4-test.html Normal file
View File

@ -0,0 +1,53 @@
<!doctype html>
<html lang="en-GB">
<head>
<meta charset="UTF-8" />
<meta http-equiv="content-type" content="text/html" charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="" />
<meta name="keyword" content="" />
<!-- jquery -->
<script src="http://cdn.hiimray.co.uk/8206c600-707c-469e-8d49-a76ae35782af/jquery/3.7.0/dist/jquery.min.js"></script>
<!-- bootstrap -->
<script src="http://cdn.hiimray.co.uk/8206c600-707c-469e-8d49-a76ae35782af/bootstrap/4.6.2/dist/js/bootstrap.bundle.min.js"></script>
<link href="http://cdn.hiimray.co.uk/8206c600-707c-469e-8d49-a76ae35782af/bootstrap/4.6.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="bsdialog4.js"></script>
<title></title>
</head>
<body class="py-5">
<div class="container">
<div class="row mb-3">
<div class="col-12">
<button type="button" class="btn btn-primary" onclick="BSDialog.Create('abc123', 'My Modal Box 123', null, 'xl')">
Launch Modal 1
</button>
</div>
</div>
<div class="row mb-3">
<div class="col-12">
<button type="button" class="btn btn-primary" onclick="BSDialog.Create('abc123', 'My Modal Box 123', 'Hello momo!', 'lg')">
Launch Modal 2
</button>
</div>
</div>
<div class="row mb-3">
<div class="col-12">
<button type="button" class="btn btn-primary" onclick="BSDialog.ShowToast('abc123', 'My Modal Box 123', 'Help! I\'m toast.', 'sm')">
Launch Modal 3
</button>
</div>
</div>
</div>
</body>
</html>

View File

@ -1,191 +1,295 @@
/**
* BSDialog4
* @version v0.1.0.002 (2021/04/25 1713)
* @version v0.1.1.024 (2023/08/03 0013)
*/
var BSDialog = {
Create: function (id, title, url, size) {
Create: async function (id, title, url, size) {
var a = this;
a.id = id;
a.title = title;
a.url = url;
a.pfx = "bsdia5_";
a.body = document.getElementsByTagName("body")[0];
if (typeof (size) == "undefined") {
a.size = "md";
} else if (size === true) {
a.size = "lg";
} else if (size === false) {
a.size = "md";
} else {
a.size = size;
}
a.addBackdrop();
a.addModal(id, title, size);
if (!a.Exists(id)) {
a.renderContent(null);
if (a.isNullOrWhitespace(url)) {
a.UpdateBody(id, "");
} else if (url.startsWith("http://") || url.startsWith("https://")) {
a.UpdateBodyRemote(id, url);
} else {
await a.UpdateBody(id, url);
}
if (url != null) {
$.ajax({
url: url,
cache: false,
xhrFields: {
withCredentials:true
},
timeout: 30000,
success: function (result, status, xhr) {
if ((xhr.status == 200) || (xhr.status == 302) || (xhr.status == 301)) {
a.updateContentBody(id, result);
} else {
a.updateContentBody(id, xhr.statusText + " (" + xhr.status + ")");
}
},
error: function (xhr) {
a.updateContentBody(id, xhr.statusText + " (" + xhr.status + ")");
},
complete: function (xhr, status) {
// do nothing yet
}
});
}
a.initialiseComponents();
},
Close: function (id) {
$("#dlg" + id).modal('hide');
},
Clear: function () {
$("body > div[class~='modal'][role='dialog']").remove();
$("body > div[class~='modal-backdrop']").remove();
$("body").removeClass("modal-open");
},
ShowToast: function (id, title, message, size) {
var a = this;
this.body.querySelectorAll(".modal").forEach(function(e) {
e.parentNode.removeChild(e);
});
if (a.Exists(id)) {
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;
}
a.id = id;
a.title = title;
a.url = null;
a.size = ((typeof (size) == "undefined") ? "md" : size);
this.removeBackdrop();
},
UpdateTitle: function (id, title) {
let modal = this.Find(id);
if (modal === null) {
return;
}
a.renderContent(message);
a.initialiseComponents();
modal.Title.forEach(function(e) {
e.innerHTML = title;
});
},
UpdateSize: function (id, size) {
let modal = this.Find(id);
if (modal === null) {
return;
}
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-" + size);
});
},
UpdateBody: function (id, content) {
var a = this;
let modal = a.Find(id);
if (modal === null) {
return;
}
modal.Body.forEach(function(e) {
a.html(e, content);
});
},
UpdateBodyRemote: async function (id, url) {
var a = this;
if (!a.Exists(id)) {
return;
}
await fetch(url, {
cache: 'no-cache',
credentials: 'same-origin'
}).then(data => data.text()).then(data => {
a.UpdateBody(id, data);
}).catch((error) => {
a.UpdateBody(id, "Error: " + error);
});
},
UpdateFooter: function (id, content) {
var a = this;
let modal = a.Find(id);
if (modal === null) {
return;
}
modal.Footer.forEach(function(e) {
a.html(e, content);
});
},
Exists: function (id) {
return ($("body > div[id='dlg" + id + "']").length > 0);
return (this.Find(id) !== null);
},
generateModalHtml: function (message) {
var a = this;
var html = "";
html += "<div class=\"modal fade\" id=\"dlg" + a.id + "\" tabindex=\"-1\" role=\"dialog\">";
html += " <div class=\"modal-dialog modal-" + a.size + "\">";
html += " <div class=\"modal-content\">";
html += " <div class=\"modal-header\">";
html += " <strong class=\"modal-title\" style=\"cursor:default; \">" + a.title + "</strong>";
html += " <button type=\"button\" class=\"close\" data-modal-action=\"restore\" aria-hidden=\"true\">&#8722;</button>";
html += " <button type=\"button\" class=\"close ml-0\" data-dismiss=\"modal\" aria-hidden=\"true\">&times;</button>";
html += " </div>";
if ($.trim(message).length <= 0) {
html += " <div class=\"modal-body\">";
html += " <div class=\"text-center\">";
html += " <div class=\"spinner-border text-secondary text-center\" role=\"status\">";
html += " <span class=\"sr-only\">Loading...</span>";
html += " </div>";
html += " </div>";
html += " </div>";
} else {
html += " <div class=\"modal-body\">" + message + "</div>";
Find: function (id) {
let modal = this.body.querySelectorAll("#" + this.pfx + id + ".modal");
if (!modal) {
return null;
}
html += " <div class=\"modal-footer\">";
html += " <button type=\"button\" class=\"btn btn-outline-dark\" data-dismiss=\"modal\">Close</button>";
html += " </div>";
html += " </div>";
html += " </div>";
html += "</div>";
if (modal.length <= 0) {
return null;
}
return html;
return {
Title: modal[0].querySelectorAll(".modal-title"),
Body: modal[0].querySelectorAll(".modal-body"),
Footer: modal[0].querySelectorAll(".modal-footer"),
Close: modal[0].querySelectorAll("[data-dismiss='modal']"),
Modal: modal
};
},
renderContent: function (content) {
$("body").append(this.generateModalHtml(content));
ShowToast: function (id, title, message, size) {
this.Create(id, title, null, size);
this.UpdateBody(id, message);
},
initialiseComponents: function () {
var a = this;
var dialog = a.getElement();
addBackdrop: function () {
let a = this;
var btnToggleSize = $(dialog).find("button[data-modal-action='restore']");
if ($(btnToggleSize).length > 0) {
$(btnToggleSize).off('click');
$(btnToggleSize).on('click', function () {
a.toggleSize();
});
}
$(dialog).modal('show');
$(dialog).off('hide.bs.modal');
$(dialog).on('hide.bs.modal', function () {
if ($(dialog).next().is("div[class~='modal-backdrop']")) {
$(dialog).next().remove();
}
$(dialog).remove();
});
$(dialog).find(".modal-header").off("mousedown");
$(dialog).find(".modal-header").on("mousedown", function(e) {
var posX = e.pageX - $(this).offset().left;
var posY = e.pageY - $(this).offset().top;
$("body").off("mousemove.draggable");
$("body").on("mousemove.draggable", function(e2) {
$(dialog).children(".modal-dialog").offset({ "left": (e2.pageX - posX), "top": (e2.pageY - posY) });
});
$("body").off("mouseup");
$("body").on("mouseup", function() {
$("body").off("mousemove.draggable");
});
$(dialog).off("bs.modal.hide");
$(dialog).on("bs.modal.hide", function() {
$("body").off("mousemove.draggable");
});
});
},
updateContentBody: function (id, text) {
var body = $("#dlg" + id).find(".modal-body");
if ($(body).hasClass("custom-loading")) $(body).removeClass("custom-loading");
$(body).html(text);
},
getElement: function () {
return $("#dlg" + this.id);
},
toggleSize: function () {
var div = $(this.getElement()).find("div[class^='modal-dialog']");
if ($(div).length <= 0) {
// don't allow duplicates
if (a.body.querySelectorAll(".modal-backdrop").length > 0) {
return;
}
if ($(div).hasClass("modal-md")) {
$(div).removeClass("modal-md");
$(div).addClass("modal-lg");
} else if ($(div).hasClass("modal-lg")) {
$(div).removeClass("modal-lg");
$(div).addClass("modal-xl");
} else if ($(div).hasClass("modal-xl")) {
$(div).removeClass("modal-xl");
// $(div).addClass("modal-sm");
$(div).addClass("modal-md");
} else if ($(div).hasClass("modal-sm")) {
$(div).removeClass("modal-sm");
$(div).addClass("modal-md");
a.appendHtml(a.body, '<div class="modal-backdrop fade show"></div>');
// lock background
a.body.classList.add("modal-open");
a.body.style.overflow = "hidden";
// close
let backdrop = a.body.querySelectorAll(".modal-backdrop")[0];
backdrop.addEventListener("click", function(e){
e.stopPropagation();
e.preventDefault();
a.Clear();
});
},
addModal: function (id, title, size) {
var a = this;
// don't allow duplicates
let modal = a.Find(id);
if (modal !== null) {
return;
}
let html = "";
html += '<div class="modal fade show d-block" id="' + a.pfx + id + '" tabindex="-1">';
html += ' <div class="modal-dialog modal-' + size + '">';
html += ' <div class="modal-content">';
html += ' <div class="modal-header">';
html += ' <span class="modal-title font-weight-bold">' + title + '</span>';
html += ' <button type="button" class="close" data-dismiss="modal" aria-label="Close">';
html += ' <span aria-hidden="true">&times;</span>';
html += ' </button>';
html += ' </div>';
html += ' <div class="modal-body">';
html += '<div class="row mt-3 pb-3">';
html += ' <div class="col-12 text-center">';
html += ' <div class="spinner-border" role="status">';
html += ' <span class="sr-only">Loading...</span>';
html += ' </div>';
html += ' </div>';
html += '</div>';
html += ' </div>';
html += ' <div class="modal-footer">';
html += ' <button type="button" class="btn btn-outline-secondary" data-dismiss="modal">Close</button>';
html += ' </div>';
html += ' </div>';
html += ' </div>';
html += '</div>';
a.appendHtml(a.body, html);
modal = a.Find(id);
if (modal === null) {
return;
}
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 () {
if (this.body.querySelectorAll(".modal-backdrop").length <= 0) {
return;
}
let backdrop = this.body.querySelectorAll(".modal-backdrop")[0];
backdrop.parentNode.removeChild(backdrop);
// unlock background
this.body.classList.remove("modal-open");
this.body.style.overflow = null;
},
toggleSize: function () {
var a = this;
let modal = a.Find(a.id);
if (modal === null) {
return;
}
let modalDialog = modal.Modal[0].querySelectorAll(".modal-dialog")[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");
}
}
};

4
bsdialog4.min.js vendored
View File

@ -1,5 +1,5 @@
/**
* BSDialog4
* @version v0.1.0.002 (2021/04/25 1713)
* @version v0.1.1.024 (2023/08/03 0013)
*/
var BSDialog={Create:function(o,t,e,d){var a=this;a.id=o,a.title=t,a.url=e,a.size=void 0===d?"md":!0===d?"lg":!1===d?"md":d,a.Exists(o)||a.renderContent(null),null!=e&&$.ajax({url:e,cache:!1,xhrFields:{withCredentials:!0},timeout:3e4,success:function(t,e,d){200==d.status||302==d.status||301==d.status?a.updateContentBody(o,t):a.updateContentBody(o,d.statusText+" ("+d.status+")")},error:function(t){a.updateContentBody(o,t.statusText+" ("+t.status+")")},complete:function(o,t){}}),a.initialiseComponents()},Close:function(o){$("#dlg"+o).modal("hide")},Clear:function(){$("body > div[class~='modal'][role='dialog']").remove(),$("body > div[class~='modal-backdrop']").remove(),$("body").removeClass("modal-open")},ShowToast:function(o,t,e,d){var a=this;a.Exists(o)||(a.id=o,a.title=t,a.url=null,a.size=void 0===d?"md":d,a.renderContent(e),a.initialiseComponents())},Exists:function(o){return $("body > div[id='dlg"+o+"']").length>0},generateModalHtml:function(o){var t=this,e="";return e+='<div class="modal fade" id="dlg'+t.id+'" tabindex="-1" role="dialog">',e+=' <div class="modal-dialog modal-'+t.size+'">',e+=' <div class="modal-content">',e+=' <div class="modal-header">',e+=' <strong class="modal-title" style="cursor:default; ">'+t.title+"</strong>",e+=' <button type="button" class="close" data-modal-action="restore" aria-hidden="true">&#8722;</button>',e+=' <button type="button" class="close ml-0" data-dismiss="modal" aria-hidden="true">&times;</button>',e+=" </div>",$.trim(o).length<=0?(e+=' <div class="modal-body">',e+=' <div class="text-center">',e+=' <div class="spinner-border text-secondary text-center" role="status">',e+=' <span class="sr-only">Loading...</span>',e+=" </div>",e+=" </div>",e+=" </div>"):e+=' <div class="modal-body">'+o+"</div>",e+=' <div class="modal-footer">',e+=' <button type="button" class="btn btn-outline-dark" data-dismiss="modal">Close</button>',e+=" </div>",e+=" </div>",e+=" </div>",e+="</div>"},renderContent:function(o){$("body").append(this.generateModalHtml(o))},initialiseComponents:function(){var o=this,t=o.getElement(),e=$(t).find("button[data-modal-action='restore']");$(e).length>0&&($(e).off("click"),$(e).on("click",function(){o.toggleSize()})),$(t).modal("show"),$(t).off("hide.bs.modal"),$(t).on("hide.bs.modal",function(){$(t).next().is("div[class~='modal-backdrop']")&&$(t).next().remove(),$(t).remove()}),$(t).find(".modal-header").off("mousedown"),$(t).find(".modal-header").on("mousedown",function(o){var e=o.pageX-$(this).offset().left,d=o.pageY-$(this).offset().top;$("body").off("mousemove.draggable"),$("body").on("mousemove.draggable",function(o){$(t).children(".modal-dialog").offset({left:o.pageX-e,top:o.pageY-d})}),$("body").off("mouseup"),$("body").on("mouseup",function(){$("body").off("mousemove.draggable")}),$(t).off("bs.modal.hide"),$(t).on("bs.modal.hide",function(){$("body").off("mousemove.draggable")})})},updateContentBody:function(o,t){var e=$("#dlg"+o).find(".modal-body");$(e).hasClass("custom-loading")&&$(e).removeClass("custom-loading"),$(e).html(t)},getElement:function(){return $("#dlg"+this.id)},toggleSize:function(){var o=$(this.getElement()).find("div[class^='modal-dialog']");$(o).length<=0||($(o).hasClass("modal-md")?($(o).removeClass("modal-md"),$(o).addClass("modal-lg")):$(o).hasClass("modal-lg")?($(o).removeClass("modal-lg"),$(o).addClass("modal-xl")):$(o).hasClass("modal-xl")?($(o).removeClass("modal-xl"),$(o).addClass("modal-md")):$(o).hasClass("modal-sm")&&($(o).removeClass("modal-sm"),$(o).addClass("modal-md")))}};
var BSDialog={Create:async function(t,l,o,e){var a=this;a.id=t,a.pfx="bsdia5_",a.body=document.getElementsByTagName("body")[0],a.addBackdrop(),a.addModal(t,l,e),a.isNullOrWhitespace(o)?a.UpdateBody(t,""):o.startsWith("http://")||o.startsWith("https://")?a.UpdateBodyRemote(t,o):await a.UpdateBody(t,o)},Clear:function(){this.body.querySelectorAll(".modal").forEach((function(t){t.parentNode.removeChild(t)})),this.removeBackdrop()},Close:function(t){let l=this.Find(t);null!==l&&(l.Modal.forEach((function(t){t.parentNode.removeChild(t)})),l=this.Find(t),null===l&&this.removeBackdrop())},UpdateTitle:function(t,l){let o=this.Find(t);null!==o&&o.Title.forEach((function(t){t.innerHTML=l}))},UpdateSize:function(t,l){let o=this.Find(t);null!==o&&o.Modal.forEach((function(t){t.classList.remove("modal-sm"),t.classList.remove("modal-md"),t.classList.remove("modal-lg"),t.classList.remove("modal-xl"),t.classList.add("modal-"+l)}))},UpdateBody:function(t,l){var o=this;let e=o.Find(t);null!==e&&e.Body.forEach((function(t){o.html(t,l)}))},UpdateBodyRemote:async function(t,l){var o=this;o.Exists(t)&&await fetch(l,{cache:"no-cache",credentials:"same-origin"}).then((t=>t.text())).then((l=>{o.UpdateBody(t,l)})).catch((l=>{o.UpdateBody(t,"Error: "+l)}))},UpdateFooter:function(t,l){var o=this;let e=o.Find(t);null!==e&&e.Footer.forEach((function(t){o.html(t,l)}))},Exists:function(t){return null!==this.Find(t)},Find:function(t){let l=this.body.querySelectorAll("#"+this.pfx+t+".modal");return l?l.length<=0?null:{Title:l[0].querySelectorAll(".modal-title"),Body:l[0].querySelectorAll(".modal-body"),Footer:l[0].querySelectorAll(".modal-footer"),Close:l[0].querySelectorAll("[data-dismiss='modal']"),Modal:l}:null},ShowToast:function(t,l,o,e){this.Create(t,l,null,e),this.UpdateBody(t,o)},addBackdrop:function(){let t=this;t.body.querySelectorAll(".modal-backdrop").length>0||(t.appendHtml(t.body,'<div class="modal-backdrop fade show"></div>'),t.body.classList.add("modal-open"),t.body.style.overflow="hidden",t.body.querySelectorAll(".modal-backdrop")[0].addEventListener("click",(function(l){l.stopPropagation(),l.preventDefault(),t.Clear()})))},addModal:function(t,l,o){var e=this;let a=e.Find(t);if(null!==a)return;let d="";d+='<div class="modal fade show d-block" id="'+e.pfx+t+'" tabindex="-1">',d+=' <div class="modal-dialog modal-'+o+'">',d+=' <div class="modal-content">',d+=' <div class="modal-header">',d+=' <span class="modal-title font-weight-bold">'+l+"</span>",d+=' <button type="button" class="close" data-dismiss="modal" aria-label="Close">',d+=' <span aria-hidden="true">&times;</span>',d+=" </button>",d+=" </div>",d+=' <div class="modal-body">',d+='<div class="row mt-3 pb-3">',d+=' <div class="col-12 text-center">',d+=' <div class="spinner-border" role="status">',d+='\t <span class="sr-only">Loading...</span>',d+=" </div>",d+=" </div>",d+="</div>",d+=" </div>",d+=' <div class="modal-footer">',d+=' <button type="button" class="btn btn-outline-secondary" data-dismiss="modal">Close</button>',d+=" </div>",d+=" </div>",d+=" </div>",d+="</div>",e.appendHtml(e.body,d),a=e.Find(t),null!==a&&a.Close.forEach((function(l){l.addEventListener("click",(function(l){l.stopPropagation(),l.preventDefault(),e.Close(t)})),l.addEventListener("auxclick",(function(t){t.stopPropagation(),t.preventDefault(),1===t.button&&e.toggleSize()}))}))},appendHtml:function(t,l){let o=document.createElement("template");o.innerHTML=l,o=o.content.firstChild,t.appendChild(o)},html:function(t,l){jQuery?jQuery(t).html(l):t.innerHTML=l},isNullOrWhitespace:function(t){return void 0===t||(null==t||(0==t||t.trim().length<=0))},removeBackdrop:function(){if(this.body.querySelectorAll(".modal-backdrop").length<=0)return;let t=this.body.querySelectorAll(".modal-backdrop")[0];t.parentNode.removeChild(t),this.body.classList.remove("modal-open"),this.body.style.overflow=null},toggleSize:function(){let t=this.Find(this.id);if(null===t)return;let l=t.Modal[0].querySelectorAll(".modal-dialog")[0];l.classList.contains("modal-sm")?(l.classList.remove("modal-sm"),l.classList.add("modal-md")):l.classList.contains("modal-md")?(l.classList.remove("modal-md"),l.classList.add("modal-lg")):l.classList.contains("modal-lg")?(l.classList.remove("modal-lg"),l.classList.add("modal-xl")):l.classList.contains("modal-xl")?(l.classList.remove("modal-xl"),l.classList.add("modal-sm")):(l.classList.remove("modal-sm"),l.classList.remove("modal-md"),l.classList.remove("modal-lg"),l.classList.remove("modal-xl"),l.classList.add("modal-md"))}};