Files
linkding/bookmarks/frontend/components/form.js
2026-01-01 01:08:54 +01:00

72 lines
1.9 KiB
JavaScript

import { HeadlessElement } from "../utils/element.js";
class Form extends HeadlessElement {
constructor() {
super();
this.onKeyDown = this.onKeyDown.bind(this);
this.onChange = this.onChange.bind(this);
}
init() {
this.addEventListener("keydown", this.onKeyDown);
this.addEventListener("change", this.onChange);
if (this.hasAttribute("data-form-reset")) {
// Resets form controls to their initial values before Turbo caches the DOM.
// Useful for filter forms where navigating back would otherwise still show
// values from after the form submission, which means the filters would be out
// of sync with the URL.
this.initFormReset();
}
}
disconnectedCallback() {
if (this.hasAttribute("data-form-reset")) {
this.resetForm();
}
}
onChange(event) {
if (event.target.hasAttribute("data-submit-on-change")) {
this.querySelector("form")?.requestSubmit();
}
}
onKeyDown(event) {
// Check for Ctrl/Cmd + Enter combination
if (
this.hasAttribute("data-submit-on-ctrl-enter") &&
event.key === "Enter" &&
(event.metaKey || event.ctrlKey)
) {
event.preventDefault();
event.stopPropagation();
this.querySelector("form")?.requestSubmit();
}
}
initFormReset() {
this.controls = this.querySelectorAll("input, select");
this.controls.forEach((control) => {
if (control.type === "checkbox" || control.type === "radio") {
control.__initialValue = control.checked;
} else {
control.__initialValue = control.value;
}
});
}
resetForm() {
this.controls.forEach((control) => {
if (control.type === "checkbox" || control.type === "radio") {
control.checked = control.__initialValue;
} else {
control.value = control.__initialValue;
}
delete control.__initialValue;
});
}
}
customElements.define("ld-form", Form);