BUGFIX: resetbutton

This commit is contained in:
Simon Martens
2025-05-30 20:40:20 +02:00
parent 8ea36da40f
commit dbed4e7e71
4 changed files with 158 additions and 105 deletions

View File

@@ -134,22 +134,38 @@ function ShowBoostedErrors() {
});
}
function FormHasChanged(form) {
if (!form || !(form instanceof HTMLFormElement)) {
return false;
}
const resetButton = form.querySelector("reset-button");
if (resetButton && resetButton.changed) {
return true;
// INFO: Hooks up to all the reset button children of the target element.
// If an element has a changed state, it will trigger the action with `true`.
// If no elements are changed, it will trigger the action with `false`.
// @param {HTMLElement} target - The parent element containing reset buttons.
// @param {Function} action - The function to call with the change state.
function HookupRBChange(target, action) {
if (!(target instanceof HTMLElement)) {
console.warn("Target must be an HTMLElement.");
return;
}
return false;
if (typeof action !== "function") {
console.warn("Action must be a function.");
return;
}
const btns = target.querySelectorAll(RESET_BUTTON_ELEMENT);
target.addEventListener("rbichange", (event) => {
for (const btn of btns) {
if (btn.isCurrentlyModified()) {
action(event.details, true);
return;
}
}
action(event.details, false);
});
}
window.ShowBoostedErrors = ShowBoostedErrors;
window.GenQRCode = GenQRCode;
window.SelectableInput = SelectableInput;
window.PathPlusQuery = PathPlusQuery;
window.FormHasChanged = FormHasChanged;
window.HookupRBChange = HookupRBChange;
export { FilterList, ScrollButton, AbbreviationTooltips, MultiSelectSimple, MultiSelectRole, ToolTip, PopupImage, TabList, FilterPill, ImageReel, IntLink };

View File

@@ -1,13 +1,12 @@
const RBI_BUTTON_BASE_CLASS = "rbi-button";
const RBI_ICON_CLASS = "rbi-icon";
export class ResetButton extends HTMLElement {
constructor() {
super();
this.initialStates = new Map();
this._controlledElements = [];
this.button = null;
this.changed = false;
this.lastOverallModifiedState = null;
this.handleInputChange = this.handleInputChange.bind(this);
this.handleReset = this.handleReset.bind(this);
@@ -18,7 +17,6 @@ export class ResetButton extends HTMLElement {
}
connectedCallback() {
// Use an HTML template literal string to define the button's structure
const buttonHTML = `
<button type="button" class="${RBI_BUTTON_BASE_CLASS} cursor-pointer disabled:cursor-default" aria-label="Reset field">
<tool-tip position="right">
@@ -27,13 +25,12 @@ export class ResetButton extends HTMLElement {
</tool-tip>
</button>
`;
this.innerHTML = buttonHTML; // Set the inner HTML of the custom element
this.button = this.querySelector("button"); // Get the button element
this.innerHTML = buttonHTML;
this.button = this.querySelector("button");
if (this.button) {
this.button.addEventListener("click", this.handleReset);
} else {
// This case should ideally not be reached if the HTML string is correct
console.error("ResetButtonIndividual: Button element not found after setting innerHTML.");
}
@@ -69,6 +66,7 @@ export class ResetButton extends HTMLElement {
});
this._controlledElements = [];
this.initialStates.clear();
this.lastOverallModifiedState = null;
const controlIds = (this.getAttribute("controls") || "")
.split(",")
@@ -78,6 +76,7 @@ export class ResetButton extends HTMLElement {
if (!controlIds.length && this.button) {
this.button.disabled = true;
this.button.setAttribute("aria-disabled", "true");
this.checkIfModified();
return;
}
@@ -165,6 +164,7 @@ export class ResetButton extends HTMLElement {
}
}
// Internal helper to check a single element
isElementModified(element) {
const initialState = this.initialStates.get(element.id);
if (!initialState) return false;
@@ -185,12 +185,25 @@ export class ResetButton extends HTMLElement {
}
}
// Public method to check overall modification state
isCurrentlyModified() {
if (this._controlledElements.length === 0) {
return false; // Not modified if there are no elements to control
}
for (const el of this._controlledElements) {
if (this.isElementModified(el)) {
return true; // Found one modified element
}
}
return false; // No elements were modified
}
checkIfModified() {
let overallModified = false;
const overallModified = this.isCurrentlyModified(); // Use the new public method
// Update classes for controlled elements
this._controlledElements.forEach((el) => {
const modified = this.isElementModified(el);
if (modified) {
overallModified = true;
if (this.isElementModified(el)) {
el.classList.add("modified-element");
} else {
el.classList.remove("modified-element");
@@ -220,7 +233,7 @@ export class ResetButton extends HTMLElement {
}
}
if (this.changed !== overallModified) {
if (this.lastOverallModifiedState !== overallModified) {
const event = new CustomEvent("rbichange", {
bubbles: true,
composed: true,
@@ -231,7 +244,7 @@ export class ResetButton extends HTMLElement {
},
});
this.dispatchEvent(event);
this.changed = overallModified;
this.lastOverallModifiedState = overallModified;
}
}