Sortable
Řazení řádků
Drag & drop řazení řádků s toggle režimem a automatickou databázovou perzistencí.
Na této stránce
Drag & drop řazení řádků s toggle režimem a automatickou databázovou perzistencí.
Základní použití
use Livewire\Component;use NyonCode\WireTable\Table;use NyonCode\WireTable\Columns\TextColumn;use NyonCode\WireTable\Concerns\WithTable;use NyonCode\WireSortable\Concerns\WithSortable; class TaskTable extends Component{ use WithTable, WithSortable; public function table(Table $table): Table { return $table ->model(Task::class) ->reorderable() ->columns([ TextColumn::make('name', 'Name'), TextColumn::make('status', 'Status'), ]); } public function render() { return view('livewire.task-table'); }}
Trait WithSortable registruje Table makra, která přidávají reorderable() a další metody do základní třídy Table. Řetězíte je přímo na $table.
Blade šablona používá computed vlastnost $table:
{{-- resources/views/livewire/task-table.blade.php --}}<div> {!! $this->table !!}</div>
Jak reorder režim funguje
- V toolbaru tabulky se objeví tlačítko „Reorder"
- Uživatel klikne na tlačítko pro vstup do reorder režimu
- V reorder režimu:
- Na každém řádku se objeví drag handly
- Stránkování je vypnuté (zobrazí se všechny záznamy)
- Řazení podle sloupce se obejde -- řádky jsou seřazené podle sort sloupce vzestupně
- Hledání a filtry zůstávají v platnosti, seznam tedy jde stále zúžit
- Uživatel táhne řádky na požadovanou pozici
- Při konci tažení se nové pořadí uloží do databáze
- Uživatel klikne na „Done reordering" pro opuštění reorder režimu
- Tabulka se vrátí do normálního stavu s obnoveným stránkováním a řazením podle sloupce
Řazení podle sloupce musí ustoupit, protože pořadí na obrazovce je přesně to pořadí, které se při puštění zapíše zpět: může být jedině pořadím sort sloupce. Hledání a filtry ustupovat nemusí, protože mění to, které řádky lze táhnout, nikoli význam tažení -- proč je to bezpečné, viz Přeřazování zúženého seznamu.
Vlastní sloupec pořadí
return $table ->model(Task::class) ->reorderable('position') ->columns([...]);
Název sloupce musí existovat ve vaší databázové tabulce. Výchozí sort_order.
Vždy zapnutý reorder režim
Pokud chcete drag handly viditelné neustále bez toggle tlačítka:
return $table ->model(Task::class) ->alwaysReorderable() ->columns([...]);
S vlastním sloupcem:
return $table ->model(Task::class) ->alwaysReorderable('position') ->columns([...]);
V tomto režimu je tabulka vždy v reorder režimu -- žádné toggle tlačítko se nevykreslí a $isReordering je při mountu nastaveno na true. Cesta zpět k běžné tabulce neexistuje, a přesně proto reorder režim ponechává hledání a filtry funkční: vyhledávací pole by na vždy přeřaditelné tabulce jinak nikdy nic neudělalo.
Podmíněné řazení
Vypněte řazení na základě podmínky (např. oprávnění uživatele):
return $table ->model(Task::class) ->reorderable('sort_order', auth()->user()->can('reorder', Task::class)) ->columns([...]);
Když je jako druhý argument předáno false, reorder tlačítko se neobjeví a metoda toggleReordering() je no-op.
Stránkované během reorderingu
Ve výchozím stavu je stránkování v reorder režimu vypnuté, aby uživatel mohl táhnout přes celý dataset. Pokud máte velký dataset a preferujete zachovat stránkování:
return $table ->model(Task::class) ->reorderable() ->paginatedWhileReordering() ->columns([...]);
Poznámka: Se zapnutým stránkováním mohou uživatelé přeřazovat jen v rámci aktuální stránky. Puštění přeuspořádá řádky té stránky mezi sebou a všechny ostatní stránky nechá tam, kde byly.
Přeřazování zúženého seznamu
Uživatel v reorder režimu může stále hledat, filtrovat a -- s
paginatedWhileReordering() -- stránkovat. Tažení se tedy obvykle odehrává nad
podmnožinou tabulky a řádky, které tato podmnožina skryla, se pohnout nesmí.
A nepohnou se, protože puštění řádky, které dostane, nepřečísluje. Posbírá hodnoty pořadí, které tyto řádky už mají, seřadí je vzestupně a rozdá je zpět v novém vizuálním pořadí:
// Řádky s sort_order 10, 20, 30. Přetáhněte poslední úplně nahoru:// před po// A 10 C 10// B 20 A 20// C 30 B 30
Tři důsledky, které stojí za to znát:
- Řádky mimo tažení se nikdy nepohnou. Zůstávají na svých pozicích, takže
hledání
auditmůže přeřadit čtyři odpovídající řádky, aniž by rozhodilo čtyři sta, které skrylo. - Mezery zůstávají zachované. Sloupec pořadí
10, 20, 30zůstane10, 20, 30. Pokud necháváte mezery pro pozdější vkládání, přeřazení je nezavře. - Prázdný nebo konstantní sloupec pořadí nemá co rozdávat. Tam, a jen tam, se
místo toho zapíšou pozice od klienta (
1..n) -- což je pro sloupec, který žádné pořadí nenesl, ta správná odpověď.
Lifecycle hooky
Přepište tyto metody ve své komponentě pro zapojení do reorder procesu:
protected function beforeReorder(array $items): void{ // Autorizovat, validovat nebo odeslat pre-reorder logiku $this->authorize('reorder', Task::class);} protected function afterReorder(array $items): void{ // Vyčistit cache, odeslat události, zalogovat aktivitu Cache::forget('tasks.ordered'); $this->dispatch('tasks-reordered');}
Každá položka $items je asociativní pole:
[ ['value' => '1', 'order' => 1], ['value' => '5', 'order' => 2], ['value' => '3', 'order' => 3],]
value-- primární klíč záznamuorder-- nová 1-based pozice
Vlastní primární klíč
Ve výchozím stavu reorder dotazy používají primární klíč tabulky (id). Pokud váš model používá jiný klíč:
return $table ->model(Task::class) ->primaryKey('uuid') ->reorderable() ->columns([...]);
Tok řazení řádků
- Toolbar tabulky ukáže reorder toggle, když je řazení řádků zapnuté
- Uživatel vstoupí do reorder režimu
- Tabulka zobrazí záznamy seřazené podle nakonfigurovaného sloupce pořadí
- Uživatel táhne řádky do požadovaného pořadí
- Wire Sortable přijme nové pořadí a aktualizuje sloupec pořadí v jedné databázové transakci
- Vaše hooky
beforeReorder()aafterReorder()běží kolem uložení - Tabulka se obnoví a opustí nebo zůstane v reorder režimu podle akce uživatele