3
0
Эх сурвалжийг харах

Save name/PIN edits on blur, restrict PIN input to digits

Mobile users often can't easily hit Enter to commit an inline edit, so
blur now saves too (name: non-blank and changed; PIN: valid 4-8 digit
length). Escape still cancels without saving. PIN fields also get
inputmode=numeric plus JS-level digit filtering, since only numeric
codes are supported.
ZiB 3 сар өмнө
parent
commit
72542fb010

+ 29 - 5
custom_components/zlock_slots/frontend/zlock-slots-card.js

@@ -128,7 +128,7 @@ class ZLockSlotsCard extends HTMLElement {
                           ${s.name != null ? escapeHtml(s.name) : '<em style="opacity:.4">unnamed</em>'}
                         </span>
                         <span class="inline-edit" id="name-edit-${s.slot_num}" style="display:none">
-                          <input id="name-input-${s.slot_num}" type="text" value="${escapeHtml(s.name ?? '')}" placeholder="Enter name — Enter to save, Esc to cancel" data-slot="${s.slot_num}" />
+                          <input id="name-input-${s.slot_num}" type="text" value="${escapeHtml(s.name ?? '')}" placeholder="Enter name" data-slot="${s.slot_num}" />
                         </span>
                       </td>
                       <td class="actions-cell">
@@ -149,7 +149,7 @@ class ZLockSlotsCard extends HTMLElement {
                       <td colspan="3">
                         <div class="pin-edit">
                           <label>New PIN</label>
-                          <input id="pin-input-${s.slot_num}" type="password" minlength="4" maxlength="8" autocomplete="one-time-code" placeholder="4–8 digits — Enter to save, Esc to cancel" data-slot="${s.slot_num}" data-type="pin" />
+                          <input id="pin-input-${s.slot_num}" type="password" inputmode="numeric" pattern="[0-9]*" minlength="4" maxlength="8" autocomplete="one-time-code" placeholder="4–8 digits" data-slot="${s.slot_num}" data-type="pin" />
                         </div>
                       </td>
                     </tr>
@@ -167,7 +167,7 @@ class ZLockSlotsCard extends HTMLElement {
             </div>
             <div class="field pin">
               <label>PIN</label>
-              <input id="add-code" type="password" minlength="4" maxlength="8" autocomplete="one-time-code" placeholder="4–8 digits" />
+              <input id="add-code" type="password" inputmode="numeric" pattern="[0-9]*" minlength="4" maxlength="8" autocomplete="one-time-code" placeholder="4–8 digits" />
             </div>
             <button class="action" id="add-btn">Set</button>
           </div>
@@ -229,9 +229,17 @@ class ZLockSlotsCard extends HTMLElement {
       root.getElementById(`pin-edit-row-${slot}`).style.display = "none";
     };
 
+    const digitsOnly = (input) => {
+      input.addEventListener("input", () => {
+        const filtered = input.value.replace(/\D/g, "");
+        if (filtered !== input.value) input.value = filtered;
+      });
+    };
+
     root.querySelectorAll("input[data-slot]").forEach(input => {
       const slot = parseInt(input.dataset.slot, 10);
       const isPin = input.dataset.type === "pin";
+      if (isPin) digitsOnly(input);
 
       input.addEventListener("keydown", async (e) => {
         if (e.key === "Enter") {
@@ -253,13 +261,29 @@ class ZLockSlotsCard extends HTMLElement {
         }
       });
 
-      input._blurHandler = () => isPin ? closePin(slot) : closeName(slot);
+      input._blurHandler = async () => {
+        if (isPin) {
+          const code = input.value;
+          closePin(slot);
+          if (code.length >= 4 && code.length <= 8) {
+            await this._callService("set_code", { ...target, slot, code });
+          }
+        } else {
+          const name = input.value.trim();
+          closeName(slot);
+          if (name && name !== (input.defaultValue ?? "").trim()) {
+            await this._callService("set_name", { ...target, slot, name });
+          }
+        }
+      };
       input.addEventListener("blur", input._blurHandler);
     });
 
+    const codeInput = root.getElementById("add-code");
+    if (codeInput) digitsOnly(codeInput);
+
     root.getElementById("add-btn")?.addEventListener("click", async () => {
       const slotInput = root.getElementById("add-slot");
-      const codeInput = root.getElementById("add-code");
       const status = root.getElementById("add-status");
 
       const slotVal = slotInput.value ? parseInt(slotInput.value, 10) : undefined;