hx-on is not working for custom events
Taking this video as reference I've tried to fire a custom event with hx-on attribute but is not working.
Client-side code:
export default function Home({people}: TProps) {
return (
<Layout>
<div>
<h2>Phonebook</h2>
<form
hx-post="/api/contacts"
hx-swap="innerHTML"
hx-target="#listing-box"
hx-on--after-request="this.reset()"
hx-on--customevent="console.log('chesu!!')"
>
<div>
<label for="name">Name: </label>
<input type="text" name="name" id="name"/>
</div>
<div>
<button type="submit">add</button>
</div>
</form>
<h2>Numbers</h2>
<div id="listing-box">
<PeopleListingBox {...{people}}/>
</div>
</div>
</Layout>
)
}
Layout component code:
export default function Layout({ children, title = 'My App' } : TProps) {
return (
<>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="/public/img/elysia.png"></link>
<link rel="stylesheet" href="/public/styles/main.css"></link>
<script src="https://unpkg.com/[email protected]" integrity="sha384-ujb1lZYygJmzgSwoxRggbCHcjc0rB2XoQrxeTUQyRjrOnlCoYta87iKBWq3EsdM2" crossorigin="anonymous"></script>
<script src="https://unpkg.com/[email protected]"></script>
<title>{title}</title>
</head>
<body>
{children}
</body>
</html>
</>
);
}
Server side code for contacts Api (I'm using Bun with ElysiaJs):
export const contactsRoutes = new Elysia()
.use(html())
.post(
'/',
({html, body: {name}, set}) => {
const value = name.toLowerCase();
if (people.some(person => person.name.toLowerCase() === value)) {
set.headers['hx-trigger'] = 'customevent';
} else {
const newPerson: TContact = {
id: 0,
name,
number: "?",
}
people.push(newPerson);
}
// set['status'] = 201;
return html(<PeopleListingBox {...{people}} />);
},
{
body: t.Object({
name: t.String({minLength: 3, maxLength: 100})
})
}
)
;
after sending a Post request with a duplicate name, server returns this for Response Headers section:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf8
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Vary: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: *
Access-Control-Expose-Headers: *
Access-Control-Exposed-Headers: *
hx-trigger: customevent
Date: Thu, 09 May 2024 17:13:11 GMT
Content-Length: 120
However custom event is not fired as expected and console shows no output. I've tried with:
hx-on="customevent: console.log('chesu!!')"
same result, no output.
Most likely you had Typo error, seems like htmx is case sensitive went it comes to headers, so instead of hx-trigger, you use HX-Trigger it will work fine.
Eg:
`import { Elysia } from "elysia"; import { html } from '@elysiajs/html'
const app = new Elysia() app .use(html()) .get('/', () => { return '
return '<span>Msg from server</span>'
}) .listen(3000);
console.log(
🦊 Elysia is running at http://${app.server?.hostname}:${app.server?.port}
);
`
I don't think so because I previously tried (like as the reference video ) with "Hx-Trigger" and it didn't work. Instead of using hx-on I've tried hyperscript and it is working as expected.
Well I'm glad that you find another solution. But the example above it's working as well, maybe you use the "Hx-Trigger" with 'x' in lower case and it caused the issue? Not sure to be fair.
:)
I think the problem with hx-on is that it's listening on the element it is placed on. You'd need something like hx-on-from-body. :)
I've tested my code again with some variants and here my observations:
- the formats
hx-on--customevent=orhx-on-customevent=are definitely not working - the format
hx-on="customevent:is working, - the key "hx-trigger" passed as header is insensitive-case
The strange here is when I posted this issue, the format hx-on="customevent: was not working but it is now @ _ @
however that format will be deprecated as documentation, so it is not really a solution. Moreover it seems hx-on is very limited regarding the number of operations I can do, hyperscript is more flexible in this aspect.
Nice, good job!
yes, hx-on is designed to only be used for simple things, for anything beyond that i highly recommend hyperscript, alpine.js or https://github.com/gnat/surreal
I think the problem with hx-on is that it's listening on the element it is placed on. You'd need something like hx-on-from-body. :)
Yes this was my issue thank you... I think this should really be documented as a gotcha. If the element with the hx-on is replaced, the hx-on is no longer executed.