I've got Sprig set up to filter entries by a few categories. I'm trying to re-layout Masonry JS after this update takes place.
For starters, I add Masonry to the window variable (defined as global in my JS module since I'm using node):
global.masonryLayout = new Masonry('.masonry', options)
Then, in my sprig component, I'm using a <script>
tag that runs each time sprig loads entries, as per the docs:
<script>
if (window.masonryLayout) {
window.masonryLayout.reloadItems()
}
</script>
I've got an example up and running, including console outputs each time the script runs. The Masonry class is there, but it just isn't laying out.
- https://masonry.brycekirk.com/press
- Filter by Source > The New York Times
Expected behaviour: Items are loaded into a Masonry layout.
Actual behaviour: No errors, but the layout is just normal columns, not Masonry (the 2nd row of articles are on their own line below the others).
Right now I'm using .reloadItems()
, which actually populates colYs
and cols
.
.layout()
leaves colYs
and cols
blank.
What am I missing here??
EDIT: Working code based on MoritzLost's answer
In my JS module:
global.Masonry = Masonry
global.masonryOptions = options
global.masonryLayout = new Masonry('.masonry', options)
In my sprig component:
if (window.masonryLayout) {
window.masonryLayout.destroy()
window.masonryLayout = new window.Masonry('.masonry', window.masonryOptions)
}
EDIT (JULY 2023): This is much easier with htmx events. Just need to make sure to load the sprig script before your sprig component.
JS module:
global.Masonry = Masonry
global.masonryOptions = options // These are just masonry options I've defined in an object variable
window.onload = () => {
global.masonryLayout = new Masonry('.masonry', options)
}
In my sprig component:
htmx.on('htmx:beforeSwap', function(e) {
window.masonryLayout.destroy()
})
htmx.on('htmx:afterSwap', function(e) {
window.masonryLayout = new window.Masonry('.masonry', window.masonryOptions)
document.querySelector('#load-more-oob').scrollIntoView({
behavior: 'smooth',
block: 'end'
}) // This just re-aligns the window
})