-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: hx-init attribute or simpler equivalent #2863
Comments
Seems that hx-on::load already does what you want fine for the simple case. Note that :htmx: can be shortened to :: making it only a few characters more than "hx-init" <div hx-on::load="console.log('hi')"></div> There are already many ways supported to handle load events in htmx like the htmx.onLoad() and hx-on and you can also try adding a simple event listener to the body so you don't have to define the load event on every single element. document.body.addEventListener('htmx:load', function(evt) {
if(evt.detail.elt.tagName == 'TABLE') {
// do custom table init code here
}
}); One thing to be aware of with htmx:load events is they fire once on the body when you do the first full page load and also on every parent element swapped in via a htmx ajax request. But you do not get a load event for any children loaded in during initial page load or any children elements inside htmx partial responses. So sometimes when handling load events you may need to also process all the elt's children to see what needs to have custom init code run. For example here is a global handler that could init all div's (swap in different logic for your use) as they are loaded: function customInit(elt) {
console.log('do custom init here')
}
document.body.addEventListener('htmx:load', function(evt) {
if(evt.detail.elt.tagName == 'DIV') {
customInit(evt.detail.elt) // check item itself need init
}
for(const el of evt.detail.elt.querySelectorAll("div")) {
customInit(el) // check if any children need init
}
}); So if you were going to implement a proper "hx-init" attribute in htmx then it would be great if it was able to do the querySelectorAll part above for you and run reliably on all initial page loaded elements and all children of partial ajax responses. I think this could be done with a new htmx extension if you didn't want to have to write custom event listeners as above. |
Thanks @MichaelWest22. Your example highlights some of my own observations very well. Maybe an extension could improve the situation. Looking at some of the htmx debug messages, maybe I can get something workable using: https://htmx.org/events/#htmx:afterProcessNode |
I couldn't identify a simple enough htmx attribute or event that could satisfy this request. For the time being, it looks like there is no equivalent capability in htmx (in terms of simplicity, safety, clarity, maintainability and LoB), when compared to the following initialisation methods offered by other supporting libraries: hyperscript <span _="init log 'hyperscript'"></span> alpine<span x-data x-init="console.log('alpine')"></span> surreal<span>
<script>
console.log("surreal");
</script>
</span> htmx (non-init)<span hx-on:htmx:load="console.log('htmx - triggers for all htmx content or not at all')"></span> htmx (HX-Trigger)<span
hx-get="/init-my-component"
hx-swap="none"
hx-trigger="load"
hx-on:my-component-init-event="console.log('htmx - server returns HX-Trigger my-component-init-event')"
></span> The For the <span
hx-trigger="load trigger:my-init"
hx-on:my-init="console.log('body init (htmx)"
></span> Here is the code handling the hx-trigger version of Lines 2593 to 2596 in 7fc1d61
|
Yeah I can see several ways to create a hx-init extension:
|
let intAPI
htmx.defineExtension('hx-init', {
init: function(apiRef) {
intAPI = apiRef
},
onEvent: function(name, evt) {
if (name === 'htmx:load') {
if(evt.detail.elt.getAttribute('hx-init') !== null) {
intAPI.triggerEvent(evt.detail.elt,'htmx:init')
}
for(const el of evt.detail.elt.querySelectorAll("[hx-init]")) {
intAPI.triggerEvent(el,'htmx:init')
}
}
}
}) For example here is option 1 which seems to work well. just set hx-ext="hx-init" attribute on the page body and add hx-init="true" to all elements to trigger init on and then write a htmx:init eventListener |
@MichaelWest22 I like option 1. Thanks for the reference implementation. |
This is how I ended up solving it for https://github.com/maddalax/htmgo
|
Thank you for providing a refreshing way to create for the web.
I find myself hooking into hyperscript and javascript whenever I need to do some initialisation work on an htmx component.
Hyperscript:
HTMX JS API:
I imagine
hx-on
could also be used, although I haven't tested it):It would be nice to have something similar for htmx, to avoid the need for hyperscript or javascript for that simple use case:
The text was updated successfully, but these errors were encountered: