E feladat automatizálásában segít a WebSnap paletta PageAdapter komponense, mellyel egy saját, tetszőleges formátumú listánkat jeleníthetjük meg web oldalunkon.
A mellékelt példában arra is láthatunk megoldást, hogy miként használhatunk web oldalainkon stílusokat (Cascading Style Sheets) az egyes objektumainkhoz.

A mellékelt példa futtatása előtt a Unit3.pas 54. sorában lévő DATFILE konstans értékét módosítania kell attól függően, hogy hova másolta a mellékelt a.dat állományt!
Mellékelt példában létrehoztunk egy a.dat szöveges állományt, melyben soronként egy-egy számot adtunk meg. A feladatunk az lenne, hogy web oldalunkon az a.dat állomány tartalmát jelenítsük meg, több oldalra tördelve, mivel egy oldalon nagyon hosszú lenne a lista.
A példa megoldását a következőképp hozhatjuk létre: nyissunk egy új WebSnap alkalmazást, abból is a Web App Debugger executable típust, melynél a CoClass név Step05. A projektet Project5 névvel mentsük.
Rögtön ezután hozzunk létre egy új web oldalt (Web Snap Page Module), amelyről töröljük a PageProducer komponenst, viszont tegyünk fel egy TPagedAdapter komponenst. Mellékelt példában ez a Unit3.pas-ban található. A PagedAdapter1 komponens PageSize property-jét rögtön állítsuk tízre. Ezzel azt érjük el, hogy a listánk elemei tízesével csoportosítva jelennek meg.
TPagedAdapter működését annak eseményein keresztül befolyásolhatjuk. Itt adhatjuk meg, hogy saját listánknak hány eleme van, valamint az események felhasználásával léptethetjük majd a listánkat.
A lista kezeléséhez létrehozunk egy belső változót, mely TStringList típusú és FList nevű. Ebbe a listába töltjük be az a.dat állományt és innen szolgáltatjuk majd az adatokat a web oldalra. Szükség lesz még egy olyan változóra is, mely jegyzi az aktuális elem sorszámát. Erre a változóra tekinthetünk úgy, mintha egy adattáblánál ez alapján határoznánk meg az aktuális rekord sorszámát. Ez a változó lesz az FIndex.
Amikor a web modul létrejön, akkor hozzuk létre az FList változót, illetve adunk kezdőértéket az FIndex-nek.
procedure TPageProducerPage3.WebPageModuleCreate(Sender: TObject);
begin
FList:=TStringList.Create;
FIndex:=0;
end;
Az FList-et meg is kell szüntetnünk, amikor már a web modul is megszűnik.
procedure TPageProducerPage3.WebPageModuleDestroy(Sender: TObject);
begin
FList.Free;
end;
Az a.dat állományt akkor töltjük be az FList-be, amikor a web modul aktívvá válik.
procedure TPageProducerPage3.WebPageModuleActivate(Sender: TObject);
begin
FList.LoadFromFile(DATFILE);
end;
Ezen előkészületek után nézzük miként működik a TPagedAdapter. Az első esemény, amit felhasználunk az OnGetEOF lesz. Ez akkor jön létre, amikor programunknak meg kell határoznia, hogy a lista végén állunk-e már, vagy még nem. Paraméterként kapunk egy EOF logikai változót. Ennek kell értéket adnunk oly módon, hogy ha a lista végén vagyunk, akkor igazat, különben hamisat adunk. Ezt most úgy tudjuk meghatározni, hogy az aktuális indexet ellenőrizzük, hogy az a lista végén van-e vagy még nincs.
procedure TPageProducerPage3.PagedAdapter1GetEOF(Sender: TObject; var EOF: Boolean);
begin
EOF:=FIndex>=FList.Count;
end;
Következő felhasználandó esemény az OnGetFirstRecord lesz. Ez akkor jön létre, amikor programunknak a listánk első elemére lesz szüksége. Ekkor nincs más teendőnk, mint az FIndex változónkat nullára állítani. Ez biztosítja, hogy amikor kiolvasás történik, akkor az az első lista elem legyen. Itt is találunk egy EOF változót, melynek most hasonlóan adhatunk értéket, mint az előbb.
procedure TPageProducerPage3.PagedAdapter1GetFirstRecord(Sender: TObject; var EOF: Boolean);
begin
FIndex:=0;
EOF:=0>=FList.Count;
end;
Az OnGetNextRecord eseményt akkor kapjuk, ha alkalmazásunk a következő lista elemre kíváncsi. Ekkor nincs más teendőnk, mint növelni az FIndex értékét és ismét meghatározni az EOF változó tartalmát.
procedure TPageProducerPage3.PagedAdapter1GetNextRecord(Sender: TObject; var EOF: Boolean);
begin
inc(FIndex);
EOF:=FIndex>=FList.Count;
end;
Van még két egyszerű esemény, melyet fel kell használnunk a komponens helyes működésének érdekében. Az egyik az OnGetRecordCount esemény, ahol azt kérdezi tőlünk a TPagedAdapter komponens, hogy hány eleme van a listánknak. Erre a Count nevű paraméterben válaszolhatunk.
procedure TPageProducerPage3.PagedAdapter1GetRecordCount(Sender: TObject; var Count: Integer);
begin
Count:=FList.Count;
end;
Másik eseményben pedig az aktuális sorszámot kell megadnunk, amit az OnGetRecordIndex esemény Index paraméterében tehetünk meg az FIndex változónk értékének átadásával.
procedure TPageProducerPage3.PagedAdapter1GetRecordIndex(Sender: TObject; var Index: Integer);
begin
Index:=FIndex;
end;
Ezzel a komponens már működőképes lenne, azonban a tényleges használathoz létre kell hoznunk adatmezőket, különben nem lesz mit megjeleníteni. Kattintsunk tehát a Data property-re és hozzunk létre két új adatmezőt AdapterField1 és AdapterField2 névvel. Az első DisplayLabel property-be írjuk be a "Sorszám" szöveget, míg a másodiknál az "Érték" szöveget. A megjelenítendő web lapon ugyanis két oszlopot szeretnénk létrehozni: az egyikben az aktuális lista elem sorszáma lenne, a másikban pedig az a.dat állományból vett érték.
Gondoskodnunk kell még e két adatmező értékadásáról is, ezért hozzunk létre mind a kettőhöz egy-egy OnGetValue eseményt.
Az elsőnél a sorszámra van szükség, tehát a Value paraméter az FIndex értékét kapja.
procedure TPageProducerPage3.AdapterField1GetValue(Sender: TObject; var Value: Variant);
begin
Value:=IntToStr(FIndex+1)+'.';
end;
A második esetben a lista aktuális elemét kell visszaadnunk, vagyis az FList változóból vesszük az FIndex-ben megadott elemet.
procedure TPageProducerPage3.AdapterField2GetValue(Sender: TObject; var Value: Variant);
begin
Value:=FList[FIndex];
end;
Mind a két esetben az FIndex változót csak felhasználnunk kell. Az FIndex értéke a PagedAdapter komponens eseményein keresztül fog változni, mindig úgy, ahogy az adott megjelenítéshez a komponensnek szüksége van.
Az adatokról tehát gondoskodtunk ezzel, most már csak a megjelenítéssel, vagyis a web oldalunk létrehozásával van dolgunk. Mivel az adatok most egy Adapter komponensből, a PagedAdapter1-ből származnak, így célszerű egy TAdapterPageProducer komponenst használni a web oldal előállítására a PagedAdapter1 adatai alapján. Tegyünk fel tehát egy TAdapterPageProducer komponenst a modulra, majd kattintsunk a WebPageItems property-re, vagy magára a komponensre duplán. A megjelenő ablakban kell összeállítanunk a web oldalunkat. Kattintsunk az ablak AdapterPageProducer1 elemére, majd a New Item gombra. A megjelenő ablakból válasszuk az AdapterForm-ot. Ekkor létrejön egy AdapterForm1 objektum. Most válasszuk ezt, majd ismét New Item és most hozzunk létre egy AdapterGrid-et. Az AdapterGrid1 objektum Adapter property-jénél kell összekötnünk a táblázatot az adatforrással, tehát itt válasszuk a PagedAdapter1 komponenst. Szintén az AdapterGrid1 objektum TableAttributes property-jének Border property-jét pedig állítsuk nullára. Ezzel eltüntetjük a táblázat keretezését.
Ezzel tulajdonképpen készen is lennénk: a lista első tíz eleme már megjelenne a web oldalon, viszont még nem tudunk lépkedni ezek között.
Válasszuk ismét az AdapterForm1 objektumot, majd a New Item gomb után válasszuk az AdapterCommandGroup elemet. Ekkor létrejön egy AdapterCommandGroup1 objektum. Ennek van három alapértelmezett funkciója: ugrás az előző listára, ugrás az egyes csoportokra és ugrás a következőre. Ahhoz, hogy e három funkció működhessen, be kell állítanunk az AdapterCommandGroup1 objektum DisplayComponent property-jét. Itt adjuk tudtára e három funkciónak, hogy melyik megjelenített listát kell kezelnie. Ha ezt megtettük, akkor máris megjelenik egy PrevPage 1 NextPage link.
Feltéve, hogy e három felirat nem felel meg igényeinknek, nézzük gyorsan miként tudjuk magyarosítani őket. Kattintsunk jobb gombbal az AdapterCommandGroup1 objektumon, majd válasszuk az Add All Commands menüpontot. Ekkor létrejön három újabb objektum, CmdPrevPage1, CmdGotoPage1 és CmdNextPage1 névvel. E három objektum a három linknek felel meg. Most már könnyedén átírhatjuk a megjelenő szövegeket a Caption property-ben.
További lehetőség, hogy link helyett nyomógombot jelenítsünk meg. Ehhez csak annyit kell tennünk, hogy a DisplayType property-ben a ctButton értéket választjuk ki. Ha a HideOptions property bhoHideOnDisabledAction értékét is igazra állítjuk, akkor ezzel azt érjük el, hogy ha az adott funkció letiltásra kerül, akkor nem jelenik meg a link, illetve a nyomógombunk sem. Ilyen eset például akkor következik be, ha a lista elején állunk, mivel ekkor az "előző" funkciónak nem is lenne sok értelme, így felesleges is megjeleníteni a web oldalon.
Az előző, következő linkekkel és e kettő között álló számokkal semmi dolgunk, ezt automatikusan kódolja és dolgozza fel a WebSnap, így nem is kell foglalkoznunk azzal, hogy milyen linkek kerülnek előállításra a web oldalon.
Ha a táblázatban megjelenő két oszlopban lévő adatokat is szeretnénk személyre szabni, akkor hasonlóan kell eljárnunk, mint az előbb. Jelöljük most ki az AdapterGrid1-et, majd jobb gomb után válasszuk az Add All Columns menüpontot. Ekkor kapunk két új objektumot a két oszlopunkhoz, ahol azok tulajdonságait befolyásolhatjuk.
Az eredmény web oldalon történő megjelenítéséhez ne felejtsük el beszúrni a Unit3.htm-be a <#serverscript> címkét.
Ezzel a kitűzött feladatot megvalósítottuk, de a próba előtt még nézzük meg, hogy miként használhatunk stílusokat is a web oldalunkon, hogy az ott található elemeket egyszerűbben formázhassuk. Az AdapterPageProducer1 komponens Styles property-jébe felvehetünk tetszőleges számú stílus definíciót. Az itt megadott szöveg tulajdonképpen egy egyszerű másolással bekerül a Unit3.htm oldalra, méghozzá oda, ahová a <#styles> címkét helyezzük. Ezt célszerű a HTML kód HEAD részében elhelyezni.
Ezzel a stílusok a weblapra kerülnek, de nézzük, miként használhatjuk fel azokat. Válasszuk az AdapterPageProducer1 komponenst, dupla kattintás, keressük elő az AdapterCommandGroup1 objektumot, majd jelöljük ki a CmdGotoPage objektumot. Az Object Inspector-ban a StyleRule property-t legördítve választhatunk egy stílust ehhez a szöveghez a megadott stílusaink közül.