how to make custom column sortable

I have a custom column in my table, which i want to be able to sort it. the custom column contains numbers from a calculation, so they are not part of the fields of the model represented in the table
Solution:
that should be it, and you dont need games() or gamesCount() functions
Jump to solution
12 Replies
Dan Harrin
Dan Harrin2y ago
define a sortable() callback which does the SQL necessary to sort
ericmp
ericmpOP2y ago
where should i define it? inside the custom column, or when calling it in the table? not sure how to do it my code at the moment:
TeamGamesCountColumn::make('games')
->sortable(true, function ($query) {
// $query->
})
->translateLabel()
,
TeamGamesCountColumn::make('games')
->sortable(true, function ($query) {
// $query->
})
->translateLabel()
,
<?php

namespace App\Tables\Columns;

use Closure;
use Filament\Tables\Columns\Column;

class TeamGamesCountColumn extends Column
{
protected string $view = 'tables.columns.team-games-count-column';
}
<?php

namespace App\Tables\Columns;

use Closure;
use Filament\Tables\Columns\Column;

class TeamGamesCountColumn extends Column
{
protected string $view = 'tables.columns.team-games-count-column';
}
view:
<div>
{{ $getRecord()->gamesCount() }}
</div>
<div>
{{ $getRecord()->gamesCount() }}
</div>
Dan Harrin
Dan Harrin2y ago
what is gamesCount you define it when building the table btw... there is no need for a custom column for this
TextColumn::make('games')
->getStateUsing(fn ($record) => $record->gamesCount())
->sortable(true, function ($query) {
// $query->
})
->translateLabel()
TextColumn::make('games')
->getStateUsing(fn ($record) => $record->gamesCount())
->sortable(true, function ($query) {
// $query->
})
->translateLabel()
ericmp
ericmpOP2y ago
public function games(): Builder
{
return Game::query()
->where('team_a', $this->id)
->orWhere('team_b', $this->id)
;
}
public function games(): Builder
{
return Game::query()
->where('team_a', $this->id)
->orWhere('team_b', $this->id)
;
}
oh really
Dan Harrin
Dan Harrin2y ago
what is gamesCount
ericmp
ericmpOP2y ago
is a function inside team model. a game always has a team_a field and team_b field which are relations of the team table so to get the games where that team is in, i call this function cuz idk how to set a hasmany/belongstomany relationship based on 2 possible columns idk if im explaining myself dont worry, ill try to fix it. thanks for ur time
Dan Harrin
Dan Harrin2y ago
the way youre doing it is not very optimal, because its actually causing an n+1 issue to start with, add two hasmany relationships on your model, gamesA and gamesB, each using just one foreign key then on the filament table column, add ->counts(['gamesA', 'gamesB']) then, ->getStateUsing(fn ($record) => $record->games_a_count + $record->games_b_count) then, ->sortable(true, fn ($query, $direction) => $query->orderByRaw('games_a_count + games_b_count ' . $direction))
Solution
Dan Harrin
Dan Harrin2y ago
that should be it, and you dont need games() or gamesCount() functions
ericmp
ericmpOP2y ago
thanks. ill try it. but how im causing the n+1 issue?
Dan Harrin
Dan Harrin2y ago
because you're making a query for every table row
ericmp
ericmpOP2y ago
that is awesome, works like a charm how the hell u actually solved it without even knowing my code lol i hope one day can be like u ^^ this is how it looks like now:
TextColumn::make('games')
->getStateUsing(function ($record) {
return $record->games_a_count + $record->games_b_count;
})
->counts(['gamesA', 'gamesB'])
->sortable(true, function ($query, $direction) {
$query->orderByRaw('games_a_count + games_b_count ' . $direction);
})
->translateLabel()
TextColumn::make('games')
->getStateUsing(function ($record) {
return $record->games_a_count + $record->games_b_count;
})
->counts(['gamesA', 'gamesB'])
->sortable(true, function ($query, $direction) {
$query->orderByRaw('games_a_count + games_b_count ' . $direction);
})
->translateLabel()
Dan Harrin
Dan Harrin2y ago
haha its ok
Want results from more Discord servers?
Add your server