Delphi - Szerver oldali script alapjai

WebSnap 3. rész

forráskód letöltése
A WebSnap használatakor olyan html oldalakat készíthetünk, melyek scripteket tartalmaznak. Amikor egy kérés érkezik web szerverünkhöz, melynél a válaszban ezt a html oldalt kellene visszaadni, akkor a szerver oldalon a programunk értelmezi, feldolgozza ezt a scriptet és ennek eredményét adja vissza. Így web lapjaink tartalma dinamikusan állítható elő.
Nézzük milyen lépésekre volt szükség, hogy a mellékelt példa előálljon. Létrehozunk egy új WebSnap alkalmazást (Web App Debugger executable) a már ismert módon. CoClass name-nek a Step03-at válasszuk és a programunkat Project3 néven mentjük. Így amikor futtatjuk majdan a Web App debugger-t, akkor a Project3.Step03 alkalmazást kell aktivizálnunk.
A létrejött alkalmazásban rögtön felveszünk egy új WebSnap Page Module-t. Ez lesz a PageProducerPage3 és Unit3.pas, illetve Unit3.htm tartozik hozzá. Tegyünk most erre a modulra egy TAdapter komponenst és nézzük mire is jó. A TAdapter sok komponensnek az alapja, így érdemes megismerkedni vele.
Hozzunk benne létre egy új adat mezőt. Ehhez kattintsunk az Adapter1 komponens Data property-jére. A megnyíló ablakban a New Item gomb segítségével hozzunk létre egy új elemet, típusként az AdapterField-et válasszuk. Ekkor létrejön egy új objektum AdapterField1 névvel. Az Object Inspector-ban a DisplayLabel property-jét írjuk át a következőre: Dátum, idő.
Ezzel létrehoztunk egy új adatmezőt, melynek tetszőleges értéket adhatunk programból és ezt felhasználhatjuk web oldalainkon bárhol, bármikor.
Nézzük most azt, hogy miként tudunk értéket adni ennek az adatmezőnek. Ehhez válasszuk ismét az AdapterField1 objektumot az Object Inspector-ban, majd hozzuk létre hozzá az OnGetValue eseményt. Ez lesz az a pont programunkban, ahol ennek az adatmezőnek tetszőleges értéket adhatunk. Itt most mi az aktuális dátumot és időt adjuk értékül, melyet a paraméterként kapott Value változónak kell átadnunk. Amikor valamely web oldalon szükség lesz e mező értékére, akkor fut le ez az esemény, így bármikor használjuk ezt, mindig az aktuális dátumot is időt fogjuk viszontlátni.
procedure TPageProducerPage3.AdapterField1GetValue(Sender: TObject; var Value: Variant);
begin
  Value:=FormatDateTime('yyyy. mm. dd. hh:nn:ss', Now);
end;
Következő lépés, most e mezőnek felhasználása lesz. Ehhez váltsunk át a Unit3.pas-ról a Unit3.htm oldalra. Ehhez a Web Page Module-hoz a Unit3.htm állomány tartozik, így az ebben található kód jelenik meg majdan a böngészőnkben. Ide kell most egy olyan scriptet beírni, mellyel elérhetjük a programunkban lévő AdapterField1 objektumot, illetve annak értékét.
A html oldalra scriptet a <% és %> jelek közé írhatunk. Ha a <% jelek után egy egyenlőség jelet is írunk, akkor ez azt eredményezi, hogy script szövegének helyére annak kiértékelés utáni eredménye kerül.
Mivel e modulban található az Adapter1 komponens, így ezt elérni a scripten belül is a nevének leírásával lehet. E komponensnek van egy AdapterField1 objektuma, melynek van egy DisplayLabel property-je. Így az alábbi sor leírásával a web oldalunkra beszúrhatjuk az AdapterField1 objektum DisplayLabel property-jének aktuális értékét.
<b><%= Adapter1.AdapterField1.DisplayLabel %>:</b>
Hasonlóképpen érhetjük el az adatmezőnk értékét is. Ekkor az AdapterField1 objektum DisplayText property-jére kell hivatkoznunk. Ez lesz az a pillanat, mely a web oldal feldolgozásakor aktivizálja a programunkban lévő OnGetValue eseményt, mely eredményül az aktuális dátumot és időt szolgáltatja.
<%= Adapter1.AdapterField1.DisplayText %>
Készítsünk most egy következő oldalt, ahol már egy adattábla mezőjét használjuk fel az érték kiíratásánál, melyhez szintén egy html oldalon elhelyezett scriptet használunk.
Ehhez szükségünk van egy új Web Page Module-ra, mely mellékelt példában PageProducerPage4 névvel szerepel és a Unit4.pas illetve Unit4.htm tartozik hozzá.
Az adattábla eléréséhez szükségünk lesz néhány komponensre. Tegyünk fel tehát e modulra a BDE palettáról egy TSession komponenst, melynél az AutoSessionName property-t rögtön állítsuk igazra.
Tegyünk fel egy TTable komponenst is. Itt a DatabaseName property-nél válasszuk ki a DBDEMOS aliast, mivel egy olyan adattáblát fogunk használni, melyet a Delphi példákhoz adtak.
A TableName property-nél válasszuk ki a customer.db-t és állítsuk az Active property-t igazra. Szükség lesz még minden mezőhöz egy-egy objektumra, így kattintsunk duplán a Table1 komponensen, majd Ctrl + F. Ezzel hozzáadjuk a listához az összes mezőjét a táblának. Válasszuk most ki a CustNo objektumot és a ProviderFlags property-nél a pfInKey értékét szokás szerint állítsuk igazra.
Végül szükség lesz egy TDataSetAdapter komponensre a WebSnap palettáról. Itt a DataSet property-nél válasszuk ki Table1-et.
Ezzel meg is tettük a szükséges előkészületeket. Most már elérhetjük scriptben az adattábla egyes mezőit a DataSetAdapter1 komponensen keresztül. Ha megfigyeljük, a DataSetAdapter1 komponensnek is van Data property-je, épp úgy, mint az előző lapon használt TAdapter komponensnek. Itt viszont, ha nem veszünk fel egy adatmezőt sem, akkor alapértelmezésben az összes olyan mezőhöz automatikusan kapunk egy adatmezőt, mely a DataSet property-ben megadott Table1 komponensnél létezik. Ezek alapján írhatjuk a Unit4.htm oldalra a következő scriptet:
<b>Company:</b> <%= DataSetAdapter1.Company.DisplayText %><br>
Ezzel a Table1 aktuális rekordjából a Company mező értékét tudjuk megjeleníteni a web oldalunkon.
Ehhez hasonlóan érhetjük el a tábla többi mezőjét is.
<b>Addr1:</b> <%= DataSetAdapter1.Addr1.DisplayText %><br>
<b>City:</b> <%= DataSetAdapter1.City.DisplayText %><br>
Készítsünk most ismét egy új web oldalt, vagyis hozzunk létre még egy Web Page Module-t. Mellékelt példában ez lesz a PageProducerPage5, melyhez a Unit5.pas és Unit5.htm állományok tartoznak. Ezen az oldalon most az lesz a feladatunk, hogy ne csak a tábla aktuális rekordját jelenítsük meg, hanem írassuk ki az összes rekordot, úgy hogy ehhez is web oldali scriptet használunk.
A létrejött Page Module-ra most másoljuk át az előzőből a Session1, Table1 és DataSetAdapter1 komponenseket is. Bár lenne jobb megoldás is erre, mivel most ugyanazt a táblát használjuk, de az egyszerűség kedvéért most csak másoljuk. Az igazi megoldás majd a WebSnap Data Module használata lesz, amint ezt a későbbiekben még láthatjuk.
Másolás után már csak a scriptet kell megírnunk a Unit5.htm-be. Mivel itt most nem csak az aktuális rekordra lesz szükségünk, így el kell érnünk azt, hogy a scriptből is lehessen a következő rekordra lépni és ez egy ciklusban addig ismételjük, míg el nem jutunk a tábla végére.
Ehhez segítségünkre lesz egy Enumerator nevű objektum, melyet a script elején rögtön létre is hozunk. Létrehozáskor át kell adni az Enumerator számára, hogy mi az az adathalmaz, melyet kezelni szeretnénk. Ez nem lesz más, mint a DataSetAdapter1 komponens rekordjai, melyet a Records property-n keresztül érhetünk el.
  <% e = new Enumerator(DataSetAdapter1.Records) %>
Létrehozunk még egy belső változót is, melyben számlálni fogjuk, hogy hányadik rekordnál tartunk.
  <% i = 1 %>
Ezek után kezdeményezünk egy for ciklust, mely addig tart, amíg az Enumerator nem ért a rekordjaink végére. Ehhez az Enumerator osztály atEnd függvényét hívjuk meg, mely igaz értéket ad vissza, ha az aktuális rekordunk már az utolsó. A ciklus léptetésénél pedig magát az aktuális rekord pozíciót léptetjük a következőre. Ehhez az Enumerator osztály moveNext függvényét hívjuk.
  <% for (; !e.atEnd(); e.moveNext()) %>
  <% { %>
A ciklusmagban első lépésként kiírjuk a web lapra az i belső változónk értékét, mely számlálja a rekordokat.
    <b><%= i%>.:</b>
Ezt követően a már ismert módon megjelenítjük az adattáblából az aktuális rekord Company mezőjének értékét.
    <%= DataSetAdapter1.Company.DisplayText %>
Ezek után kiírjuk az AdapterField1 objektum értékét, melynek létrehozásáról még nem volt szó, de hamarosan erre is kitérünk.
    [<%= DataSetAdapter1.AdapterField1.DisplayText %>]
    <br>
Végül növeljük eggyel az i változónk értékét és zárjuk a ciklust.
     <% i = i + 1 %>
  <% } %>
Mivel a scriptben lévő ciklus végigmegy az összes rekordon, így a ciklusmagban lévő kód annyiszor fut le, ahány rekord aktuálisan van. Ennek pedig nyilvánvaló eredménye az lesz, hogy megjelenik a web lapon az összes Company mező értéke.
Térjünk most vissza a rejtélyes AdapterField1-re. TTable komponensnél ismerős lehet az ún. kalkulált mezők létrehozása. Ehhez hasonló történik most itt az AdapterField1-nél is.
Keressük elő a PageProducerPage5-ben lévő DataSetAdapter1 komponenst és kattintsunk a Data property-jére. Az ekkor megjelenő ablakban jobb gomb lenyomása után kapunk egy Add all fields menüpontot. Ezt kiválasztva kapunk minden mezőhöz egy-egy adat mező objektumot. Válasszuk most a New Item gombot és vegyünk fel egy új, AdapterField típusú mezőt, melynek a neve AdapterField1 lesz. Ennek a mezőnek most úgy adunk értéket az OnGetValue eseményen keresztül, hogy ott az adattábla LastInvoiceDate mezőjét használjuk fel és az ott tárolt dátumból csak az évszámot vesszük ki.
procedure TPageProducerPage5.AdapterField1GetValue(Sender: TObject; var Value: Variant);
var
  year, month, day: word;
begin
  DecodeDate(Table1LastInvoiceDate.Value, year, month, day);
  Value:=year;
end;
Az AdapterField1 értékének a kiírásáról az előbbi script-ben már gondoskodtunk. Az eredmény pedig az lesz, hogy a megjelenő web oldalon minden cégnév (Company) mező mellett egy évszám is látható lesz, melyet közvetve a LastInvoiceDate mezőből veszünk.
Ezzel a mellékelt példát be is fejeztük, jöhet az egyszeri futtatás, majd a szokásos módon a Web App Debugger és a teszt.

WebSnap paletta cikksorozat