Htmx callback plugin and htmx based report view

This commit is contained in:
2026-09-01 00:01:03 +02:00
parent 71ba949cb5
commit 2832e76a31
7 changed files with 141 additions and 16 deletions
+4
View File
@@ -18,6 +18,7 @@ import { polyfillCountryFlagEmojis } from "country-flag-emoji-polyfill";
import { limitedChoices } from "#core:alpine/limited-choices";
import { expireOldStorage } from "#core:core/localstorage";
import { default as navbar } from "#core:core/navbar";
import { getErrorCallbacksExt } from "#core:htmx/error-callback";
import {
type NotificationPlugin,
notificationsPlugin as notifications,
@@ -62,6 +63,9 @@ document.body.addEventListener(
},
);
const errorCallbackExt = getErrorCallbacksExt();
htmx.registerExtension(errorCallbackExt.name, errorCallbackExt.extension);
Object.assign(window, { htmx });
/**
@@ -0,0 +1,74 @@
interface CustomHtmxExtension {
name: string;
extension: any;
}
export const getErrorCallbacksExt = () => {
const attrPrefix = "hx-callback-";
let htmxApi: { attributeValue: (arg0: HTMLElement, arg1: string) => string | null };
const getCallback = (elt: HTMLElement, responseCode: number) => {
if (!elt || !responseCode) {
return () => {};
}
const code = responseCode.toString();
// '*' is the original syntax, as the obvious character for a wildcard.
// The 'x' alternative was added for maximum compatibility with HTML
// templating engines, due to ambiguity around which characters are
// supported in HTML attributes.
//
// Start with the most specific possible attribute and generalize from
// there.
const suffixes = [
code,
`${code.substring(0, 2)}*`,
`${code.substring(0, 2)}x`,
`${code.substring(0, 1)}*`,
`${code.substring(0, 1)}x`,
`${code.substring(0, 1)}**`,
`${code.substring(0, 1)}xx`,
"*",
"x",
"***",
"xxx",
];
if (code.startsWith("4") || code.startsWith("5")) {
suffixes.push("error");
}
for (const suffix of suffixes) {
const attr = attrPrefix + suffix;
const callback = htmxApi?.attributeValue(elt, attr);
if (callback) {
return Function("src", "target", callback);
}
}
return () => {};
};
return {
name: "error-callbacks",
extension: {
init: (api: any) => {
htmxApi = api;
},
// biome-ignore lint/style/useNamingConvention: HTMX naming convention
htmx_response_error: (
elt: HTMLElement,
event: { ctx: any; cancelled: boolean },
) => {
if (event.cancelled) {
return false;
}
getCallback(elt, event.ctx.response.status)(elt, event.ctx.target);
return true;
},
},
} as CustomHtmxExtension;
};