Tabulka
Fill handle (vyplňování tažením jako v Excelu)
Táhnutím přenesete hodnotu z jedné editovatelné buňky na řádky pod ní — stejně jako v Excelu nebo Google Sheets. Celý rozsah se zapíše jedním requestem.
Na této stránce
Táhnutím přenesete hodnotu z jedné editovatelné buňky na řádky pod ní — stejně jako v Excelu nebo Google Sheets. Celý rozsah se zapíše jedním requestem.
Zapíná se per tabulka:
use NyonCode\WireTable\Columns\SelectColumn;use NyonCode\WireTable\Columns\TextInputColumn;use NyonCode\WireTable\Columns\ToggleColumn; public function table(Table $table): Table{ return $table ->model(Task::class) ->fillHandle() ->columns([ TextInputColumn::make('reference')->fillable(false), SelectColumn::make('status')->options([ 'open' => 'Otevřeno', 'done' => 'Hotovo', ]), ToggleColumn::make('is_urgent'), ]);}
Najetím myší na vyplňovatelnou buňku — nebo jejím zaměřením — se v pravém dolním rohu objeví malý čtvereček; jakmile na něj dojedete, rozbalí se do popsaného tlačítka pro kopírování. Tažením dolů se pokryté řádky zvýrazní. Dokud tlačítko nepustíte, nezapíše se nic a neodejde žádný request. Escape tažení zruší.
Reakce na najetí je záměr: kdyby bylo nutné nejdřív kliknout, otevřeli byste editor jen kvůli zobrazení úchytu. Zaměřená buňka si úchyt udrží, takže neuteče z řádku, do kterého zrovna píšete.
API
// Table->fillHandle(bool $condition = true) // zapnutí (výchozí: vypnuto)->isFillHandleEnabled(): bool->fillMaxRecords(int $max) // strop řádků na jeden request (výchozí 500)->getFillMaxRecords(): int // Column->fillable(bool $condition = true) // výchozí true pro editovatelné sloupce->isFillable(): bool
fillable() má smysl jen na sloupci, který už je editovatelný — zobrazovací
sloupec vyplnit nelze nikdy. Vypněte ho tam, kde opakování jedné hodnoty nedává
smysl nebo je nebezpečné: číslo faktury, unikátní kód, per-záznamový token.
Co vyplnění doopravdy dělá
Každý záznam projde stejnou cestou jako jedna inline editace: vlastní
kontrolou canEdit(), vlastní validací, vlastní verzí pro optimistické zamykání.
Request je jeden, zápisy jsou per záznam.
Je to záměr, ne opomenutá optimalizace. Jediné UPDATE … WHERE id IN (…) by
obešlo Eloquent události, casty a mutátory, nesáhlo by na updated_at — což je
přesně to, co optimistický zámek porovnává — a neumělo by vyjádřit sloupec
ukládaný přes editableUsing(), relaci ani pivot. Svislé tažení navíc dosáhne
jen na vyrenderované řádky, takže je jejich počet stejně omezený stránkou.
Vyplnění není všechno nebo nic
Když jeden řádek prohraje závod o optimistický zámek nebo je pro uživatele
zakázaný, nezahodí to řádky, které se uložily. Každý záznam dostane vlastní
výsledek a klient se smíří buňku po buňce — potvrdí ty zapsané a vrátí zpět jen
ty ostatní. Částečné vyplnění hlásí „Uloženo :filled z :total řádků".
Celou transakci vrátí zpět jen infrastrukturní chyba.
Bezpečnost
- Endpoint odmítne rovnou, pokud tabulka nezavolala
fillHandle()— nelze ho tedy použít proti tabulce, která tuhle možnost nikdy nenabídla. - Záznamy se hledají přes vlastní dotaz tabulky, takže klíč mimo něj neodpovídá ničemu a je ohlášen jako nenalezený — podvržený request se nedostane na řádek, který tabulka nikdy nezobrazila.
- Oprávnění sloupce (
->permission()) i per-záznamovécanEdit()se vynucují znovu na serveru; klientský stavdisabled()je jen kosmetický. fillMaxRecords()omezuje, kolik toho jeden request smí zapsat.
Události
Každá vyplněná buňka vyvolá CellUpdating a CellUpdated přesně jako jedna
inline editace, takže auditní listener uvidí vyplnění bez jakékoli změny.
Samostatná hromadná událost neexistuje.
Rozsah
První verze vyplňuje jen svisle — jeden sloupec, dolů nebo nahoru od zdrojové buňky. Vodorovné vyplnění, obdélníkové výběry, podpora schránky a rozpoznávání posloupností (1, 2, 3 …) implementované nejsou; hodnota se duplikuje, nikdy neextrapoluje.
Poznámky
- Funguje myší, dotykem i perem přes Pointer Events; tažení za okraj viewportu automaticky roluje.
- Úchyt se nikdy neobjeví na buňce se zakázaným ovládacím prvkem ani na per-záznamově readonly buňce — ty žádný editovatelný input nevykreslí.
- Stejně jako jedna inline editace tabulku nepřekresluje: buňky se smíří samy, takže Alpine stav všech ostatních editovatelných buněk přežije.
- Tabulka s
queryCached()bude po vyplnění servírovat cachovaná data až do vypršení TTL — přesně jako po jakékoli jiné mutaci. - Vyplnění se řadí do fronty, vždy jeden request. Každé posílá verze, které vrátilo to předchozí. Táhnout znovu dřív, než dorazí poslední odpověď, je v pořádku — počká si, místo aby odešlo s verzemi, přes které už server přešel a odmítl by je jako zastaralý zápis.
Rozlišení zámku
Verze řádku je jeho updated_at jako unixový timestamp, takže dva zápisy uvnitř
jedné vteřiny jsou nerozlišitelné. Zastaralá verze se tam neodhalí.
V praxi to hraje roli jen při opakovaném zápisu do stejných řádků v rychlém sledu
— proto klient requesty řadí. Pokud voláte fillTableCells() sami — z testu,
skriptu nebo vlastního frontendu — posílejte verze, které vrátilo předchozí
volání; nepoužívejte znovu ty, se kterými jste začali.
Související
- Editace a filtry na úrovni sloupce — jak funguje jedno inline uložení
- TextInputColumn · SelectColumn · ToggleColumn
- Vrstva gest — handle je jedna z jejích schopností;
gestures(false)ho zavře i s endpointem