essentials
Search and filters
Search across fields and relations, build filter forms, and scope the board with tabs.
Search
Searchable fields
public function kanban(Kanban $kanban): Kanban
{
return $kanban
->model(Task::class)
->statusField('status')
->searchableFields(['title', 'description', 'assignedTo.name']) // ← Add searchable fields here
->columns([
// Your columns here
]);
}
Custom search
Take over the query when the default field list isn't enough:
<?php
use Illuminate\Database\Eloquent\Builder;
public function kanban(Kanban $kanban): Kanban
{
return $kanban
->model(Task::class)
->statusField('status')
->applySearchUsing(function (Builder $query, string $search) {
return $query->where('title', 'like', '%' . $search . '%')
->orWhere('description', 'like', '%' . $search . '%')
->orWhereHas('assignedTo', function ($q) use ($search) {
$q->where('name', 'like', '%' . $search . '%');
});
})
->columns([
// Your columns here
]);
}
Loading indicator
->enableLoadingIndicator()
Filters
Advanced Kanban has no built-in filter set. You describe a form schema and apply it yourself, which means any Filament field works as a filter.
Filter indicator
->enableFilterIndicator()
Filter form
<?php
use Filament\Forms\Components\Select;
use Illuminate\Contracts\Database\Eloquent\Builder;
public function kanban(Kanban $kanban): Kanban
{
return $kanban
->model(Task::class)
->statusField('status')
->searchableFields(['title', 'description'])
->filterFormSchema([
Select::make('priority')
->options([
'low' => 'Low',
'medium' => 'Medium',
'high' => 'High',
])
->placeholder('All Priorities'),
Select::make('assigned_to')
->options(User::pluck('name', 'id'))
->placeholder('All Users'),
])
->applyFiltersUsing(function (Builder $query, array $data) {
if (! empty($data['priority'])) {
$query->where('priority', $data['priority']);
}
if (! empty($data['assigned_to'])) {
$query->where('assigned_to', $data['assigned_to']);
}
return $query;
})
->columns([
// Your columns here
]);
}
Tab filters
Filament tabs scope the board query the same way they scope a resource table. Define tabs with
modifyQueryUsing() and the active tab filters the board.
On a relation manager or MRR page
use Asmit\AdvancedKanban\Concerns\HasKanbanRelatedRecords;
use Asmit\AdvancedKanban\Contracts\HasKanban;
use Filament\Schemas\Components\Tabs\Tab;
use Illuminate\Database\Eloquent\Builder;
class ManageProjectTask extends ManageRelatedRecords implements HasKanban
{
use HasKanbanRelatedRecords;
public function getTabs(): array
{
return [
'all' => Tab::make(),
'complete' => Tab::make()
->modifyQueryUsing(fn (Builder $query) => $query->where('status', 'complete')),
'pending' => Tab::make()
->modifyQueryUsing(fn (Builder $query) => $query->where('status', 'pending')),
];
}
public function kanban(Kanban $kanban): Kanban
{
return $kanban
->model(Task::class)
->statusField('status')
// ... other Kanban config
;
}
}
On a standalone Kanban page
use Asmit\AdvancedKanban\Pages\KanbanPage;
use Filament\Resources\Concerns\HasTabs;
use Filament\Schemas\Components\Tabs\Tab;
use Illuminate\Database\Eloquent\Builder;
class TaskKanban extends KanbanPage
{
use HasTabs;
public function getTabs(): array
{
return [
'All' => Tab::make('All'),
'High Priority' => Tab::make('High Priority')
->modifyQueryUsing(fn (Builder $query) => $query->where('priority', 'high')),
];
}
public function kanban(Kanban $kanban): Kanban
{
return $kanban
->model(Task::class)
->statusField('status')
// ... other Kanban config
;
}
}
The active tab is picked on first load, and switching tabs reloads the records. Nothing else needs wiring — the board applies the active tab's query itself.