]> jfr.im git - irc/unrealircd/unrealircd-webpanel.git/commitdiff
JS: Dynamic modal dialogs, and move toasts to own file
authorValerie Pond <redacted>
Fri, 28 Apr 2023 23:39:17 +0000 (00:39 +0100)
committerValerie Pond <redacted>
Fri, 28 Apr 2023 23:39:17 +0000 (00:39 +0100)
js/bs-modal.js [new file with mode: 0644]
js/bs-toast.js [new file with mode: 0644]

diff --git a/js/bs-modal.js b/js/bs-modal.js
new file mode 100644 (file)
index 0000000..d87f6c1
--- /dev/null
@@ -0,0 +1,74 @@
+/**
+ * Generate a bootstrap modal
+ * Mandatory:
+ * @param {string} title - The modal title
+ * @param {string} body - HTML for the body
+ * @param {string} footer - HTML for the footer
+ * 
+ * Optional:
+ * @param {string} size - the bootstrap size category for modals (sm, lg, xl)
+ * @param {boolean} static - whether or not to make the backdrop static, forcing the user to respond to the dialog
+ * @param {boolean} show - whether or not to automatically show the modal
+ * @returns {string} returns the ID
+ */
+
+function bsModal(title, body, footer, size = null, static = false, show = false)
+{
+    /* generate a random number between 1000 and 90000 to use as an id */
+    const min = 1000;
+    const max = 90000;
+    id = Date.now().toString(36); // base36 unique id
+    ourSize = "";
+    if (size)
+        ourSize += "modal-" + size;
+
+    const m1 = document.createElement("div");
+    const m2 = m1.cloneNode();
+    const m3 = m1.cloneNode();
+    const mHeader = m1.cloneNode();
+    const mBody = m1.cloneNode();
+    const mFooter = m1.cloneNode();
+
+    m1.classList.add("modal", "fade");
+    m1.id = id;
+    m1.role = "dialog";
+    m1.ariaHidden = "true";
+
+    m2.classList.add("modal-dialog", "modal-dialog-centered");
+    if (ourSize.length)
+        m2.classList.add(ourSize);
+
+    m2.role = "document";
+    m2.id = id + "-2";
+
+    m3.classList.add("modal-content");
+    m3.id = id + "-3";
+
+    mHeader.classList.add("modal-header");
+    mHeader.id = id + "-header";
+    mHeader.innerHTML =`<h5 class="modal-title" id="` + id + `"-title">` + title + `</h5>
+                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">&times;</span></button>`;
+    
+    mBody.classList.add("modal-body");
+    mBody.id = id + "-body";
+    mBody.innerHTML = body;
+
+    mFooter.classList.add("modal-footer");
+    mFooter.id = id + "-footer";
+    mFooter.innerHTML = footer;
+
+    m1.appendChild(m2);
+    m2.appendChild(m3);
+    m3.appendChild(mHeader);
+    m3.appendChild(mBody);
+    m3.appendChild(mFooter);
+
+    document.body.append(m1);
+    
+    if (static)
+        $('#' + m1.id).modal({ backdrop: "static" });
+
+    if (show)
+        $('#' + m1.id).modal('show');
+}
diff --git a/js/bs-toast.js b/js/bs-toast.js
new file mode 100644 (file)
index 0000000..9b1fea9
--- /dev/null
@@ -0,0 +1,55 @@
+
+/* Popup notifications */
+
+function generate_notif(title, body)
+{
+    /* generate a random number between 1000 and 90000 to use as an id */
+    const min = 1000;
+    const max = 90000;
+    const id = Math.floor(Math.random() * (max - min + 1)) + min;
+
+    const toast = document.createElement('div');
+    toast.classList.add('toast', 'hide');
+    toast.id = 'toast' + id;
+    toast.role = 'alert';
+    toast.ariaLive = 'assertive';
+    toast.ariaAtomic = 'true';
+    toast.setAttribute('data-delay', '10000');
+
+    const header = document.createElement('div');
+    header.classList.add('toast-header');
+
+    const theTitle = document.createElement('strong');
+    theTitle.classList.add('mr-auto');
+    theTitle.textContent = title;
+    
+    const notiftime = document.createElement('div');
+    notiftime.classList.add('badge', 'rounded-pill', 'badge-primary', 'ml-1');
+    notiftime.textContent = 'Just now'; // always just now I think right :D
+
+    const closebutton = document.createElement('button');
+    closebutton.type = 'button';
+    closebutton.classList.add('ml-2', 'mb-1', 'close');
+    closebutton.setAttribute('data-dismiss', 'toast');
+    closebutton.ariaLabel = 'Close';
+
+    const closebuttonspan = document.createElement('span');
+    closebuttonspan.ariaHidden = 'true';
+    closebuttonspan.innerHTML = "&times;";
+
+    const toastbody = document.createElement('div');
+    toastbody.classList.add('toast-body');
+    toastbody.textContent = body;
+
+
+    /* put it all together */
+    closebutton.appendChild(closebuttonspan);
+    header.appendChild(theTitle);
+    header.appendChild(notiftime);
+    header.appendChild(closebutton);
+    toast.appendChild(header);
+    toast.appendChild(toastbody);
+    document.getElementById('toaster').append(toast);
+
+    $('#' + toast.id).toast('show');
+}