Customizing the user experience of the empty state on tables based on existing conditions.

I have a question about the user experience when using tables. Let's assume that there is an empty table because there are no records created and the empty state has been configured with ->emptyStateActions(), ->emptyStateDescription(), ->emptyStateHeading(), and ->emptyStateIcon(). In this scenario, we can write copy to clearly instruct the user on what to do to add a record. But in a different scenario, where there are 100 records, and none are trashed, if the user filters to show only trashed records, they would get the same message as above. Is there a way to do something like this:
->emptyStateHeading(function () {
if (($this->isFilteredView())) {
return 'You currently have a filter active that may affect what you see.';
}

return 'Create a new record.';
})
->emptyStateHeading(function () {
if (($this->isFilteredView())) {
return 'You currently have a filter active that may affect what you see.';
}

return 'Create a new record.';
})
I know isFilteredView() is not real, but is there a way to tell if the filtering system is engaged or not? In my use case someone was tinkering and activated a filter for "favorites" and thought there were no records because she got the empty state. She reentered data that was already available. I'd like to be able to clearly articulate to the end user what they are seeing based on their actions.
Solution:
Here's how I solved my problem. Would love any feedback. In the Filament resource, I used a DTO class to generate closures with the state of any active filters. ```php...
Jump to solution
2 Replies
HerrChris
HerrChris14mo ago
Can't you just check the params?
No description
Solution
BuddhaNature
BuddhaNature14mo ago
Here's how I solved my problem. Would love any feedback. In the Filament resource, I used a DTO class to generate closures with the state of any active filters.
$table
->emptyStateActions([
Tables\Actions\CreateAction::make()
->hidden(FilamentEmptyStateDTO::actionIsHiddenWhenFiltered($table))
->label('Create a new record'),

Tables\Actions\CreateAction::make()
->hidden(FilamentEmptyStateDTO::actionIsHiddenWhenFiltered($table))
->label('Do another custom thing!')
->url(route('foo.bar')),
])
->emptyStateDescription(
FilamentEmptyStateDTO::forViews(
table: $table,
viewWhenFiltered: view('empty-state-description-when-filtered'),
viewWhenNotFiltered: view('empty-state-description')
)
)
->emptyStateHeading(
FilamentEmptyStateDTO::forViews(
table: $table,
viewWhenFiltered: view('empty-state-heading-when-filtered'),
viewWhenNotFiltered: view('empty-state-heading')
)
)
$table
->emptyStateActions([
Tables\Actions\CreateAction::make()
->hidden(FilamentEmptyStateDTO::actionIsHiddenWhenFiltered($table))
->label('Create a new record'),

Tables\Actions\CreateAction::make()
->hidden(FilamentEmptyStateDTO::actionIsHiddenWhenFiltered($table))
->label('Do another custom thing!')
->url(route('foo.bar')),
])
->emptyStateDescription(
FilamentEmptyStateDTO::forViews(
table: $table,
viewWhenFiltered: view('empty-state-description-when-filtered'),
viewWhenNotFiltered: view('empty-state-description')
)
)
->emptyStateHeading(
FilamentEmptyStateDTO::forViews(
table: $table,
viewWhenFiltered: view('empty-state-heading-when-filtered'),
viewWhenNotFiltered: view('empty-state-heading')
)
)
This is the DTO.
class FilamentEmptyStateDTO
{
public static function actionIsHiddenWhenFiltered(Table $table): Closure
{
return static function (Table $table) {
return ! empty($table->getFilterIndicators());
};
}

public static function forViews(Table $table, View $viewWhenFiltered, View $viewWhenNotFiltered): Closure
{
return static function (Table $table) use ($viewWhenFiltered, $viewWhenNotFiltered): HtmlString {
return new HtmlString(
empty($table->getFilterIndicators())
? $viewWhenNotFiltered
: $viewWhenFiltered
);
};
}
}
class FilamentEmptyStateDTO
{
public static function actionIsHiddenWhenFiltered(Table $table): Closure
{
return static function (Table $table) {
return ! empty($table->getFilterIndicators());
};
}

public static function forViews(Table $table, View $viewWhenFiltered, View $viewWhenNotFiltered): Closure
{
return static function (Table $table) use ($viewWhenFiltered, $viewWhenNotFiltered): HtmlString {
return new HtmlString(
empty($table->getFilterIndicators())
? $viewWhenNotFiltered
: $viewWhenFiltered
);
};
}
}
Want results from more Discord servers?
Add your server