DataGrid: Data Paging and Scrolling
Mreže, ki segajo čez višino okna: nativno drsenje, straničenje na strani strežnika in sprotno nalaganje med drsenjem – ter odločitev proti navideznemu drsenju.
Velike sezname DataGrid straniči na strežniku in jih med drsenjem sproti nalaga: če mreža sega čez vidno območje, doda naslednjo stran, ko bralec pride do konca. Brez JavaScripta ostane za upravljanje vrstica straničenja.
Nazaj: predstavitveni pregled
1. Pregled in namen
Stanje: [Live] – nativno drsenje, straničenje na strani strežnika
(možnost paging) in na njem zgrajeno sprotno nalaganje (Infinite
Loading) za mreže, ki segajo čez višino vidnega območja; namenoma brez
navideznega drsenja (arhitekturna odločitev, odsek 3). Referenca: DevExpress
ASPxGridView »Paging and Scrolling« / način navideznega drsenja.
2. Predpogoji
Brez dodatnih – zadošča osnovna pogodba dataGrid(); nativno drsenje deluje brez dodatnih nastavitev.
3. Koncepti
Namerna omejitev: na tej stopnji brez navideznega drsenja. Utemeljitev: navidezno drsenje (v DOM ohranjati le vidne vrstice, preostale sproti izrisovati glede na zamik drsenja) zahteva izrisovalnik v JS z lastnim stanjem – to je v nasprotju z načelom »brez ponovne izvedbe izrisovalnika mreže v JS« (layout → mehanika postavitve). Za zelo velike nabore rezultatov je predvidena pot zmanjšanje na strani strežnika (filtri, straničenje), ne virtualizacija na strani odjemalca.
4. Prvi koraki
// Brez funkcije straničenja odgovornost za smiselno število vrstic // nosi klicatelj -- npr. prek stavka SQL LIMIT pred dataGrid(). $rows = $db->queryAll('SELECT id, name, status FROM opravila ORDER BY id LIMIT 500'); echo $widgets->dataGrid($columns, $rows, [ 'empty' => 'Ni najdenih opravil.', ]);
Napačno: rezultat z več deset tisoč vrsticami nefiltriran posredovati
dataGrid(). Brez navideznega drsenja gradnik izriše vsako vrstico kot
pravo <tr> – DOM postane velik in stran opazno počasna; to ni napaka
gradnika, temveč dokumentirana omejitev te stopnje.
5. Uporaba
| Količina podatkov | Priporočena pot |
|---|---|
| majhna/srednja (do nekaj sto vrstic) | dataGrid() neposredno, nativno drsenje zadošča |
| velika | SQL LIMIT/WHERE pred klicem, glejte odsek 4 |
| zelo velika, upravlja jo uporabnik | straničenje na strani strežnika prek $opts['paging'] (odsek 6) |
6. Referenca API
[Live] Nativno drsenje brskalnika
Telo mreže (.wk-datagrid__body) ima overflow: auto – vse
$rows se v celoti izrišejo v DOM, drsenje pa prevzame brskalnik
(sestavina 3 recepta v
adaptivity →
recept CSS). To je edini podprt način prikaza – ključa $opts za
virtualizacijo ni; straničenje je od polne izvedbe na voljo prek
$opts['paging'] (naslednji razdelek).
[Live] Izbirno straničenje
Za nabore rezultatov, ki jih straniči strežnik (virtualizacija ostaja izključena, glejte odsek 3 – le klasično straničenje):
'paging' => ['page' => int, 'pageSize' => int, 'total' => int, 'pageUrl' => callable]izriše vrstico straničenja pod telesom mreže (.wk-datagrid__paging): Prva/Prejšnja/»Stran X od Y (N vnosov)«/Naslednja/Zadnja kot navadne povezave zaria-label; neaktivna konca se izrišeta kot posivljena elementa span.- Podobno kot
sortUrl/filterAction:pageUrl(int $page): stringvrne URL za vsako stran – pot brez JS je sama funkcija; klicatelj$rowsstraniči sam (SQLLIMIT/OFFSET). pageSizeje izbiren; brez njega velja privzeta velikost strani za ves projekthelper_plugin_wkfluentui_widgets::PAGE_SIZE= 12 vrstic. Vsak seznam v izdelku se začne z enako velikostjo strani – če tu nastavite drugo število, odstopate namerno in razlog navedite pri klicatelju.pageUrlvrne NEOBDELAN URL (ločilo&, ne&). Gradnik sam maskira na vsakem mestu, kjer URL vstavi. Če mu podate že maskirano obliko, v HTML-ju nastane&; brskalnik to dekodira v dobesedni&, in vsak parameter za prvim se tedaj imenujeamp;do,amp;page, … – stran 2 neopazno pristane v pregledu skrbništva. 2026-07-30 so bili prizadeti štirje klicatelji hkrati (wkidentity uporabniki, wkblog prispevki/komentarji, wksqliteds Browse), ker pomožne metodeurl()teh modulov privzeto maskirajo. Gradnik od tedaj dodatno normalizira (str_replace('&', '&', …)), kerwl()vrednosti parametrov kodira z odstotki in je dobesedni&v ustvarjenem URL-ju zato vedno ločilo, nikoli podatek.
[Live] Infinite Loading (sprotno nalaganje med drsenjem)
Pravilo (zahteva uporabnikov 2026-07-29): ko mreža preseže višino
vidnega območja, samodejno preklopi v način sprotnega nalaganja.
Izvedba: paging poleg vrstice straničenja objavi še URL naslednje strani in
lastne seštevke kot podatkovne atribute na .wk-datagrid__more;
scripts/gridinfinite.js med izvajanjem odloči, ali se način vklopi –
odločilno dejstvo (ali ta mreža sega čez vidno območje?) obstaja šele po
izračunu postavitve.
| Obnašanje | Opis |
|---|---|
| Merilo za vklop | Telo mreže se dejansko pomika (scrollHeight > clientHeight) ali pa je vrstica za nalaganje pod robom vidnega območja. Kratki seznami ostanejo pri vrstici straničenja. |
| Trenutek vklopa | Po load in dveh izrisih slike, ne ob DOMContentLoaded. Prej veriga višin delovne površine še ni določena; opazovalec bi dobil koren drsenja, v katerem se njegov sprožilec nikoli ne pojavi, in nič se ne bi naložilo. Do takrat upravljanje opravlja vrstica straničenja. |
| Sprožilec | Prazna točka .wk-datagrid__sentinel v območju, ki se pomika, za tabelo: ko bralec pride do zadnje vrstice, doseže tudi njo. Skript jo vstavi sam – brez skripta nima pomena. Vidna vrstica .wk-datagrid__more je zunaj drsenja in za sprožilec ni primerna: ves čas je vidna, IntersectionObserver pa sporoča spremembe. |
| Opazovalec | IntersectionObserver z rootMargin: 300px in korenom = prednikom, ki se pomika (v lupini delovne površine se pomika telo mreže samo; opazovalec, zasidran na vidno območje, se tam ne bi nikoli sprožil). |
| Več strani zapored | Po vsakem dodajanju skript preveri, ali je sprožilec še vedno v dosegu, in po potrebi nalaga naprej. To se omeji samo: ko nove vrstice sprožilec potisnejo iz vidnega območja, se ustavi. Brez tega preverjanja bi ostalo pri natanko eni strani – pri prekrivanju se namreč ni nič spremenilo. |
| Po vklopu | Vrstica straničenja se skrije in jo nadomesti pravi gumb »Naloži več« – samo sproženje z drsenjem brez kazalne naprave ni uporabno. Vrstica stanja role=status/aria-live=polite: »naloženih 24 od 40«. |
| Zadnja stran | Gumb izgine, vrstica straničenja ostane skrita: vse, kamor bi lahko vodila, je že v DOM. |
| Napaka | Neuspešen prenos (potekla seja, napaka strežnika, napačno maskiran URL) ustavi način, obnovi vrstico straničenja in vzrok zapiše v konzolo brskalnika. Bralec ne sme nikoli ostati brez obojega. |
| Izklop | 'paging' => [..., 'infinite' => 'off'] mrežo strogo drži pri straneh – smiselno za zaslone, katerih vrstice se urejajo na mestu: naknadno naložene strani bi neshranjen obrazec neopazno povečale. |
| Naknadno vstavljene mreže | window.wkGridInfinite.init(root) idempotentno inicializira poddrevo – za mreže, ki jih v stran šele prineseta dialog.js/auxbar.js. |
Brez navideznega drsenja (odsek 3 velja nespremenjeno): vsaka naložena
vrstica ostane prava vrstica v DOM. Izbira, Ctrl+A, razvrščanje, število
v vrstici množičnih dejanj in izvoz CSV zato ohranijo preprost pomen »vse
naloženo«; vrstice se nikoli ne reciklirajo ali odstranijo. Brez JavaScripta
se nič ne spremeni – vrstica straničenja je navigacija.
7. Parametri, opcije in stanja
| Ključ | Tip | Pomen |
|---|---|---|
$opts['paging']['page'] | int | trenutna stran |
$opts['paging']['pageSize'] | int | vrstic na stran |
$opts['paging']['total'] | int | skupno število vrstic (za »stran X od Y«) |
$opts['paging']['pageUrl'] | callable | neobdelan URL za vsako stran (ločilo &); pot brez JS in vir URL-ja za sprotno nalaganje |
$opts['paging']['infinite'] | auto|off | sprotno nalaganje med drsenjem; privzeto auto |
Kombinacija z razvrščanjem in filtri (zavezujoče pravilo za
klicatelja): pri straničenju na strani strežnika morajo funkcije sortUrl
in filterHidden trenutno stran prenašati v ustvarjenem URL-ju oziroma v
skritih poljih – sicer sprememba razvrščanja ali filtra neopazno skoči na
1. stran.
8. Popolni primeri
$page = max(1, (int)($_GET['p'] ?? 1)); $rows = $db->queryAll('SELECT id, name FROM opravila ORDER BY id LIMIT 50 OFFSET ' . (($page - 1) * 50)); echo $widgets->dataGrid($columns, $rows, [ 'paging' => [ 'page' => $page, 'pageSize' => 50, 'total' => $skupaj, 'pageUrl' => static fn (int $p) => wl($ID, ['p' => $p]), ], ]);
9. Omejitve in robni primeri
- Brez navideznega drsenja (namerna, trajna omejitev, glejte odsek 3) – sprotno nalaganje ni virtualizacija, temveč dodajanje pravih vrstic.
- Sprotno nalaganje je vezano na
paging. Mreža brezpagingizriše vse podane vrstice in se pomika nativno; tam ni ničesar naložiti (tako deluje na primer mreža z rezultati na delovni površini SQL, ki vrstice dobi naenkrat). - Pogoj sta
IntersectionObserverinfetch; če eden manjka, ostane vrstica straničenja vidna in vse deluje kot prej. - Praktična zgornja meja za »še vedno tekoče« je odvisna od brskalnika in naprave in tu namenoma ni navedena kot stalno število (nepodprta trditev o zmogljivosti).
10. Dostopnost in združljivost
- Nativno drsenje je v celoti upravljivo s tipkovnico (Page Up/Page Down, puščice, ko je fokus v telesu mreže) brez dodatne kode.
- Brez zahtev za združljivost brskalnikov, ki bi presegale osnovno podporo CSS
overflow.
11. Odpravljanje težav
Simptom: mreža postane pri velikih naborih rezultatov opazno počasna.
Vzrok: vse vrstice se v celoti izrišejo v DOM – to je dokumentirana omejitev te stopnje, ne napaka.
Rešitev: nabor rezultatov zmanjšajte pred klicem (SQL LIMIT/
WHERE) ali vklopite straničenje na strani strežnika prek
$opts['paging'] (odsek 6).
12. Sorodne teme
- predstavitveni pregled – vse kategorije
- DataGrid: adaptivity – recept CSS, na katerem temelji drsenje
- DataGrid: filtering – zmanjšanje podatkov na strani strežnika (filtri)
- area:layout → mehanika postavitve – načelo »brez ponovne izvedbe izrisovalnika mreže v JS«