Run a javascript function when table is redrawn

I have an external tool that adds tooltips to links when a page loads. The problem is, if Filament re-orders or filters the rows, thus updating the page content, the links vanish when the content is re-drawn. I found a function in the tool to trigger the modification of links, but I now need to know how I can have that javascript function run after filament updates the table contents.
6 Replies
awcodes
awcodes4w ago
You could probably tap into the livewire js lifecycle hooks.
awcodes
awcodes4w ago
Laravel
JavaScript | Laravel
A full-stack framework for Laravel that takes the pain out of building dynamic UIs.
treii28
treii284w ago
yeah I've tried a number of them already and can't seem to get one to trigger on a resort. I'm not sure which one I should be using for re-orders and search/filtering. part of the problem seems to be that all the examples I find say to use an event listener for livewire.load but adding a console log inside just the outer function of that, the liverwire.load even never seems to trigger so any events I try to add within it never even get created. I think I found one in that list with morph.updated, but as mentioned, couldn't get livewire.load event to trigger. So instead I used a window onload with a 3 second set-timeout which seems to work for the time being. var rooTimeout = null; function refreshOnlyOnce() { if(rooTimeout) clearTimeout(rooTimeout); rooTimeout = setTimeout(doRefresh, 1000); } function doRefresh() { console.log('refreshing wowhead tooltips'); WH.Tooltips.refreshLinks(); } window.onload = function() { setTimeout(function() { Livewire.hook('morph.updated', ({ el, component }) => { refreshOnlyOnce() }) }, 3000) }; it triggers once for every record in the list it seems, thus the refreshOnlyOnce wrapper so it only triggers one time per resort/filter operation.
jjo63
jjo634w ago
I had this same issue (i.e. I wanted to have a button on each row that did something custom)- solved it after many many attempts - I am not a js expert by any means but the following was the basis
if (tableContainer) {
// console.log("Table container found. Setting up MutationObserver");

const observer = new MutationObserver((mutationsList) => {
// console.log("MutationObserver detected changes in the table container");

for (let mutation of mutationsList) {
if (mutation.type === 'childList') {
// console.log("Child list changed. Reattaching document link listeners");
attachDocumentLinkListeners(); // Reattach listeners whenever the table changes
}
}
});

observer.observe(tableContainer, { childList: true, subtree: true });
// console.log("MutationObserver is now observing the table container");
} else {
// console.log("Table container not found! MutationObserver not set up.");
}
if (tableContainer) {
// console.log("Table container found. Setting up MutationObserver");

const observer = new MutationObserver((mutationsList) => {
// console.log("MutationObserver detected changes in the table container");

for (let mutation of mutationsList) {
if (mutation.type === 'childList') {
// console.log("Child list changed. Reattaching document link listeners");
attachDocumentLinkListeners(); // Reattach listeners whenever the table changes
}
}
});

observer.observe(tableContainer, { childList: true, subtree: true });
// console.log("MutationObserver is now observing the table container");
} else {
// console.log("Table container not found! MutationObserver not set up.");
}
It was all about targeting the correct elements and watching for changes there - and then executing the
attachDocumentLinkListeners
attachDocumentLinkListeners
function Let me know if you need to see any more of the solution and hope this does help sonewhat.
treii28
treii284w ago
My solution seems to work for the time being. But I would still like to know what I can use in the filament/livewire startup to trigger setting up the listener when they are done loading. Using the setTimeout method is cludgy at best and can potentially fail if something in the loading doesn't finish within the timeout period. I ran into another issue along the way in that my breadcrumbs and action buttons vanished as soon as I loaded the javascript using a custom ->getHeader() call to load a view with the script tags. It turned out the index.blade was looking for a non-null return from ->getHeader() with a elseif to display any output of ->getHeadings() I ended up having to track down the index.blade.php and pull out the second condition for ->getHeadings() and add it to my custom header template to get those to show up. There didn't seem to be any way built into filamentphp to get the default header items in a custom template short of repeating that code. Ugly IMHO. that sub-portion should be sub-templated so you can load it when needed without repeating code. (that's going to be an nightmare if they update anything)
lacymj
lacymj2w ago
Any updates on this issue (I'm having the same trouble). In fact, I can't get any javascript to run from filament.
Want results from more Discord servers?
Add your server