Tabulka
Editace a filtry na úrovni sloupce
Na této stránce
Filtrování na úrovni sloupce
Kromě dedikovaných tříd Filter může mít jakýkoli sloupec inline filtr ve své hlavičce.
// Select filtr v hlavičce sloupce (jedna hodnota)TextColumn::make('status') ->filterable() ->filterAsSelect(['active' => 'Active', 'inactive' => 'Inactive']) // Multi-select filtr (více hodnot → odpovídá kterékoli, whereIn). Renderuje stejný// searchable combobox jako wire-forms Select — vyhledávání je defaultně zapnuté.BadgeColumn::make('role') ->filterAsMultiSelect([ 'admin' => 'Administrator', 'editor' => 'Editor', 'viewer' => 'Viewer', ], 'Libovolná role') ->filterSearchable(false) // vypnutí vyhledávání pro krátký seznam // Boolean filtrBooleanColumn::make('is_active') ->filterable() ->filterAsBoolean() // Filtr rozsahu dataTextColumn::make('created_at') ->filterable() ->filterAsDateRange() // Filtr rozsahu číselTextColumn::make('price') ->filterable() ->filterAsNumberRange(0, 10000) // min, max, volitelný krok // Vlastní logika filtruTextColumn::make('name') ->filterable() ->filterUsing(fn (Builder $query, mixed $value) => $query->where('name', 'like', "%{$value}%")) ->filterDebounce(500) // Filtr s operátoremTextColumn::make('age') ->filterable() ->filterOperator('>=')
API filtru na úrovni sloupce
Filtr hlavičky sloupce je umístění kanonického Filter — pomocné metody
filterAs*() jsou tenké factory nad TextFilter / SelectFilter / DateFilter /
NumberRangeFilter / TernaryFilter, nebo předej hotový přes ->filter(). Sdílený
engine, chipy a query-string persistenci viz Filtry na úrovni sloupce.
->filterable(bool $filterable = true, string $type = 'text', array|string $options = [])->isFilterable(): bool->filter(Filter $filter) // připoj hotový kanonický filtr->getFilter(): ?Filter->filterAsSelect(array|string $options, ?string $placeholder = null) // jedna hodnota; searchable combobox->filterAsMultiSelect(array|string $options, ?string $placeholder = null) // více hodnot (whereIn); searchable combobox->filterSearchable(bool $condition = true) // přepnutí vyhledávání (defaultně zapnuté)->filterAsDate(string|DateTimeInterface|null $minDate = null, string|DateTimeInterface|null $maxDate = null)->filterAsDateRange(string|DateTimeInterface|null $minDate = null, string|DateTimeInterface|null $maxDate = null)->filterAsNumberRange(?float $min = null, ?float $max = null, ?float $step = null)->filterAsBoolean(?string $trueLabel = null, ?string $falseLabel = null)->filterOperator(string $operator) // '=', '!=', '>', '<', '>=', '<=', 'like' (výchozí, částečná shoda), 'starts_with', 'ends_with'->filterDebounce(int $ms)->filterPlaceholder(?string $placeholder)->filterUsing(Closure $fn) // fn(Builder $query, mixed $value)
Inline editace
Sloupce mohou také použít generické API editable() (kromě dedikovaných TextInputColumn/SelectColumn/ToggleColumn):
TextColumn::make('name') ->editable() // typ výchozí 'text' ->editableRules(fn ($record) => ['required', 'max:255']) ->editableUsing(function ($record, $column, $value) { $record->update([$column => $value]); }) TextColumn::make('category') // editable(enabled, type, options) — 'text' | 'select' | 'toggle' ->editable(true, 'select', ['a' => 'Category A', 'b' => 'Category B']) ->editableRules(fn ($record) => ['required', 'in:a,b'])
Argument options u editable(type: 'select', …) i filterable() /
filterAsSelect() přijímá i třídu PHP enumu — rozvine se na value => label přesně
jako dedikovaný SelectColumn/SelectFilter. Viz Enum Options.
Jak fungují inline uložení
Uložení buňky (updateTableCell) záměrně nepřekresluje tabulku — DOM morph by resetoval
Alpine stav všech editovatelných buněk. Místo toho každá buňka přepne svůj vzhled optimisticky
a sesynchronizuje se serverem přes jednu sdílenou Alpine komponentu (wireEditableCell): text
inputy, selecty i toggly ji používají, takže se chovají konzistentně.
- Optimistic + rollback. Buňka hned ukáže novou hodnotu, pak zavolá server; když uložení selže (validace, oprávnění, chyba), vrátí se na poslední serverem potvrzenou hodnotu a zobrazí zprávu.
- Optimistic locking. Každý edit nese verzi řádku (
updated_at). Když se řádek od načtení stránky změnil, uložení se odmítne jako konflikt: buňka načte aktuální hodnotu a zobrazí zprávu o konfliktu přímo na buňce (červený stav na text/select/toggle, bez toastu nebo nastaveníNotificationManager) — dva lidé (nebo dva rychlé edity, které řádek bumpnou) se tak tiše nepřepíšou. Polling verzi buněk obnoví v dalším cyklu. Volitelně lze pro konflikty vyvolat i (nápadnější) toast přesTable::notifyEditConflicts()— ten už vyžaduje zapojený notifikační systém (toast container); inline hláška funguje i bez něj. - Serverová autorizace. Klientský
disabled()stav je jen kosmetika — per-recorddisabled()buňka (i oprávnění sloupce) se znovu vynutí na serveru vupdateTableCell, takže forged request nemůže zapsat do zamčené buňky.