From 37e15c270be153ee0d24c9aee370d28c6e5f5c03 Mon Sep 17 00:00:00 2001 From: ChuckBuilds Date: Sat, 4 Jul 2026 20:41:11 -0400 Subject: [PATCH] fix: array-table boolean columns always saved as unchecked MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported bug: countdown plugin always shows "No Active" even with a countdown configured and enabled — because every save silently unchecked it. Root cause: the boolean column's hidden-sentinel input (needed so unchecked checkboxes still submit "false", since browsers omit unchecked checkboxes entirely) was hardcoded to value="false" and shared the same `name` as the checkbox, with no sync between them. Whichever of the two same-named inputs the save request's form-collection happens to prefer, the hidden's stale "false" could silently override an actually-checked box on every save, independent of what the user set. Fixed in both places this pattern is rendered: - plugin_config.html: the initial server-rendered row for every array-table boolean column (affects countdown's per-countdown "enabled" and the custom-feeds widget's per-feed "enabled") — now sets the hidden's initial value from the actual data, and syncs it via onchange on every toggle. - array-table.js: the client-side row renderer used when adding/rebuilding rows in the browser — same fix, keeping both inputs in sync at render time and via a change listener. Verified other checkbox/hidden-input patterns in plugin_config.html and confirmed they're unrelated/already-safe: the default single-checkbox renderer (no hidden pair), checkbox-group (array-bracket names with its own explicit sync), the array-table advanced-props modal editor (single hidden per name, explicitly written on Save), the top-level plugin enable/disable toggle (separate immediate hx-post), and the no-schema fallback checkbox. custom-feeds.js's own client-side row renderer never creates a hidden sentinel at all, so it isn't affected either. Verified the fix's rendered output directly with an isolated Jinja render of the exact snippet: hidden and checkbox now agree ("true"/checked or "false"/unchecked) for both states, where before the hidden was always "false" regardless of the actual value. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01KEZK1P1Q1fu5pcuVrkrCFZ --- .../static/v3/js/widgets/array-table.js | 12 ++++++++++-- .../templates/v3/partials/plugin_config.html | 16 ++++++++++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/web_interface/static/v3/js/widgets/array-table.js b/web_interface/static/v3/js/widgets/array-table.js index 77e82edfc..a42fd08f2 100644 --- a/web_interface/static/v3/js/widgets/array-table.js +++ b/web_interface/static/v3/js/widgets/array-table.js @@ -174,11 +174,16 @@ cell.style.verticalAlign = 'middle'; if (colType === 'boolean') { - // Boolean: hidden sentinel + visible checkbox + // Boolean: hidden sentinel + visible checkbox, same `name` (so + // unchecked boxes still submit "false"). Keep the hidden's value + // synced to the checkbox at all times — some form-collection + // paths prefer whichever of the two same-named inputs comes + // first/last in the DOM, and a stale hidden value previously + // caused this field to silently revert to false on every save. const hidden = document.createElement('input'); hidden.type = 'hidden'; hidden.name = inputName; - hidden.value = 'false'; + hidden.value = String(Boolean(colValue)); cell.appendChild(hidden); const cb = document.createElement('input'); @@ -187,6 +192,9 @@ cb.checked = Boolean(colValue); cb.value = 'true'; cb.className = 'h-4 w-4 text-blue-600'; + cb.addEventListener('change', () => { + hidden.value = String(cb.checked); + }); cell.appendChild(cb); } else if (colType === 'integer' || colType === 'number') { diff --git a/web_interface/templates/v3/partials/plugin_config.html b/web_interface/templates/v3/partials/plugin_config.html index 12fdfc4d9..d0857d49f 100644 --- a/web_interface/templates/v3/partials/plugin_config.html +++ b/web_interface/templates/v3/partials/plugin_config.html @@ -450,15 +450,16 @@ - - + -