Implement `Dom/Util.innerSuccess()`
authorAlexander Ebert <ebert@woltlab.com>
Sun, 2 May 2021 10:12:12 +0000 (12:12 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Sun, 2 May 2021 10:12:12 +0000 (12:12 +0200)
Closes #4170

ts/WoltLabSuite/Core/Dom/Util.ts
wcfsetup/install/files/js/WoltLabSuite/Core/Dom/Util.js

index a630f6cb0cfe9833dee720cabc6e5e6d0ce6ff87..838c52b4ca24cfa6f373b32295ad9816be40f663 100644 (file)
@@ -449,7 +449,7 @@ const DomUtil = {
       }
     }
 
-    let innerError = element.nextElementSibling;
+    let innerError = element.nextElementSibling as HTMLElement | null;
     if (innerError === null || innerError.nodeName !== "SMALL" || !innerError.classList.contains("innerError")) {
       if (errorMessage === "") {
         innerError = null;
@@ -466,10 +466,64 @@ const DomUtil = {
         innerError = null;
       }
     } else {
-      innerError![isHtml ? "innerHTML" : "textContent"] = errorMessage;
+      if (isHtml) {
+        innerError!.innerHTML = errorMessage;
+      } else {
+        innerError!.textContent = errorMessage;
+      }
+    }
+
+    return innerError;
+  },
+
+  /**
+   * Displays or removes an error message below the provided element.
+   */
+  innerSuccess(element: HTMLElement, message?: string | false | null, isHtml?: boolean): HTMLElement | null {
+    const parent = element.parentNode;
+    if (parent === null) {
+      throw new Error("Only elements that have a parent element or document are valid.");
+    }
+
+    if (typeof message !== "string") {
+      if (!message) {
+        message = "";
+      } else {
+        throw new TypeError(
+          "The message must be a string; `false`, `null` or `undefined` can be used as a substitute for an empty string.",
+        );
+      }
+    }
+
+    let innerSuccess = element.nextElementSibling as HTMLElement | null;
+    if (
+      innerSuccess === null ||
+      innerSuccess.nodeName !== "SMALL" ||
+      !innerSuccess.classList.contains("innerSuccess")
+    ) {
+      if (message === "") {
+        innerSuccess = null;
+      } else {
+        innerSuccess = document.createElement("small");
+        innerSuccess.className = "innerSuccess";
+        parent.insertBefore(innerSuccess, element.nextSibling);
+      }
+    }
+
+    if (message === "") {
+      if (innerSuccess !== null) {
+        innerSuccess.remove();
+        innerSuccess = null;
+      }
+    } else {
+      if (isHtml) {
+        innerSuccess!.innerHTML = message;
+      } else {
+        innerSuccess!.textContent = message;
+      }
     }
 
-    return innerError as HTMLElement | null;
+    return innerSuccess;
   },
 
   /**
index 6f07819176d7348a51c535aa35f45e9477ed792a..49f7a0ed7fcc427af55a14b083eeb63ddb5cb57b 100644 (file)
@@ -398,10 +398,60 @@ define(["require", "exports", "tslib", "../StringUtil"], function (require, expo
                 }
             }
             else {
-                innerError[isHtml ? "innerHTML" : "textContent"] = errorMessage;
+                if (isHtml) {
+                    innerError.innerHTML = errorMessage;
+                }
+                else {
+                    innerError.textContent = errorMessage;
+                }
             }
             return innerError;
         },
+        /**
+         * Displays or removes an error message below the provided element.
+         */
+        innerSuccess(element, message, isHtml) {
+            const parent = element.parentNode;
+            if (parent === null) {
+                throw new Error("Only elements that have a parent element or document are valid.");
+            }
+            if (typeof message !== "string") {
+                if (!message) {
+                    message = "";
+                }
+                else {
+                    throw new TypeError("The message must be a string; `false`, `null` or `undefined` can be used as a substitute for an empty string.");
+                }
+            }
+            let innerSuccess = element.nextElementSibling;
+            if (innerSuccess === null ||
+                innerSuccess.nodeName !== "SMALL" ||
+                !innerSuccess.classList.contains("innerSuccess")) {
+                if (message === "") {
+                    innerSuccess = null;
+                }
+                else {
+                    innerSuccess = document.createElement("small");
+                    innerSuccess.className = "innerSuccess";
+                    parent.insertBefore(innerSuccess, element.nextSibling);
+                }
+            }
+            if (message === "") {
+                if (innerSuccess !== null) {
+                    innerSuccess.remove();
+                    innerSuccess = null;
+                }
+            }
+            else {
+                if (isHtml) {
+                    innerSuccess.innerHTML = message;
+                }
+                else {
+                    innerSuccess.textContent = message;
+                }
+            }
+            return innerSuccess;
+        },
         /**
          * Finds the closest element that matches the provided selector. This is a helper
          * function because `closest()` does exist on elements only, for example, it is