TableWidget: Modal in View Actions empty data

What I'm trying to do: Show a modal when clicking on "View" within a TableWidget. What I did: I created a custom widget that extends TableWidget. I added a view action that shows a modal for a user record. Even though the modal shows form elements, they are empty. Code:
<?php

namespace App\Filament\Widgets;

use App\Filament\Resources\UserResource;
use App\Models\User;
use Filament\Forms\Form;
use Filament\Tables\Actions\ViewAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Filament\Widgets\TableWidget as BaseWidget;

class UserWidget extends BaseWidget
{
public function table(Table $table): Table
{
return $table
->query(
User::query()
)
->columns([
TextColumn::make('name'),
])
->actions([
ViewAction::make()
->form(function (User $user) {
$form = UserResource::form(Form::make($this))
->model($user);

$form->fill($user->getAttributes());
return $form;
}),
]);
}
}
<?php

namespace App\Filament\Widgets;

use App\Filament\Resources\UserResource;
use App\Models\User;
use Filament\Forms\Form;
use Filament\Tables\Actions\ViewAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Filament\Widgets\TableWidget as BaseWidget;

class UserWidget extends BaseWidget
{
public function table(Table $table): Table
{
return $table
->query(
User::query()
)
->columns([
TextColumn::make('name'),
])
->actions([
ViewAction::make()
->form(function (User $user) {
$form = UserResource::form(Form::make($this))
->model($user);

$form->fill($user->getAttributes());
return $form;
}),
]);
}
}
Additional Info: I know I can just redirect the user to the /users/{id} route to view the record, but I really like the modal popup (it keeps them on the dashboard). Question: So is there a way I can bind the record to the form?
No description
Solution:
Hopefully this helps someone - I was able to solve this by passing ->statePath('state'), this also requires that the Widget has this state defined as public, it will not work if not defined in the class. This is the GenericTableWidget ```php <?php...
Jump to solution
3 Replies
Solution
seamlessly
seamlessly5w ago
Hopefully this helps someone - I was able to solve this by passing ->statePath('state'), this also requires that the Widget has this state defined as public, it will not work if not defined in the class. This is the GenericTableWidget
<?php

namespace App\Filament\Widgets;

use Filament\Forms\Form;
use Filament\Tables\Actions\DeleteAction;
use Filament\Tables\Actions\EditAction;
use Filament\Tables\Actions\ViewAction;
use Filament\Tables\Table;
use Filament\Widgets\TableWidget as BaseWidget;

class GenericTableWidget extends BaseWidget
{
public array $state;
protected static string $resourceClass;

public function table(Table $table): Table
{
$class = static::$resourceClass;
$form = fn(Form $form) => $class::form($form);

return $table
->heading($class::getNavigationLabel())
->query($class::getModel()::query())
->columns($class::getTableColumns())
->actions([
ViewAction::make()->form($form),
EditAction::make()->form($form),
DeleteAction::make(),
]);
}
}
<?php

namespace App\Filament\Widgets;

use Filament\Forms\Form;
use Filament\Tables\Actions\DeleteAction;
use Filament\Tables\Actions\EditAction;
use Filament\Tables\Actions\ViewAction;
use Filament\Tables\Table;
use Filament\Widgets\TableWidget as BaseWidget;

class GenericTableWidget extends BaseWidget
{
public array $state;
protected static string $resourceClass;

public function table(Table $table): Table
{
$class = static::$resourceClass;
$form = fn(Form $form) => $class::form($form);

return $table
->heading($class::getNavigationLabel())
->query($class::getModel()::query())
->columns($class::getTableColumns())
->actions([
ViewAction::make()->form($form),
EditAction::make()->form($form),
DeleteAction::make(),
]);
}
}
Now you can extend this class to show a specific resource such as Users:
<?php

namespace App\Filament\Widgets;

use App\Filament\Resources\UserResource;

class UserTableWidget extends GenericTableWidget
{
protected static string $resourceClass = UserResource::class;
}
<?php

namespace App\Filament\Widgets;

use App\Filament\Resources\UserResource;

class UserTableWidget extends GenericTableWidget
{
protected static string $resourceClass = UserResource::class;
}
Make sure that in your UserResource you have defined the static function getTableColumns:
public static function getTableColumns(): array
{
return [
Tables\Columns\TextColumn::make('name'),
Tables\Columns\TextColumn::make('email'),
Tables\Columns\TextColumn::make('role.name')->label('Role')
];
}
public static function getTableColumns(): array
{
return [
Tables\Columns\TextColumn::make('name'),
Tables\Columns\TextColumn::make('email'),
Tables\Columns\TextColumn::make('role.name')->label('Role')
];
}
seamlessly
seamlesslyOP5w ago
You can now add your widget onto the dashboard with:
class Dashboard extends FilamentDashboard
{
public function getWidgets(): array
{
return [
UserTableWidget::class,
];
}
...
class Dashboard extends FilamentDashboard
{
public function getWidgets(): array
{
return [
UserTableWidget::class,
];
}
...
If you have done everything correctly, you should now see the User table (with actions that appear as modals) on the dashboard.
noahlocke
noahlocke3w ago
I copied this exactly and am getting Typed static property App\Filament\Widgets\GenericTableWidget::$resourceClass must not be accessed before initialization ... any ideas?
Want results from more Discord servers?
Add your server