mirror of
https://github.com/sissbruecker/linkding
synced 2024-11-21 19:03:02 +00:00
Add clear buttons in bookmark form (#846)
This commit is contained in:
parent
c5c5949d20
commit
ed57da3c99
5 changed files with 101 additions and 41 deletions
42
bookmarks/frontend/behaviors/clear-button.js
Normal file
42
bookmarks/frontend/behaviors/clear-button.js
Normal file
|
@ -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);
|
|
@ -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, {
|
mutationObserver.observe(document.body, {
|
||||||
childList: true,
|
childList: true,
|
||||||
subtree: true,
|
subtree: true,
|
||||||
|
@ -41,7 +58,6 @@ Behavior.interacting = false;
|
||||||
|
|
||||||
export function registerBehavior(name, behavior) {
|
export function registerBehavior(name, behavior) {
|
||||||
behaviorRegistry[name] = behavior;
|
behaviorRegistry[name] = behavior;
|
||||||
applyBehaviors(document, [name]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function applyBehaviors(container, behaviorNames = null) {
|
export function applyBehaviors(container, behaviorNames = null) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import "@hotwired/turbo";
|
import "@hotwired/turbo";
|
||||||
import "./behaviors/bookmark-page";
|
import "./behaviors/bookmark-page";
|
||||||
import "./behaviors/bulk-edit";
|
import "./behaviors/bulk-edit";
|
||||||
|
import "./behaviors/clear-button";
|
||||||
import "./behaviors/confirm-button";
|
import "./behaviors/confirm-button";
|
||||||
import "./behaviors/dropdown";
|
import "./behaviors/dropdown";
|
||||||
import "./behaviors/form";
|
import "./behaviors/form";
|
||||||
|
|
|
@ -1,48 +1,38 @@
|
||||||
.bookmarks-form-page {
|
.bookmarks-form-page {
|
||||||
section {
|
section {
|
||||||
max-width: 550px;
|
max-width: 550px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.bookmarks-form {
|
.bookmarks-form {
|
||||||
& .btn.btn-link.form-icon {
|
& .has-icon-right > input, & .has-icon-right > textarea {
|
||||||
padding: 0;
|
padding-right: 30px;
|
||||||
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 {
|
& .form-icon.loading {
|
||||||
padding-right: 30px;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
& .has-icon-right > input:placeholder-shown ~ .btn.form-icon,
|
& .form-group .clear-button {
|
||||||
& .has-icon-right > textarea:placeholder-shown ~ .btn.form-icon {
|
display: none;
|
||||||
visibility: visible;
|
padding: 0;
|
||||||
}
|
border: none;
|
||||||
|
height: auto;
|
||||||
|
font-size: var(--font-size-sm);
|
||||||
|
}
|
||||||
|
|
||||||
& .form-icon.loading {
|
& .form-input-hint.bookmark-exists {
|
||||||
visibility: hidden;
|
display: none;
|
||||||
}
|
color: var(--warning-color);
|
||||||
|
}
|
||||||
|
|
||||||
& .form-input-hint.bookmark-exists {
|
& .form-input-hint.auto-tags {
|
||||||
display: none;
|
display: none;
|
||||||
color: var(--warning-color);
|
color: var(--success-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
& .form-input-hint.auto-tags {
|
& details.notes textarea {
|
||||||
display: none;
|
box-sizing: border-box;
|
||||||
color: var(--success-color);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
& details.notes textarea {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -31,12 +31,22 @@
|
||||||
{{ form.tag_string.errors }}
|
{{ form.tag_string.errors }}
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="{{ form.title.id_for_label }}" class="form-label">Title</label>
|
<div class="d-flex justify-between align-baseline">
|
||||||
|
<label for="{{ form.title.id_for_label }}" class="form-label">Title</label>
|
||||||
|
<button ld-clear-button data-for="{{ form.title.id_for_label }}" class="btn btn-link clear-button"
|
||||||
|
type="button">Clear
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
{{ form.title|add_class:"form-input"|attr:"autocomplete:off" }}
|
{{ form.title|add_class:"form-input"|attr:"autocomplete:off" }}
|
||||||
{{ form.title.errors }}
|
{{ form.title.errors }}
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="{{ form.description.id_for_label }}" class="form-label">Description</label>
|
<div class="d-flex justify-between align-baseline">
|
||||||
|
<label for="{{ form.description.id_for_label }}" class="form-label">Description</label>
|
||||||
|
<button ld-clear-button data-for="{{ form.description.id_for_label }}" class="btn btn-link clear-button"
|
||||||
|
type="button">Clear
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
{{ form.description|add_class:"form-input"|attr:"rows:3" }}
|
{{ form.description|add_class:"form-input"|attr:"rows:3" }}
|
||||||
{{ form.description.errors }}
|
{{ form.description.errors }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -116,6 +126,7 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
input.value = value;
|
input.value = value;
|
||||||
|
input.dispatchEvent(new Event('value-changed'));
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateCheckbox(input, value) {
|
function updateCheckbox(input, value) {
|
||||||
|
|
Loading…
Reference in a new issue