Use the `input` event to detect the comma on Chromium for Android
authorAlexander Ebert <ebert@woltlab.com>
Wed, 27 Jan 2021 12:23:11 +0000 (13:23 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Wed, 27 Jan 2021 12:23:11 +0000 (13:23 +0100)
ts/WoltLabSuite/Core/Ui/ItemList.ts
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/ItemList.js

index d107695b31504986e88eddf2e1da1ddb0639ffe9..4da547d925c546b8beec07322fbd9ac72f3e553f 100644 (file)
@@ -36,6 +36,7 @@ function createUI(element: ItemListInputElement, options: ItemListOptions): UiDa
   const listItem = document.createElement("li");
   listItem.className = "input";
   list.appendChild(listItem);
+  element.addEventListener("input", input);
   element.addEventListener("keydown", keyDown);
   element.addEventListener("keypress", keyPress);
   element.addEventListener("keyup", keyUp);
@@ -153,10 +154,11 @@ function keyDown(event: KeyboardEvent): void {
 }
 
 /**
- * Handles the `[ENTER]` and `[,]` key to add an item to the list unless it is restricted.
+ * Detects the Enter key to add an item to the list. This must not be
+ * part of the `keydown` handler to prevent conflicts with the suggestions.
  */
 function keyPress(event: KeyboardEvent): void {
-  if (event.key === "Enter" || event.key === ",") {
+  if (event.key === "Enter") {
     event.preventDefault();
 
     const input = event.currentTarget as HTMLInputElement;
@@ -171,6 +173,30 @@ function keyPress(event: KeyboardEvent): void {
   }
 }
 
+/**
+ * Detects changes to the value of an input element to find a comma. This was
+ * previously checked in the `keypress` event, but Chromium on Android cripples
+ * the event to not expose any key whatsoever.
+ */
+function input(event: InputEvent): void {
+  const input = event.currentTarget as HTMLInputElement;
+  if (_data.get(input.id)!.options.restricted) {
+    // restricted item lists only allow results from the dropdown to be picked
+    return;
+  }
+
+  let value = input.value;
+  if (value.includes(",")) {
+    // Remove the comma and forward it.
+    value = value.replace(/,/g, "");
+    if (value.length) {
+      addItem(input.id, { objectId: 0, value: value });
+    } else {
+      input.value = value;
+    }
+  }
+}
+
 /**
  * Splits comma-separated values being pasted into the input field.
  */
index 84969cab6d179eee141476d7add14abfa95821b0..bcd8651e554381ea9324aa79ad81b12aa17e7de2 100644 (file)
@@ -34,6 +34,7 @@ define(["require", "exports", "tslib", "../Core", "../Dom/Traverse", "../Languag
         const listItem = document.createElement("li");
         listItem.className = "input";
         list.appendChild(listItem);
+        element.addEventListener("input", input);
         element.addEventListener("keydown", keyDown);
         element.addEventListener("keypress", keyPress);
         element.addEventListener("keyup", keyUp);
@@ -139,10 +140,11 @@ define(["require", "exports", "tslib", "../Core", "../Dom/Traverse", "../Languag
         }
     }
     /**
-     * Handles the `[ENTER]` and `[,]` key to add an item to the list unless it is restricted.
+     * Detects the Enter key to add an item to the list. This must not be
+     * part of the `keydown` handler to prevent conflicts with the suggestions.
      */
     function keyPress(event) {
-        if (event.key === "Enter" || event.key === ",") {
+        if (event.key === "Enter") {
             event.preventDefault();
             const input = event.currentTarget;
             if (_data.get(input.id).options.restricted) {
@@ -155,6 +157,29 @@ define(["require", "exports", "tslib", "../Core", "../Dom/Traverse", "../Languag
             }
         }
     }
+    /**
+     * Detects changes to the value of an input element to find a comma. This was
+     * previously checked in the `keypress` event, but Chromium on Android cripples
+     * the event to not expose any key whatsoever.
+     */
+    function input(event) {
+        const input = event.currentTarget;
+        if (_data.get(input.id).options.restricted) {
+            // restricted item lists only allow results from the dropdown to be picked
+            return;
+        }
+        let value = input.value;
+        if (value.includes(",")) {
+            // Remove the comma and forward it.
+            value = value.replace(/,/g, "");
+            if (value.length) {
+                addItem(input.id, { objectId: 0, value: value });
+            }
+            else {
+                input.value = value;
+            }
+        }
+    }
     /**
      * Splits comma-separated values being pasted into the input field.
      */