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.
7 Replies
awcodes
awcodes3mo ago
You could probably tap into the livewire js lifecycle hooks.
awcodes
awcodes3mo ago
Laravel
JavaScript | Laravel
A full-stack framework for Laravel that takes the pain out of building dynamic UIs.
treii28
treii28OP3mo 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
jjo633mo 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
treii28OP3mo 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
lacymj3mo ago
Any updates on this issue (I'm having the same trouble). In fact, I can't get any javascript to run from filament.
treii28
treii28OP2mo ago
I never did get a response of a valid 'livewire is ready' type event, but the code i posted seems to work for most use cases by just waiting a second-a-half after the page is loaded to set the refresh triggers. I'm using the morph.updated event to run the code I needed to run.
Want results from more Discord servers?
Add your server