Custom Table Action and polling

I have a table that polls data every 5 seconds (and it's configurable), I added two actions to that table widget, a built-in one (a EditAction) and a custom that has a custom view and a trigger. For some reason the standard action is always click-able, meanwhile the custom action is not always clickable. Table widget:
...
return $table
->emptyStateHeading('No Active Calls')
->poll(config('widgets.poll'))
->striped()
->columns([
Tables\Columns\TextColumn::make('name')
->size(TextColumnSize::ExtraSmall)
->wrap()
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\Action::make('custom')
->view('filament.company.tables.modals.custom')
->visible(fn($record) => $this->spyVisibility($record))
->action((function ($record) {
Log::debug($record);
// This code is never executed
})),

]);
...
return $table
->emptyStateHeading('No Active Calls')
->poll(config('widgets.poll'))
->striped()
->columns([
Tables\Columns\TextColumn::make('name')
->size(TextColumnSize::ExtraSmall)
->wrap()
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\Action::make('custom')
->view('filament.company.tables.modals.custom')
->visible(fn($record) => $this->spyVisibility($record))
->action((function ($record) {
Log::debug($record);
// This code is never executed
})),

]);
And the blade view:
<x-filament::modal id="spy-modal" icon="heroicon-m-puzzle-piece" alignment="center" :extra-modal-window-attribute-bag="$action?->getExtraModalWindowAttributeBag()">
<x-slot name="trigger">
<x-filament::button icon="heroicon-m-puzzle-piece" x-on:click="window.dispatchEvent(new Event('js-modalopen-hndlr'));" />
</x-slot>

<x-slot name="heading">
Demo
</x-slot>
</x-filament::modal>
<x-filament::modal id="spy-modal" icon="heroicon-m-puzzle-piece" alignment="center" :extra-modal-window-attribute-bag="$action?->getExtraModalWindowAttributeBag()">
<x-slot name="trigger">
<x-filament::button icon="heroicon-m-puzzle-piece" x-on:click="window.dispatchEvent(new Event('js-modalopen-hndlr'));" />
</x-slot>

<x-slot name="heading">
Demo
</x-slot>
</x-filament::modal>
According to Filament documentation, that's all I need to add to make this work. The question is, what else should I add to the trigger in order to make it work?
20 Replies
toeknee
toeknee6d ago
change ->action((function ($record) { Log::debug($record); // This code is never executed })), tio ->action(function ($record) { Log::debug($record); // This code is never executed }), Does that now get triggered?
nuovo2023
nuovo2023OP6d ago
Oops, I made the change, and that piece of code does not execute, but the main concern is that button is not always clickable, even the mouse pointer reflects that behavior. Thanks for replying 🙂
nuovo2023
nuovo2023OP6d ago
Odd, trigger button's disabled property is toggling true/false every few seconds. I'm not setting that in my code 😦
No description
LeandroFerreira
try to add wire:target to the button 🤔
nuovo2023
nuovo2023OP6d ago
I ended up adding disabled="false" to my Blade template:
<x-slot name="trigger">
<x-filament::button icon="heroicon-m-puzzle-piece" x-on:click="window.dispatchEvent(new Event('js-modalopen-hndlr'));" disabled="false" />
</x-slot>
<x-slot name="trigger">
<x-filament::button icon="heroicon-m-puzzle-piece" x-on:click="window.dispatchEvent(new Event('js-modalopen-hndlr'));" disabled="false" />
</x-slot>
I also tried :disabled but it didn't work, the base view calls isDisabled, but it is ignoring ->disabled(false) I used it once, with custom view using modalContent method. For some reason the modal disappeared after running a simple javascript code. The Blade view only purpose was to pass data to JavaScript, then in my js code I created an extension using sip.js When the modal disappeared, it was creating additonal instances of my js object
LeandroFerreira
if you decide using modal action, share the code that you are using.. maybe I can help you
nuovo2023
nuovo2023OP6d ago
Sure, the action was this one:
->actions([
Tables\Actions\Action::make('spy')
->iconButton()
->button()
->label('')
->icon('icon-headphones')
->visible(fn($record) => $this->spyVisibility($record))
->modal()
->modalContent(fn($record) => view('filament.company.tables.modals.spy'))
->modalSubmitAction(false)
->modalCancelAction(
fn(StaticAction $action) => $action->extraAttributes(['id' => 'close-spy-modal'])->label('Close')
)
->extraModalWindowAttributes(fn($record) => ['id' => 'pbx_spymodal', 'data-sip' => $record->sipnum]),
])
->actions([
Tables\Actions\Action::make('spy')
->iconButton()
->button()
->label('')
->icon('icon-headphones')
->visible(fn($record) => $this->spyVisibility($record))
->modal()
->modalContent(fn($record) => view('filament.company.tables.modals.spy'))
->modalSubmitAction(false)
->modalCancelAction(
fn(StaticAction $action) => $action->extraAttributes(['id' => 'close-spy-modal'])->label('Close')
)
->extraModalWindowAttributes(fn($record) => ['id' => 'pbx_spymodal', 'data-sip' => $record->sipnum]),
])
And the blade view:
@php
use Filament\Facades\Filament;
$company = Filament::getTenant();
$spyUser = $company->spyUser ?? null;
$spyPass = $company->data['spy_pass'] ?? null;
$spyExt = config('pbx.defaults.spy_extension', null);
$closeModalID = 'spy-modal';
@endphp


<div x-ignore ax-load ax-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('sip-client') }}"
x-data="sipClient({
state: {
spyUser: '{{ @$spyUser }}',
spyPass: '{{ @$spyPass }}',
spyExtension: '{{ @$spyExt }}',
closeModalID: '{{ $closeModalID }}',
target: '{{ @$record->sipnum }}',
}
})">
{{ $record->channel ?? '' }}

<audio id="chspyaudio" controls style="display: none">
<p>Your browser does not support the audio element</p>
</audio>
</div>
@php
use Filament\Facades\Filament;
$company = Filament::getTenant();
$spyUser = $company->spyUser ?? null;
$spyPass = $company->data['spy_pass'] ?? null;
$spyExt = config('pbx.defaults.spy_extension', null);
$closeModalID = 'spy-modal';
@endphp


<div x-ignore ax-load ax-load-src="{{ \Filament\Support\Facades\FilamentAsset::getAlpineComponentSrc('sip-client') }}"
x-data="sipClient({
state: {
spyUser: '{{ @$spyUser }}',
spyPass: '{{ @$spyPass }}',
spyExtension: '{{ @$spyExt }}',
closeModalID: '{{ $closeModalID }}',
target: '{{ @$record->sipnum }}',
}
})">
{{ $record->channel ?? '' }}

<audio id="chspyaudio" controls style="display: none">
<p>Your browser does not support the audio element</p>
</audio>
</div>
I'm not modifying any generated code in javascript, that was the odd part.
LeandroFerreira
For some reason the modal disappeared after running a simple javascript code. Is this the issue?
nuovo2023
nuovo2023OP6d ago
Yup btw: I'm using the close modal ID to trigger the close-modal event when a call ends I was also using poll() I can't find that post Anyway, I don't like my solution, but it's working so far. If you can find what's wrong it would be nice to know 🙂
LeandroFerreira
I'll check and I let you know What is sip-client ?
nuovo2023
nuovo2023OP6d ago
I followed this guide https://filamentphp.com/docs/3.x/support/assets#asynchronous-alpinejs-components, to add custom JS code. It creates a sip.js instance, and allow me to make calls
LeandroFerreira
I mean, is sip-client a js lib? or you are using a custom js code..
nuovo2023
nuovo2023OP6d ago
It's my code I build that code using node bin/build.js, and it's bundled and included right in public folder You guys made a great job documenting that info I found wire:loading.attr is the one that affects trigger disabled toggling, by default is set as this:
<x-filament::button icon="icon-headphones" tooltip="Listen" wire:loading.attr="disabled"...>
<x-filament::button icon="icon-headphones" tooltip="Listen" wire:loading.attr="disabled"...>
This will be toggling its state depending on poll value. I found out that adding disabled="false" here will disable the x-on:click event I ended add setting a random-ish value for wire:loading.attr, the final solutions is this one:
<x-slot name="trigger">
<x-filament::button icon="heroicon-m-puzzle-piece" tooltip="Listen" wire:loading.attr="enabled" x-on:click="window.dispatchEvent(new Event('js-modalopen-hndlr'));" />
</x-slot>
<x-slot name="trigger">
<x-filament::button icon="heroicon-m-puzzle-piece" tooltip="Listen" wire:loading.attr="enabled" x-on:click="window.dispatchEvent(new Event('js-modalopen-hndlr'));" />
</x-slot>
LeandroFerreira
You said: For some reason the modal disappeared after running a simple javascript code. Does this happen if you run a simple JS like:
\Filament\Tables\Actions\Action::make('spy')
->modalSubmitAction(false)
->modalCancelActionLabel('Close')
->modalContent(view('filament.company.tables.modals.spy')),
\Filament\Tables\Actions\Action::make('spy')
->modalSubmitAction(false)
->modalCancelActionLabel('Close')
->modalContent(view('filament.company.tables.modals.spy')),
<!-- spy.blade.php -->
<div x-data="{
init() {
console.log('init')
}
}">
</div>
<!-- spy.blade.php -->
<div x-data="{
init() {
console.log('init')
}
}">
</div>
?
nuovo2023
nuovo2023OP5d ago
Yes, the same thing just happened, only the dark background is preserved. I can see "init" on the browser console.
No description
nuovo2023
nuovo2023OP5d ago
Off-topic: I'm trying to dispatch the close-modal event in my code, but the generated code is expecting an event id (this id changes every time) and it will complaing about it.
No description
nuovo2023
nuovo2023OP5d ago
By the looks of it, seems like no matter what JS code is run at init (or ax-loaded), it will make the modal disappear sometimes. And to add to that, we also have the poll method that's in the table widget.
LeandroFerreira
It was supposed to work.. 🤔 Are you able to create a minimal repo on github to reproduce this issue?
nuovo2023
nuovo2023OP5d ago
Sure

Did you find this page helpful?