Closed peterswords closed 2 years ago
My apologies, it's covered in the documentation under '3rd Party Javascript'. You need to call htmx.process()
on any content newly added to the DOM (also mentioned in Issue 571). Here is an updated JsFiddle: https://jsfiddle.net/p20tc6Lx/ (again, you'll need to use browser dev tools to see that a request is actually now issued for Page 2).
I've taken the Alpine approach of doing a $watch
for a change of variable that causes the new content to be loaded. However, the $watch
event fires before the content appears, so it's also necessary to use Alpine's $nextTick()
to defer the htmx.process()
until that happens.
Excellent. If you have time would you mind creating a docs pull request with this against the 3rd party section? I'm sure other people would be interested in Alpine and htmx working together properly.
@peterswords - You use $nextTick()
to avoid a superfluous call of htmx.process() on intialisation? Sorry if this is obvious. - I am new to this. It also works without using $nextTick()
:
<div x-data="{p1: true, p2: false}"
x-init="$watch('p2', value => htmx.process(document.querySelector('#p2')) )">
<template x-if="p1">
<div id="p1"><a hx-get="/page1" href="#">Page1</a></div>
</template>
<template x-if="p2">
<div id="p2"><a hx-get="/page2" href="#">Page2</a></div>
</template>
<button @click = " p2=true ">Press Me</button>
</div>
@dalito, weird, I could have sworn it wasn't working without the $nextTick
, but you're right -- it seems fine now. It's also worth showing the more general case where the value might be toggled on and off: you don't want to do a htmx.process()
if the content has been removed. I revised the JsFiddle here: https://jsfiddle.net/4d8fsq2y/
It also turns out that script defer
on the Alpine JS library is vital. Without it the button's click event fires twice, and the value gets set and reset before we see the new content.
Thanks for the steer.
<div x-data="{show_new: false}"
x-init="$watch('show_new', value => {
if (show_new) {
htmx.process(document.querySelector('#new_content'))
}
})">
<button @click = "show_new = !show_new">Toggle New Content</button>
<template x-if="show_new">
<div id="new_content">
<a hx-get="/server/newstuff" href="#">New Clickable</a>
</div>
</template>
</div>
Excellent. If you have time would you mind creating a docs pull request with this against the 3rd party section? I'm sure other people would be interested in Alpine and htmx working together properly.
@1cg, old-school enterprise developer here. Forty years coding and I don't know how to do a pull request. However, even a tiny contribution to such a great project is worth a try, so I hope I've done it right.
Accepted! Thank you!
I am using HTMX with Alpine JS. Alpine allows you to conditionally load parts of a page based on "
x-if
" attributes attached to a template element. If such a template contains nested elements withhx-get
attributes, thehx-get
triggers only if it was shown when the page initially loaded.This is easiest to show with an example. JsFiddle is here: https://jsfiddle.net/r5b8k90v/1/
Since the
hx-get
tries to load from a non-existent location/blah
, you cannot see anything actually working (or failing to). However, you can use the Firefox or Chrome developer tools to see what events are attached. When you run the fiddle, you initially see one link (an anchor tag with ah-get
and text 'Page 1').Press the "Press Me" button to change a flag and make a second link visible (identical to the first except for differently named). While I can't show in this fiddle how the second link is broken, it can be seen in the browser developer tools that only the "Page1" link has an event attached, while the second link which was only revealed after initial page load is broken -- Picture 1, Picture 2.
Is there something that needs to be done to make HTMX elements "come alive" if they are incorporated into a page from a template after the initial page load?