F
Filament5mo ago
btx

Modal Action in Form with Table Modal Body

Hey everyone, I have a complex issue with my selection dialog. I hope I can explain it in 3 steps: 1) I have an action button in a form, that opens a modal. This Modal contains a custom table via table builder to select a record, that should be used to pre-fill the form. 2) For this, each table record, has a "Select" button. Clicking on this button dispatches an event to pass the data down to the form. 3) The problem: The event is dispatched (can see it in Debug bar), but it does not reach the form or any function outside the Livewire class. The form:
Tabs\Tab::make('Import')->schema([
Actions::make([
SelectProductAction::make('select_product'),

SelectShippingAction::make('select_shipping'),
]),
]),
Tabs\Tab::make('Import')->schema([
Actions::make([
SelectProductAction::make('select_product'),

SelectShippingAction::make('select_shipping'),
]),
]),
The modal action
class SelectProductAction extends Action {
public static function getDefaultName(): ?string {
return 'selectProductAction';
}

protected function setUp(): void {
parent::setUp();

$this->label('Select Product');
$this->modalHeading('Select Product');
$this->modalSubmitAction(false);
$this->modalCancelAction(false);
$this->modalFooterActions([]);
$this->modalContent(function (SelectProductAction $action): View {
return view('filament.actions.select-product-modal-content', [
'selectProductTable' => SelectProductTable::class,
]);
});
$this->action(fn ($data, $value, $state) => dd($data, $value, $state));
}

#[On('fooBarEvent')]
public function onFooBar($data): void {
// DOES NOT RECEIVE THE EVENT !
dd("On fooBarEvent", $data);
}
}
class SelectProductAction extends Action {
public static function getDefaultName(): ?string {
return 'selectProductAction';
}

protected function setUp(): void {
parent::setUp();

$this->label('Select Product');
$this->modalHeading('Select Product');
$this->modalSubmitAction(false);
$this->modalCancelAction(false);
$this->modalFooterActions([]);
$this->modalContent(function (SelectProductAction $action): View {
return view('filament.actions.select-product-modal-content', [
'selectProductTable' => SelectProductTable::class,
]);
});
$this->action(fn ($data, $value, $state) => dd($data, $value, $state));
}

#[On('fooBarEvent')]
public function onFooBar($data): void {
// DOES NOT RECEIVE THE EVENT !
dd("On fooBarEvent", $data);
}
}
11 Replies
btx
btxOP5mo ago
The table (Livewire component)
class SelectProductTable extends Component implements HasForms, HasTable {
use InteractsWithForms;
use InteractsWithTable;

#[On('fooBarEvent')]
public function onFooBar($data): void {
// THIS WORKS !
dd("On fooBarEvent", $data);
}

public function table(Table $table): Table {
return $table
->query(Product::query())
->paginated([30])
->recordCheckboxPosition(RecordCheckboxPosition::BeforeCells)
->columns([
Tables\Columns\TextColumn::make('id')->label('ID')->sortable(),

Tables\Columns\TextColumn::make('product_number')->label('P/N')->sortable()->toggleable(),

Tables\Columns\TextColumn::make('sales_price_net_eur')
->label('VK')
->tooltip('Verkaufspreis')
->badge()
->color(Color::Green)
->money('EUR')
->sortable(),
])
->actions([
Action::make('select_product')
->label('Select')
->button()
->action(function ($record, $livewire) {
$this->dispatch('fooBarEvent', data: $record);
}),
])
;
}

public function render(): View {
return view('livewire.select-product-table');
}
}
class SelectProductTable extends Component implements HasForms, HasTable {
use InteractsWithForms;
use InteractsWithTable;

#[On('fooBarEvent')]
public function onFooBar($data): void {
// THIS WORKS !
dd("On fooBarEvent", $data);
}

public function table(Table $table): Table {
return $table
->query(Product::query())
->paginated([30])
->recordCheckboxPosition(RecordCheckboxPosition::BeforeCells)
->columns([
Tables\Columns\TextColumn::make('id')->label('ID')->sortable(),

Tables\Columns\TextColumn::make('product_number')->label('P/N')->sortable()->toggleable(),

Tables\Columns\TextColumn::make('sales_price_net_eur')
->label('VK')
->tooltip('Verkaufspreis')
->badge()
->color(Color::Green)
->money('EUR')
->sortable(),
])
->actions([
Action::make('select_product')
->label('Select')
->button()
->action(function ($record, $livewire) {
$this->dispatch('fooBarEvent', data: $record);
}),
])
;
}

public function render(): View {
return view('livewire.select-product-table');
}
}
btx
btxOP5mo ago
No description
No description
LeandroFerreira
LeandroFerreira5mo ago
yes, because you need to define the onFooBar in the Livewire component Did that fix the issue?
btx
btxOP5mo ago
can you explain more please? thx!
LeandroFerreira
LeandroFerreira5mo ago
sorry, explain what? SelectProductTable is a livewire component https://livewire.laravel.com/docs/events
Laravel
Events | Laravel
A full-stack framework for Laravel that takes the pain out of building dynamic UIs.
btx
btxOP5mo ago
@LeandroFerreira SelectProductTable is of course a Livewire component
use Filament\Tables\Contracts\HasTable;
use Filament\Forms\Contracts\HasForms;
use Livewire\Attributes\On;
use Livewire\Component;

class SelectProductTable extends Component implements HasForms, HasTable {
use Filament\Tables\Contracts\HasTable;
use Filament\Forms\Contracts\HasForms;
use Livewire\Attributes\On;
use Livewire\Component;

class SelectProductTable extends Component implements HasForms, HasTable {
LeandroFerreira
LeandroFerreira5mo ago
Sorry, I didn't understand your question
btx
btxOP5mo ago
in short: #[On('fooBarEvent')] does not work in any component function thats not inside class SelectProductTable extends \Livewire\Component, where public function table() ... is dispatching the event. Where I want it to work: class SelectProductAction extends Action ... public function onFooBar(), but I see now a Filament Action is not a Livewire component, is it ?
elmudometal
elmudometal5mo ago
https://github.com/elmudometal/filament-select-table/ I went through the same thing and solved it the way I did in this package. You can make it easier if you set up a livewire with a repeater instead of a table.
GitHub
GitHub - elmudometal/filament-select-table
Contribute to elmudometal/filament-select-table development by creating an account on GitHub.
LeandroFerreira
LeandroFerreira5mo ago
yes. Take a look: https://filamentphp.com/docs/3.x/actions/adding-an-action-to-a-livewire-component You can add an action to a Livewire component, but the event must be defined within the component itself
btx
btxOP5mo ago
In the end, I fixed it by creating a custom FormField instead of an Action 🙂

Did you find this page helpful?