Sortable
Řazení sloupců
Drag & drop řazení hlaviček sloupců s databázovou perzistencí per uživatel, per tabulka.
Na této stránce
- Základní použití
- Databázová perzistence
- Struktura úložiště
- Jak se načítá
- Jak se ukládá
- Validace názvů sloupců
- Získání seřazených sloupců
- Resetování pořadí sloupců
- Kombinace s řazením řádků
- Více tabulek nad stejným modelem
- Vlastní resolvování uživatele
- Vlastní typ modelu
- Hosté (neautentizovaní uživatelé)
- Tok řazení sloupců
Drag & drop řazení hlaviček sloupců s databázovou perzistencí per uživatel, per tabulka.
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) ->columnReorderable() ->columns([ TextColumn::make('name', 'Name'), TextColumn::make('status', 'Status'), TextColumn::make('priority', 'Priority'), ]); }}
Uživatelé mohou táhnout hlavičky sloupců pro jejich přeuspořádání. Buňky těla se přeřadí automaticky, aby odpovídaly.
Databázová perzistence
Pořadí sloupců je uloženo v tabulce reorderable_column_orders s unikátním omezením na (user_id, model_type, table_identifier). To znamená:
- Každý uživatel má své vlastní uspořádání sloupců
- Uspořádání je vázáno na třídu Eloquent modelu i třídu Livewire komponenty
- Více table komponent zobrazujících stejný model dostane nezávislá pořadí sloupců
- Když je uživatel smazán, jeho pořadí sloupců se kaskádově smaže
Struktura úložiště
reorderable_column_orders├── user_id: 1│ ├── model_type: "App\Models\Task", table_identifier: "App\Livewire\TaskListTable"│ │ → ["status", "name", "priority"]│ ├── model_type: "App\Models\Task", table_identifier: "App\Livewire\TaskBoardTable"│ │ → ["priority", "name", "status"]│ └── model_type: "App\Models\User", table_identifier: "App\Livewire\UserTable"│ → ["email", "name", "role"]├── user_id: 2│ └── model_type: "App\Models\Task", table_identifier: "App\Livewire\TaskListTable"│ → ["priority", "status", "name"]
Jak se načítá
Při mountu komponenty (mountWithSortable) trait:
- Získá ID aktuálního uživatele přes
getReorderableUserId()(výchozíauth()->id()) - Získá typ modelu přes
getReorderableModelType()(třída Eloquent modelu) - Získá identifikátor tabulky přes
getReorderableTableIdentifier()(třída Livewire komponenty) - Dotáže se
ReorderableColumnOrder::getOrder($userId, $modelType, $tableIdentifier) - Když najde, nastaví
$reorderableColumnOrderuloženými názvy sloupců
Jak se ukládá
Když uživatel táhne hlavičku sloupce:
- Alpine.js přečte nové pořadí hlaviček z atributů
th[data-sortable-column] - Zavolá
$wire.reorderColumns(['status', 'name', 'priority']) - Trait zvaliduje názvy sloupců proti definici tabulky (ignoruje neznámé sloupce)
- Uloží přes
ReorderableColumnOrder::saveOrder($userId, $modelType, $tableIdentifier, $columnOrder)
Validace názvů sloupců
Trait filtruje příchozí názvy sloupců proti definici tabulky. Perzistují se jen názvy, které odpovídají definovanému sloupci. To předchází:
- Injektování libovolných názvů sloupců z frontendu
- Zastaralým názvům sloupců, které by rozbily tabulku poté, co je sloupec odebrán z definice
Při načítání uloženého pořadí se sloupce, které už v definici neexistují, tiše přeskočí. Nově přidané sloupce (nepřítomné v uloženém pořadí) se připojí na konec.
Získání seřazených sloupců
Použijte getReorderableColumns() pro získání sloupců v uživatelem preferovaném pořadí:
$columns = $this->getReorderableColumns();
To vrátí všechny definované sloupce seřazené podle uloženého pořadí. Sloupce nepřítomné v uloženém pořadí se připojí na konec.
Resetování pořadí sloupců
Zavolejte resetColumnOrder() pro obnovení výchozího pořadí:
<button wire:click="resetColumnOrder"> Reset Column Order</button>
To vyčistí jak vlastnost komponenty, tak databázový záznam.
Kombinace s řazením řádků
Řazení řádků a sloupců funguje nezávisle a lze je použít společně:
return $table ->model(Task::class) ->reorderable('position') ->columnReorderable() ->columns([...]);
Více tabulek nad stejným modelem
Ve výchozím stavu je identifikátor tabulky třída Livewire komponenty (static::class). To znamená, že dvě komponenty jako TaskListTable a TaskBoardTable, které obě dotazují App\Models\Task, budou mít nezávislá pořadí sloupců bez jakékoli extra konfigurace.
Pokud potřebujete vlastní identifikátor (např. jedna komponenta, která vykresluje různé konfigurace tabulky), přepište getReorderableTableIdentifier():
protected function getReorderableTableIdentifier(): string{ return static::class . ':' . $this->tableVariant;}
Vlastní resolvování uživatele
Ve výchozím stavu trait používá auth()->id() k identifikaci uživatele. Přepište getReorderableUserId() pro vlastní logiku:
// Multi-guard autentizaceprotected function getReorderableUserId(): ?int{ return auth('admin')->id();}
Vlastní typ modelu
Ve výchozím stavu se typ modelu resolvuje z $table->getQuery()->getModel(). Přepište getReorderableModelType(), pokud potřebujete vlastní klíč:
protected function getReorderableModelType(): ?string{ return 'custom-key';}
Hosté (neautentizovaní uživatelé)
Když getReorderableUserId() vrátí null, řazení sloupců se tiše vypne:
mountWithSortable()přeskočí načítání uloženého pořadíreorderColumns()je no-opresetColumnOrder()vyčistí jen lokální vlastnost
Drag & drop UI stále funguje v prohlížeči (přes Alpine.js), ale změny se neperzistují.
Tok řazení sloupců
- Alpine komponenta zavolá
initColumnSortable()na prvním<thead tr> - Hlavičkové buňky se identifikují podle
wire:click="sortTable('column')"nebo atributůdata-column - Každá identifikovaná buňka dostane atribut
data-sortable-columna kurzorgrab - SortableJS zapne vodorovné tažení elementů
th[data-sortable-column] - Při konci tažení se
<td>buňky těla přeřadí, aby odpovídaly novému pořadí hlaviček - Nová sekvence názvů sloupců se pošle do
reorderColumns()přes Livewire - Trait zvaliduje názvy sloupců, uloží do
reorderable_column_ordersa aktualizuje lokální vlastnost - Ne-datové sloupce (výběr, akce, drag handle) jsou z tažení vyloučeny