Tricks

Apply filter by clicking on value in column

Sep 10, 2022
studiowizjo
Table builder, Admin panel

You can easily filter data in a table by clicking on a given value in cell, instead of opening filters and selecting value from there:

Apply filter by clicking on value in column

TextColumn::make('user.full_name')
->label('Person')
->tooltip('Filter by this person')
->disableClick()
->extraAttributes(function (Settlement $record) {
return [
'wire:click' => '$set("tableFilters.users.values", [' . $record->user_id . '])',
'class' => 'transition hover:text-primary-500 cursor-pointer',
];
}),

tableFilters.users.values - "users" is your filter name and depending on whether your filter allows multiple values to be selected values should be replaced by value and the field value should be passed as array or not.

If you need to set few filters at once, unfortunately you cannot set it inline, but instead you can extract it to dedicated method:

TextColumn::make('created_at')
->date()
->tooltip('Show only from this day')
->disableClick()
->extraAttributes(function ($record) {
return [
'wire:click' => 'filterFromDay("' . $record->created_at->format('Y-m-d') . '", "' . $record->created_at->format('Y-m-d') . '")',
'class' => 'transition hover:text-primary-500 cursor-pointer',
];
}),

and here is that method, which you should place in your ListRecords resource:

public function filterFromDay(string $from, string $until) : void
{
$this->tableFilters['date_range']['created_from'] = $from;
$this->tableFilters['date_range']['created_until'] = $until;
}
avatar

Hi, The trick doesn't work since the quotes get escaped:

wire:click="$set('tableFilters.status.value', ' . open . ')"

Do you know how to fix this?

avatar

I dont't see your code, just the output, so it's hard to say, but I think maybe you're using double quotes instead of single. You can then try to escape them or extract method, the same as shown in the second example.

avatar

I copied your exact fragment, though I use a string as value:

ResourceHelperService::getColumn('status')
->tooltip('Filter by this status')
->disableClick()
->extraAttributes(function ($record) {
return [
'wire:click' => '$set("tableFilters.status.value", "' . $record->status->value . '")',
'class' => 'transition hover:text-primary-500 cursor-pointer',
];
}),

The output results in this:

<div class="filament-tables-text-column px-4 py-3
transition hover:text-primary-500 cursor-pointer"
wire:click="$set(&amp;quot;tableFilters.status.value&amp;quot;, &amp;quot;open&amp;quot;)">
 
<div class="inline-flex items-center space-x-1 rtl:space-x-reverse">
 
<span class="">
open
</span>
 
</div>
 
</div>

not only the status 'open' gets escaped, but the double quotes around tableFilters.status.value as well.

BTW: my Filament version is v2.17.17.

👍 1
avatar

It works, if you wrap the value for 'wire:click' in extraAttributes in a new HtmlString()

👍 2
🥳 1
👀 1
avatar

Thanks for the hint, after a few tries I got it to work like this:

'wire:click' => new HtmlString("\$set('tableFilters.status.value', '{$record->status->value}')"),

With inverted quotes and the Dollar-sign in $set needs to be escaped

avatar

With suggestion of @Josef Behr I do like this and work. Thank all...

<?php
 
protected function table(Table $table): Table
{
return $table
->columns([
// ...
 
Tables\Columns\IconColumn::make('email_verified_at')
->label(__('Verified'))
->sortable()
->disableClick()
->trueColor('success')
->falseColor('danger')
->extraAttributes(function ($record) {
$verifiedFilter = $record?->email_verified_at ? 'verified' : 'Not_verified';
 
return [
'wire:click' => new \Illuminate\Support\HtmlString("\$set('tableFilters.{$verifiedFilter}.isActive', [1])"),
'class' => 'transition hover:text-primary-500 cursor-pointer',
];
}),
// ...
])
->filters([
Tables\Filters\Filter::make('verified')
->query(fn (Builder $query): Builder => $query->whereNotNull('email_verified_at')),
 
Tables\Filters\Filter::make('Not_verified')
->query(fn (Builder $query): Builder => $query->whereNull('email_verified_at')),
])
->actions([
//
])
->bulkActions([
//
]);
}
😍 1
avatar

Thank you!

avatar

Nice trick! It works to change the url but does not reload the table. How can the filter be applied (table refresh)? (I'm using v3)