В этом видео автор демонстрирует множество практических примеров использования фильтров таблиц в Filament, таких как фильтры с кастомизацией макета, различными опциями и инструментами для настройки фильтров пользователем. Автор подчеркивает, что у фильтров таблиц есть много скрытых или менее известных функций, большинство из которых описаны в документации по фильтрам Select, но документация не содержит скриншотов. Поэтому автор решил продолжить свою традицию визуализации документации в видеоформате, показывая, что происходит при использовании определенных опций из Filament.
Простой фильтр Select:

- Фильтр для выбора отраслей клиентов.
- Можно кастомизировать метку фильтра и опции.
- Фильтр доступен для поиска.
| 1 2 3 4 5 | SelectFilter::make('type') ->label('Type') ->options(self::typeOptions()) ->indicator('Selected type') ->searchable(), |
| 1 2 3 4 5 6 7 8 9 | protected static function typeOptions (): array { return [ 'hotel' => 'Hotel', 'coworking' => 'Coworking', 'meeting_room' => 'Meeting Room', 'event_space' => 'Event Space', ]; } |
Фильтр Select с данными из базы данных:

Опции могут быть массивом или результатом пользовательского запроса к базе данных.
Пример: фильтр по странам, полученным из таблицы клиентов.
| 1 2 3 4 5 6 7 8 9 10 | SelectFilter::make('country') ->label('Country') ->options(fn (): array => Property :: query() ->select('country') ->whereNotNull('country') ->distinct() ->orderBy('country') ->pluck('country', 'country') ->toArray()) ->searchable(), |
Тернарный фильтр (Ternary Filter):


Фильтр «Да/Нет» для активных значений. По умолчанию отображаются все значения, но можно выбрать только активные или не активные.
| 1 2 3 | TernaryFilter::make('is_active') ->label('Is Active') ->indicator('Active Status'), |
Фильтр с использованием отношений бд:

Фильтр по клиентам из базы данных, полученным через отношение. Использование отношения вместо статического массива опций.
| 1 2 3 4 5 6 | SelectFilter::make('property') ->label('Property') ->relationship('property', 'name') ->indicator('Property') ->searchable() ->preload(), |
Но обязательно в модели Booking должна быть связь BelongTo
| 1 2 3 4 5 6 7 | /** * Get the property for the booking. */ public function property(): BelongsTo { return $this->belongsTo(Property::class); } |
Кастомный фильтр дат:

| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | Filter::make('check_in_range') ->label('Check in between') ->indicator('Check in beetween') ->schema([ DatePicker::make('check_in_from') ->label('From'), DatePicker::make('check_in_until') ->label('Until'), ]) ->columns(2) ->indicateUsing(function(array $data):array{ $indicators = []; if (filled($data['check_in_from'] ?? null)) { $indicators[] = Indicator::make('Check in from '. Carbon::parse($data['check_in_from'])->toFormattedDateString()) ->removeField('check_in_from'); } if (filled($data['check_in_until'] ?? null)) { $indicators[] = Indicator::make('Check in until '. Carbon::parse($data['check_in_until'])->toFormattedDateString()) ->removeField('check_in_until'); } return $indicators; }) ->query(function(Builder $query,array $data):Builder{ return $query ->when( filled($data['check_in_from'] ?? null), fn (Builder $query) => $query->whereDate('check_in', '>=', $data['check_in_from']) , ) ->when( filled($data['check_in_until'] ?? null), fn (Builder $query) => $query->whereDate('check_in', '<=', $data['check_in_until']) , ); }), |
Фильтр для диапазона чисел

Фильтрация по минимальной и максимальной сумме.
Кастомный запрос с использованием Eloquent.
Форматирование чисел, добавление знака доллара и округление.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | Filter::make('price_range') ->label('Price range') ->indicator('Price range') ->schema([ TextInput::make('min_price') ->label('Minimum price') ->numeric() ->prefix('$'), TextInput::make('max_price') ->label('Maximum price') ->numeric() ->prefix('$'), ]) ->columns(2) ->indicateUsing(function(array $data):array{ $indicators = []; if (filled($data['min_price'] ?? null)) { $indicators[] = Indicator::make('Min $'.number_format((float) $data['min_price'], 2)) ->removeField('min_price'); } if (filled($data['max_price'] ?? null)) { $indicators[] = Indicator::make('Max $'.number_format((float) $data['max_price'], 2)) ->removeField('max_price'); } return $indicators; }) ->query(function(Builder $query,array $data):Builder{ return $query ->when( filled($data['min_price'] ?? null), fn (Builder $query) => $query->where('price_per_night', '>=', (float)$data['min_price']) , ) ->when( filled($data['max_price'] ?? null), fn (Builder $query) => $query->where('price_per_night', '<=', (float)$data['max_price']) , ); }), |
Фильтр со связанными выпадающими списками

В фильтре есть два выпадающих списка. Если пользователь выбирает значение из первого списка, то активируется второй список и дает выбрать значение.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | Filter::make('property_room') ->label('Property, Room') ->indicator('Property & Room') ->schema([ Select::make('property_id') ->label('Property') ->relationship('property', 'name') ->searchable() ->preload() ->live(), Select::make('room_id') ->label('Room') ->relationship('room', 'name') ->options(function (Get $get):array { $propertyId = $get('property_id'); if(!$propertyId){ return []; } return Room::query() ->where('property_id',$propertyId) ->orderBy('name') ->pluck('name','id') ->toArray(); }) ->searchable() ->preload() ->disabled(fn (Get $get): bool => !filled($get('property_id'))), ]), |
Тернарный фильтр со сложным запросом

Фильтр по проектам, зависящий от выбранного клиента.
Динамическое обновление опций второго фильтра.
| 1 2 3 4 5 6 7 8 9 10 | TernaryFilter::make('overdue') ->label('Overdue') ->indicator('Overdue') ->queries( true: fn (Builder $query):Builder => $query ->whereDate('check_out','<',now()) ->whereNull('cancelled_at'), false: fn (Builder $query):Builder => $query ->whereDate('check_out','>=',now()) ), |
Макет и организация полей

o Группировка фильтров в секции.
o Использование колонок и других элементов макета.

Power Tools:

o Использование Query Builder для создания пользовательских условий фильтрации.
o Пример: добавление правил для приоритета и даты открытия.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | QueryBuilder::make() ->constraints([ RelationshipConstraint::make('property') ->label('Property') ->relationship('property', 'name'), RelationshipConstraint::make('room') ->label('Room') ->relationship('room', 'name'), BooleanConstraint::make('total') ->label('is_active'), SelectConstraint::make('status') ->label('status') ->options([ 'pending'=>'Pending', 'confirmed'=>'Confirmed', 'checked_in'=>'Check In', 'checked_out'=>'Check Out', 'cancelled'=>'Cancelled', 'no_show'=>'No show' ]), DateConstraint::make('check_in') ->label('Check in'), ]) |







