From ed57da3c992e0d512757363a9d5453c4199d07f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sascha=20I=C3=9Fbr=C3=BCcker?= Date: Mon, 23 Sep 2024 11:02:30 +0200 Subject: [PATCH] Add clear buttons in bookmark form (#846) --- bookmarks/frontend/behaviors/clear-button.js | 42 +++++++++++++ bookmarks/frontend/behaviors/index.js | 20 +++++- bookmarks/frontend/index.js | 1 + bookmarks/styles/bookmark-form.css | 64 +++++++++----------- bookmarks/templates/bookmarks/form.html | 15 ++++- 5 files changed, 101 insertions(+), 41 deletions(-) create mode 100644 bookmarks/frontend/behaviors/clear-button.js diff --git a/bookmarks/frontend/behaviors/clear-button.js b/bookmarks/frontend/behaviors/clear-button.js new file mode 100644 index 0000000..3f0b476 --- /dev/null +++ b/bookmarks/frontend/behaviors/clear-button.js @@ -0,0 +1,42 @@ +import { Behavior, registerBehavior } from "./index"; + +class ClearButtonBehavior extends Behavior { + constructor(element) { + super(element); + + this.field = document.getElementById(element.dataset.for); + if (!this.field) { + console.error(`Field with ID ${element.dataset.for} not found`); + return; + } + + this.update = this.update.bind(this); + this.clear = this.clear.bind(this); + + this.element.addEventListener("click", this.clear); + this.field.addEventListener("input", this.update); + this.field.addEventListener("value-changed", this.update); + this.update(); + } + + destroy() { + if (!this.field) { + return; + } + this.element.removeEventListener("click", this.clear); + this.field.removeEventListener("input", this.update); + this.field.removeEventListener("value-changed", this.update); + } + + update() { + this.element.style.display = this.field.value ? "inline-flex" : "none"; + } + + clear() { + this.field.value = ""; + this.field.focus(); + this.update(); + } +} + +registerBehavior("ld-clear-button", ClearButtonBehavior); diff --git a/bookmarks/frontend/behaviors/index.js b/bookmarks/frontend/behaviors/index.js index c973ce2..2b14bd5 100644 --- a/bookmarks/frontend/behaviors/index.js +++ b/bookmarks/frontend/behaviors/index.js @@ -16,7 +16,24 @@ const mutationObserver = new MutationObserver((mutations) => { }); }); -document.addEventListener("turbo:load", () => { +// Update behaviors on Turbo events +// - turbo:load: initial page load, only listen once, afterward can rely on turbo:render +// - turbo:render: after page navigation, including back/forward, and failed form submissions +// - turbo:before-cache: before page navigation, reset DOM before caching +document.addEventListener( + "turbo:load", + () => { + mutationObserver.observe(document.body, { + childList: true, + subtree: true, + }); + + applyBehaviors(document.body); + }, + { once: true }, +); + +document.addEventListener("turbo:render", () => { mutationObserver.observe(document.body, { childList: true, subtree: true, @@ -41,7 +58,6 @@ Behavior.interacting = false; export function registerBehavior(name, behavior) { behaviorRegistry[name] = behavior; - applyBehaviors(document, [name]); } export function applyBehaviors(container, behaviorNames = null) { diff --git a/bookmarks/frontend/index.js b/bookmarks/frontend/index.js index 0ad14e4..789ff11 100644 --- a/bookmarks/frontend/index.js +++ b/bookmarks/frontend/index.js @@ -1,6 +1,7 @@ import "@hotwired/turbo"; import "./behaviors/bookmark-page"; import "./behaviors/bulk-edit"; +import "./behaviors/clear-button"; import "./behaviors/confirm-button"; import "./behaviors/dropdown"; import "./behaviors/form"; diff --git a/bookmarks/styles/bookmark-form.css b/bookmarks/styles/bookmark-form.css index 25c8eaf..77b4049 100644 --- a/bookmarks/styles/bookmark-form.css +++ b/bookmarks/styles/bookmark-form.css @@ -1,48 +1,38 @@ .bookmarks-form-page { - section { - max-width: 550px; - margin: 0 auto; - } + section { + max-width: 550px; + margin: 0 auto; + } } .bookmarks-form { - & .btn.btn-link.form-icon { - padding: 0; - width: 20px; - height: 20px; - visibility: hidden; - --btn-icon-color: var(--tertiary-text-color); - - & > svg { - width: 20px; - height: 20px; + & .has-icon-right > input, & .has-icon-right > textarea { + padding-right: 30px; } - } - & .has-icon-right > input, & .has-icon-right > textarea { - padding-right: 30px; - } + & .form-icon.loading { + visibility: hidden; + } - & .has-icon-right > input:placeholder-shown ~ .btn.form-icon, - & .has-icon-right > textarea:placeholder-shown ~ .btn.form-icon { - visibility: visible; - } + & .form-group .clear-button { + display: none; + padding: 0; + border: none; + height: auto; + font-size: var(--font-size-sm); + } - & .form-icon.loading { - visibility: hidden; - } + & .form-input-hint.bookmark-exists { + display: none; + color: var(--warning-color); + } - & .form-input-hint.bookmark-exists { - display: none; - color: var(--warning-color); - } + & .form-input-hint.auto-tags { + display: none; + color: var(--success-color); + } - & .form-input-hint.auto-tags { - display: none; - color: var(--success-color); - } - - & details.notes textarea { - box-sizing: border-box; - } + & details.notes textarea { + box-sizing: border-box; + } } \ No newline at end of file diff --git a/bookmarks/templates/bookmarks/form.html b/bookmarks/templates/bookmarks/form.html index 5d053f4..1cb723a 100644 --- a/bookmarks/templates/bookmarks/form.html +++ b/bookmarks/templates/bookmarks/form.html @@ -31,12 +31,22 @@ {{ form.tag_string.errors }}
- +
+ + +
{{ form.title|add_class:"form-input"|attr:"autocomplete:off" }} {{ form.title.errors }}
- +
+ + +
{{ form.description|add_class:"form-input"|attr:"rows:3" }} {{ form.description.errors }}
@@ -116,6 +126,7 @@ return; } input.value = value; + input.dispatchEvent(new Event('value-changed')); } function updateCheckbox(input, value) {