Mostani részben szeretném megismertetni az olvasókat az első olyan megjelenítési formával, ahol az XML adatok egy HTML oldal segítségével kerülnek megjelenítésre. Ezen megoldás egy DSO (Data Source Object) objektumot használ, mely segítségével az XML adatok a HTML oldalba vannak illesztve és ezen belül HTML elemekhez vannak kötve. Innen is ered az adatkötés technika megnevezés. A cikksorozat ezen része egy kicsit eltér az eddig megszokottaktól, mivel röviden szeretnék egy másik a Microsoft által kifejlesztett külső adattárolási technológiát is bemutatni, a TDC-t.
Adatkötéses technikák keletkezése és értleme
Napjainkban egyre nagyobb az internetes oldalak adatigénye, ami az oldal és egyben adat frissítéseket nagyban megnehezíti. A web oldalak túlnyomó része adatbázisból dolgozik, vagyis a gyakran változó adatok egy szerveren lévő adatbázisban vannak tárolva. A megoldás lényege és egyben legnagyobb előnye a nagyon gyors adatfrissítés lehetősége. A szerver oldali adatbázis hátránya, hogy nagyban igénybe veszi a szerver erőforrásait, mivel minden egyes kliens oldal felől érkező kérés esetén az egész oldal újra előállításra kerül az adatok alapján.
Rögtön vegyünk egy példát az érthetőség kedvéért! Tételezzük fel, hogy van egy adatbázisból dolgozó oldalunk, amely tartalmazza az eddigi forma1-es világbajnokok listáját. A lista tartalmazza az évet, a pilóta nevét és nemzetiségét. A felhasználóknak lehetőségük van a listát név, évszám és nemzetiség szerint rendezni, illetve egy bizonyos nemzetiségű világbajnokokat kiiratni. Amikor az egyes csoportosítási funkciók közül válogatnak, a szerver mindig ugyanazon lista ugyanazon elemeit, részelemeit küldi el nekünk. Ez egy csomó felesleges "munka" a szervernek, főleg ha belegondolunk abba, hogy egyidejűleg több tíz, vagy akár ezer ember is kíváncsi ugyanezen adatokra.
Mindenkiben felmerül a kérdés: Vajon hogyan lehetne megoldani ezt az elég fontosnak tűnő problémát? Ezen probléma (részleges) megoldására fejlesztettek ki egy elegáns technológiát, az úgynevezett adatkötéses technológiát. Ez a technológia lehetővé teszi az adatok helyi tárolását a HTML kódtól elkülönítve. Az úgynevezett adatforrás objektumok (Data Source Object) segítségével a web oldalunk a külső adatok számára egyfajta megjelenítő sablonként fog működni. Eme technológia egyik legnagyobb előnye a szerver terhelésének csökkentése az adatok aktualizálásánál, illetve az adatokkal való munka során.
Akkor most lássunk, hogy is működik ez a valóságban: A felhasználó elküldi a kérését a szerver felé egy HTML űrlap segítségével. A szerveren lévő (szerveroldali) szkript (PHP, ASP, CGI, ISAPI) a felhasználói kérés alapján az adatbázisból kigenerálja a kívánt adatokat és elküldi a felhasználónak (pl. XML formájában). Az összes többi műveletet ezen adatokkal a kliens oldal végzi a DSO objektumokon keresztül. SKicsit visszakanyarodva a példánkhoz: A felhasználó tehát szeretné megtekinteni a forma1 történetének összes vilagbajnokát. Elküldi a szervernek a kérést, a szerver előállítja a megjelenítési sémát, vagyis a HTML forrást és külön a puszta adatokat. A kliens oldal értelmezi a kapott adatokat és a DSO-n keresztül kitölti a HTML oldalt. Ha rendezni, illetve válogatni akarunk az adatok között, akkor az csakis a kliens oldalon történik a DSO-n keresztül.
A DSO használatának hátrányai közé tartozik, hogy rögtön az elején le kell tölteni a kliens oldalra az összes adatot (igaz, ez a probéma kiküszöbölhető az aszinkron adat feldolgozás használatával), az adatoknak szimmetrikusaknak kell lenni és a DSO-nak a gépünkön kell lenni.
DSO hatáskörébe tartoznak:
- hogyan lesznek az adatok továbbítva szerver-től kliens-ig (pl. HTTP protokoll segítségével)
- milyen műveleteket tudunk végezni az adatokkal (pl. rendezés, válogatás, frissítés)
- hogyan vannak az adatok tárolva (pl. szöveges fájl)
- milyen lesz az objektum modell (DOM) az adatok hozzáférésénél
Az IE-ben található DSO objektumok:
- Remote Data Service - lehetőséget ad az adatokkal való műveletek végzésére és aktualizálására bármilyen OLE DB kompatibilis szolgáltatóval
- applet JDBC - Netscape Navigator-ban is támogatott DSO, de a hozzáférés csak szkriptek segítségével lehetséges
- Tabular Data Control - szöveges fájl az adatforrás, nem lehet adatokat frissíteni a szerveren
- XMLDSO - XML adatokat értelemző DSO
Az összekötő ágens irányitja és szinkronizálja az adatfolyamot a DSO és adatbefogadók között.

Tehát vegyük szépen át az egész folyamatot az elejétől: Első lépésként kell nekünk egy HTML oldal, amelybe beillesztjük a külső adatokat. Az adatok beillesztése történhet közvetett(az adatok egy külső fájlban vannak) vagy közvetlen(az adatok egyenesen a HTML kódba vannak implementálva [ez csak XMLnél használható TDCnél nem]) módon.
Miután a külső adatokat sikeresen hozzákapcsoltuk a dokumentumunkhoz (HTML), a böngésző létrehozza a DSO objektumot, amely automatikusan értelmezi a külső adatokat és hozzáférhetővé teszi azokat (úgynevezett rekordokat hoz létre). Ezek után, ha egy HTML elem tartalmaz adatkötést akkor a DSO objektum automatikusan betölti oda az adatot (vagy adatokat, attól függően, hogy milyen elemről van szó).
Adatok beillesztése a HTML dokumentumba
Az adatok beillesztése a HTML dokumentumba az úgynevezett adatsziget segítségével történik. XML esetében ez nem más mint az <XML></XML>
TAG. Ezen TAG két jellemzőt támogat:
- ID - amely azonosítja az adatszigetet
- SRC - hivatkozik a külső fáljra, amelyben vannak a tényleges XML adatok
<XML>
TAG-on beülre. Ezen megoldás használata nem igazán ajánlott. Az általános és javallott megoldás a közvettet adatmegadás, melynél csak hivatkozunk a külső fáljban tárolt XML adatokra, méghozzá úgy, hogy a SRC
jellemző értékéül megadjuk a fájl elérési útvonalát.
<HTML>
<HEAD><TITLE>Adatsziget</TITLE></HEAD>
<BODY>
<!-- közvetlen adatmegadás -->
<XML ID="közvetlenDSO1">
<?xml version="1.0" encoding="ISO-8859-2"?>
<F1VILAGBAJNOKOK>
<F1VILAGBAJNOK>
<EV>1954</EV>
<NEV>Juan Fangio</NEV>
<NEMZETISEG>Argentin</NEMZETISEG>
</F1VILAGBAJNOK>
<F1VILAGBAJNOK>
<EV>1955</EV>
<NEV>Juan Fangio</NEV>
<NEMZETISEG>Argentin</NEMZETISEG>
</F1VILAGBAJNOK>
<!-- ... -->
</F1VILAGBAJNOKOK>
</XML>
<!-- közvetett adatmegadás -->
<XML ID="közvetettDSO2" SRC="f1_vilagbajnokok.xml"></XML>
</BODY>
</HTML>
ID
jellemző értékéül kell megadnunk, és amelynek egyedinek kell lenni.
Adatbefogadók
Adatbefogadó komponenseknek nevezzük azon elemeket, amelyek a DSO által szolgáltatott adatokat megjelenítik. Ezek lehetnek az általános HTML komponensek (pl. SPAN, DIV, TABLE
) vagy az ActiveX, illetve Java Applet külső objektumai. Az adatbefogadók kiválasztása nagyban függ a megjeleníteni kívánt adatok struktúrájától (DIV,SPAN
- csak egyetlen adat megjelenítésére képes, ellenben a TABLE
elemmel, amely egy adatforrás több elemét is képes megjeleníteni ).
Mit is jelent ez pontosan? Amennyiben egy olyan elemhez rendelünk hozzá adatot, amely több rekordot is képes megjeleníteni (pl. TABLE
), akkor a DSO megjeleníti az összes rekordot, úgy, hogy sokszorozza pl. egy táblázat esetén a sorokat. Egy egyrekord megjelenítésére alkalmas elem esetén (pl. SPAN
) csak az első rekord kerül megjelenítésre.
Az IE tartalmaz néhány HTML-elem tulajdonságot a DSO által szolgáltatott adatok befogadására:
- DATASRC tulajdonság azonosítja a DSO objektumot (a DSO objektum ID-jét tartalmazza)
- DATAFLD tulajdonság azonosítja a DSO adatainak egyik oszlopát
- DATAFORMATAS tulajdonsággal adhatjuk meg, hogy az elem tartalma szöveg vagy esetleg HTML kód
- DATAPAGESIZE tulajdonság adja meg az elemek számát egy oldalon (csakis többrekord megjelenítésére alkalmas elemeknél használható)
Elem | Értlemezi a HTML jelöléseket | Frissíti az XML mező tartalmát |
---|---|---|
A | Nem | Nem |
DIV | Igen | Nem |
FRAME | Nem | Nem |
IMG | Nem | Nem |
INPUT TYPE=button | Igen | Nem |
INPUT TYPE=checkbox | Nem | Igen |
INPUT TYPE=password | Nem | Igen |
INPUT TYPE=radio | Nem | Igen |
INPUT TYPE=text | Nem | Igen |
SELECT | Nem | Igen |
SPAN | Igen | Nem |
TEXTAREA | Nem | Igen |
Miről is van szó? A fenti táblázatban a DSO által szolgáltatott adatok megjelenítését támogató elemek két lényeges tulajdonságát tüntettük fel, mégpedig azt, hogy amennyiben HTML elemeket használunk az XML mező szöveges tartalmaként, úgy azt képes e az adatbefogadó értelmezni, illetve amennyiben megváltoztatjuk az adatbefogadó tartalmát, úgy az eredeti XML tartalom is frissül e. Ezeket rögtön be is mutatjuk egy példán, de mindezek előtt tanuljuk meg az DSO rekordjait HTML elemekhez kapcsolni.
<HTML>
<HEAD>
<TITLE>Egyszerű DSO</TITLE>
<XML ID="oDSO" SRC="f1_vilagbajnokok.xml"></XML>
</HEAD>
<BODY>
<B>Év</B>: <SPAN DATASRC="#oDSO" DATAFLD="EV"></SPAN><BR>
<B>Név</B>: <SPAN DATASRC="#oDSO" DATAFLD="NEV"></SPAN><BR>
<B>Nemzetiség</B>: <SPAN DATASRC="#oDSO" DATAFLD="NEMZETISEG"></SPAN><BR>
</BODY>
</HTML>
SPAN
elemeket használtunk fel, melyeknek megadtuk a forrást, vagyis a DSO objektum ID
-jét, valamint a megjeleníteni kívánt mező vagy rekord nevét a DATAFLD
jellemző értékeként. Ezen megoldástól egy lépcsőfokkal nehezebb a rekordhalmaz megjelenítése. Ezen cél eléréséhez a TABLE
elemet hívjuk segítségül.
<HTML>
<HEAD>
<TITLE>Rekordhalmaz megjelenítése</TITLE>
<XML ID="oDSO" SRC="f1_vilagbajnokok.xml"></XML>
</HEAD>
<BODY>
<input type="button" value="<< első oldal" onClick="table.firstPage()">
<input type="button" value="< előző oldal" onClick="table.previousPage()">
<input type="button" value="következő oldal >" onClick="table.nextPage()">
<input type="button" value="utolsó oldal >>" onClick="table.lastPage()">
<TABLE DATASRC="#oDSO" DATAPAGESIZE="10">
<THEAD>
<TR>
<TD width="70"><B>Évszám</B></TD>
<TD width="150"><B>Versenyző neve</B></TD>
<TD><B>Nemzetiség</B></TD>
</TR>
</THEAD>
<TR>
<TD bgcolor="silver"><SPAN DATAFLD="EV"></SPAN></TD>
<TD bgcolor="gray"><SPAN DATAFLD="NEV"></SPAN></TD>
<TD bgcolor="silver"><SPAN DATAFLD="NEMZETISEG"></SPAN></TD>
</TR>
</TABLE>
</BODY>
</HTML>
TABLE
elem nyitó részében megadtuk a DSO objektum forrását, ezen kívül meghatároztuk, hogy maximum 10 elem jelenjen meg egyszerre (DATAPAGESIZE="10"
). Ezek után viszont egy érdekes problémába ütközünk: Hogyan rendeljük hozzá az egyes mezőket a táblázat egyes oszlopaihoz, mivel az gondolom mindenkinek feltűnt, hogy az adatbefogadó elemek listájában nem szerepel a TD
elem. Ezért van szükség a SPAN
elem használatára, mely csak annyiban tér el az egy rekord megjelenítésénél használt megoldástól, hogy nem kell megadni az adatforrás objektumot.
Amennyiben elhagyjuk a TABLE
elem nyitórészéből a DATAPAGESIZE
jellemzőt, úgy az összes rekord megjelenítésre kerül. Viszont, ha bekorlátozzuk a megjeleníteni kívánt rekordok számát, kihasználhatunk egyet a DSO nyújtotta lehetőségek közül, a lapozást. Ehhez nem kell mást tennünk, mint ID
-t adni a táblázatnak (melyel majd a későbbiekben hivatkozni tudunk rá) és valamilyen esemény bekövetkezésekor hivogatni az adatbefogadó táblázat következő metódusait:
Metódus | Leírás |
---|---|
firstPage() | az első rekordlapot jeleníti meg |
previousPage() | az előző rekordlapot jeleníti meg |
nextPage() | a következő rekordlapot jeleníti meg |
lastPage() | az utolsó rekordlapot jeleníti meg |
Ahogy az a pédlaprogramból is látszik, mi egy gomb
onClick
eseményéhez (ez az esemény akkor következik be, amikor a felhasználó a bal egérgombbal ráklikkel a gombra) rendeltük hozzá a metódusokat (onClick="table.firstPage()"
).
Ezidáig egyetlen adatkötéshez használható jellemzőt nem mutattunk be, ez pedig a DATAFORMATAS
jellemző. Jellemző alapértéke TEXT
, amely mint szöveg értelmezi és jeleníti meg az XML elemek tartalmát. Viszont amennyiben mi HTML
értéket adunk meg a DATAFORMATAS
jellemzőnek, úgy az XML mező tartalmát HTML-ként értelmezi.
<HTML>
<HEAD>
<XML ID="oDSO">
<?xml version="1.0" encoding="ISO-8859-2"?>
<GYOKER>
<![CDATA[
Ez egy <a href="#">hiperhivatkozás</a> <b>akarna</b> lenni!
]]>
</GYOKER>
</XML>
</HEAD>
<BODY>
Sima szöveg: <SPAN DATASRC="#oDSO2" DATAFLD="$TEXT"></SPAN><BR>
HTML: <SPAN DATASRC="#oDSO2" DATAFLD="$TEXT" DATAFORMATAS="HTML"></SPAN>
</BODY>
</HTML>
$TEXT
változó, mely a DSO egy speciális változója és az éppen aktuális elem (csakis) karakteres adatait tartalmazza. Mivel nekünk az aktuális elemünk maga a gyökérelem (GYOKER
), melyet nem adhatunk meg a DATAFLD
jellemzőnek, ezért használjuk a $TEXT
változót, amely segítségével elérhettük az adatainkat.
Rekordokhoz való hozzáférés
Mint azt már említettük a DSO objektum rögtön rekordokba rendezi a betöltött adatokat, melyekhez különböző jellemzők és metódusok segítségével biztosít hozzáférést.
Metódus vagy jellemző | Leírás |
---|---|
moveFirst() | a rekordhalmaz első elemére állítja az elemmutatót |
movePrevious() | az előző elemre állítja az elemmutatót |
moveNext() | a következő elemre állítja az elemmutatót |
moveLast() | a rekordhalmaz utolsó elemére állítja az elemmutatót |
move(Int i) | a paraméterként megadott számot hozzáadja az elemmutatóhoz |
String fields(String field) | az aktuális elem paraméterként átadott mezőjének értékét adja vissza |
addNew() | új elemet ad a rekordhalmazhoz és ráviszi az elemmutatót |
delete() | törli az aktuális rekordot |
cancelUpdate() | visszavonja az aktuális elemen végrehajtott összes módosítást |
Bool EOF | jellemző értéke TRUE ha az utolsó utáni elemen van az elemmutató, ellenkező esetben értéke FALSE |
Bool BOF | jellemző értéke TRUE ha az első előtti elemen van az elemmutató, ellenkező esetben értéke FALSE |
Int RecordCount | az elemhalmaz hosszát tartalmazza |
Int AbsolutePosition | az aktuális rekord sorszámát tartalmazza |
A fentebb táblázatba foglalt összes metódus, függvény és jellemző a DSO objektum recordset objektumának függvénye, metódusa vagy jellemzője, ami gyakorlatban annyit tesz, hogy a metódushívások a következő képpen néznek ki: oDSO.recordset.moveFirst()
, ahol oDSO a DSO objektum ID
-je.
Mielőtt még elkezdenénk örülni az addNew()
és egyéb metódusok láttán, melyek segítségével a DSO adatai változtathatóak lennének, szögezzük le, hogy a DSO objektum a szerveren levő adatok másolataival dolgozik, nem pedig a valósakkal. Ezen függvények, metódusok, jellemzők és valamilyen kliens oldali szkriptnyelv segítségével számos fontos funkció megvalósítható, mint például a keresés, melyet hamarosan be is mutatunk, de előtte egy egyszerű kis példa az érthetőség kedvéért:
<HTML>
<HEAD>
<TITLE>Egyszerű DSO</TITLE>
<XML ID="oDSO" SRC="f1_vilagbajnokok.xml"></XML>
</HEAD>
<BODY>
<B>Év</B>: <SPAN DATASRC="#oDSO" DATAFLD="EV"></SPAN><BR>
<B>Név</B>: <SPAN DATASRC="#oDSO" DATAFLD="NEV"></SPAN><BR>
<B>Nemzetiség</B>: <SPAN DATASRC="#oDSO" DATAFLD="NEMZETISEG"></SPAN><BR>
<input type="button" value="<< első rekord" onClick="oDSO.recordset.moveFirst()">
<input type="button" value="< előző rekord" onClick="if(!oDSO.recordset.BOF)oDSO.recordset.movePrevious()">
<!-- az előző elem hívása előtt ellenőrizni kell, hogy az aktuális elem nem e az első elem -->
<input type="button" value="ugrás" onClick="i=window.prompt('Add meg az számot', '1');if(!isNaN(i))oDSO.recordset.move(Number(i))">
<!-- beolvasunk a felhasználótól egy karakterláncot, ellenőrizzük, hogy szám-e, és ha igen beállítjuk az elemmutatót -->
<input type="button" value="következő rekord >" onClick="if(!oDSO.recordset.EOF)oDSO.recordset.moveNext()">
<!-- ugyanaz a helyzet mint, az előző elemnél csak itt az utolsót kell tesztelni -->
<input type="button" value="utolsó rekord >>" onClick="oDSO.recordset.moveLast()">
</BODY>
</HTML>
Következőkben egy kicsit összetettebb példán szeretném bemutatni, hogy a DSO és kis kliens oldali szkript ötvözése mennyi lehetőséget rejt magában. A példaprogramban ismételten a forma 1 világbajnokait tartalmazó XML fájlunkat használjuk fel, melyet beépítünk az oldalba, majd kliens oldali JavaScript segítségével keresést teszünk lehetővé a felhasználó számára. A keresés történhet név, évszám és nemzetiség alapján egyaránt. Azon rekordmezőket, amelyekben megtaláltuk a keresett kifejezést, a már megszokott táblázatos formában fogjuk megjeleníteni, persze programból dinamikusan előállítva.
rekordhozzaferes_osszetett.htm
<HTML>
<HEAD>
<TITLE>Összetett rekordhozzáférés DSO</TITLE>
<XML ID="oDSO" SRC="f1_vilagbajnokok.xml"></XML>
<SCRIPT TYPE="text/javascript" LANGUAGE="JavaScript">
<!--
function create_row(ev, nev, nemzetiseg) //a táblázat egy sorát hozza létre
{
var row = document.createElement("TR"), //sor elem létrehozása
ev_cell = document.createElement("TD"), //sor celláinak létrehozása
nev_cell = document.createElement("TD"),
nemzetiseg_cell = document.createElement("TD");
ev_cell.innerText = ev; //az egyes cellák szöveges tartalmának beállítása a paraméterek alapján
nev_cell.innerText = nev;
nemzetiseg_cell.innerText = nemzetiseg;
row.appendChild(ev_cell); //az egyes cellákat hozzárendeljük a sorhoz
row.appendChild(nev_cell);
row.appendChild(nemzetiseg_cell);
return row; //a fügvény visszatérési értéke maga a sor objektum
}
function delete_all_rows(tbody) //mielőtt az új keresési eredményeket kilistáznánk töröljük a régi sorokat a táblázatból
{
while(tbody.rows.length > 0) //a ciklus addig ismétlődik, amíg a táblázat tartalmaz sorokat
tbody.deleteRow(0);
}
function find_str() //ezen függvény végzi a keresést és az eredménykiiratást is
{
var str = document.getElementById("search_str").value.toLowerCase(),
//"befogjuk" a text mezőt, ahova a keresendő szót írtuk, kiolvassuk a tartalmát (a szöveget)
//és átalakítjuk csupa kisbetűre, ezzel elkerülve a keresés kis-nagybetű érzékenységét
rsearchfor = document.getElementsByName("rsearchfor"), //a három radio-button objektumot tartalmazza
searchfor = (rsearchfor[0].checked ? "nev" : (rsearchfor[1].checked ? "ev" : "nemzetiseg")),
//attól függően, hogy melyik radio gomb van bejelölve a searchfor változónak az értéke lehet: "nev", "ev", "nemzetiseg"
//későbbiekben ez fogja meghatározni, hogy a rekordhalmaz melyik mezőjében fogunk keresni
tbody = document.getElementById("list_tab"),
//a lista táblázatot test részére; ide hozzuk létre a sorokat
found = false;
delete_all_rows(tbody); //töröljük az összes létező sorát a táblázatnak
oDSO.recordset.moveFirst(); //az első elemre állítjuk az elemmutatót
while(!oDSO.recordset.EOF) //a ciklus végigmegy a rekordhalmaz összes elemén
{
if(oDSO.recordset(searchfor).value.toLowerCase().indexOf(str) !=-1) //minden rekord searchfor változóban tárolt nevű mezőjét
{ //átalakítja kisbetűsre és megvizsgálja, hogy megtalálható e benne a keresett szöveg
// a find() függvény a sztring pozícióját adja meg, ahol megtalálta, vagy -1-et ha nem találta meg
tbody.appendChild( create_row(oDSO.recordset("ev").value, oDSO.recordset("nev").value, oDSO.recordset("nemzetiseg").value) );
// a táblázathoz hozzácsatoljuk az új sort, amelyet a create_row() öggvényünk hoz létre a rekord elemek alapján
found = true; //van találat
}
oDSO.recordset.moveNext(); // az elemmutatót a kövtkező elemre állítja
}
if(!found) //amennyiben nem volt találat egy üzenetet küldünk a felhasználónak
alert("Nincs találat!");
}
// -->
</SCRIPT>
</HEAD>
<BODY>
<TABLE>
<TR>
<TD VALIGN="top">
<INPUT TYPE="text" ID="search_str" STYLE="width:200px;">
<INPUT TYPE="button" VALUE="Keress" ONCLICK="find_str()">
</TD>
</TR>
<TR>
<TD>
<INPUT TYPE="radio" NAME="rsearchfor" CHECKED> Név
<INPUT TYPE="radio" NAME="rsearchfor"> Év
<INPUT TYPE="radio" NAME="rsearchfor"> Nemzetiség
</TD>
</TR>
</TABLE>
<BR><HR><BR>
<DIV STYLE="overflow-y:auto; overflow-x:hidden; width:450px; height:500px;">
<TABLE WIDTH="420">
<THEAD>
<TR>
<TD WIDTH="70"><B>Évszám</B></TD>
<TD WIDTH="200"><B>Versenyző neve</B></TD>
<TD WIDTH="150"><B>Nemzetiség</B></TD>
</TR>
</THEAD>
<TBODY ID="list_tab">
<!-- ide lesznek létrehozva a táblázat egyes sorai a találatok alapján -->
</TBODY>
</TABLE>
</DIV>
</BODY>
</HTML>
Tabular Data Control objektum
Ahogy azt a cikk elején ígértem megismerkedünk egy kicsit közelebről a Tabular Data Controllal vagy közismertebb nevén a TDC-vel. A TDC egy Microsoft által fejlesztett adattárolási technológia, mely a felhasználó gépén ActiveX komponens formájában van jelen és az adatokat szöveges fájl formájában tárolja. Az adatok az úgynevezett elválasztókkal vannak oszlopokra bontva. Az adatbázis egyes rekordjai új sorokba kerülnek (új sor és kocsi vissza karakterekkel vannak elválatszva), amelyet nem lehet külsőleg változtatni.
Nézzük meg rögtön, hogyan is nézne ki a forma1 világbajnokait tartalmazó adatbázisunk TDC-ben:
ev|nev|nemzetiseg
!1954!|!Juan Fangio!|!Argentin!
!1955!|!Juan Fangio!|!Argentin!
!1956!|!Juan Fangio!|!Argentin!
!1963!|!Jim Clark!|!Brit!
|!a|b != a&b!|
érvényes adata a|b != a&b
.
Mivel a TDC nyújtotta lehetőségek elég szűkösek és cikkünk tárgya sem a TDC bemutatása, ezért egyetlen a maximumhoz közeli példán szeretném bemutatni a működését. A példa tartalmaz rendezést, válogatást, elem hozzáadást és elem törlést (melyeket igaz, nem lehet menteni). Nos akkor a példa forrása:
<HTML>
<HEAD>
<TITLE>TDC DSO</TITLE>
<OBJECT ID="oDSO" CLASSID="CLSID:333C7BC4-460F-11D0-BC04-0080C7055A83" onDataSetComplete="disp();">
<PARAM NAME="CharSet" VALUE="windows-1250">
<PARAM NAME="TextQualifier" VALUE="!">
<PARAM NAME="FieldDelim" VALUE="|">
<PARAM NAME="DataURL" VALUE="f1vilagbajnokok.txt">
<PARAM NAME="UseHeader" VALUE="true">
</OBJECT>
</HEAD>
<BODY>
<input type="text" readonly id="disp" size="5"><br>
<input type="button" value="<" onclick="elozo_record()">
<input type="button" value="Mutat" onClick="record_mutat()">
<input type="button" value="Töröl" onClick="record_torol()">
<input type="button" value=">" onclick="kovetkezo_record()"><br>
<input type="button" value="Új hozzáadása" onclick="uj_record()"><br>
<B>Rendezd
<SELECT onchange="oDSO.Sort=('+'+this.value); oDSO.Reset();disp()" >
<OPTION VALUE="">Rendezetlen</OPTION>
<OPTION VALUE="nev">név</OPTION>
<OPTION VALUE="ev">év</OPTION>
<OPTION VALUE="nemzetiseg">nemzetiség</OPTION>
</SELECT> szerint es mutasd a(z)
<SELECT onchange="oDSO.Filter=('nemzetiseg='+this.value); oDSO.Reset();disp()" >
<OPTION VALUE="">összes</OPTION>
<OPTION VALUE="Amerika">amerikai</OPTION>
<OPTION VALUE="Ausztral">ausztrál</OPTION>
<OPTION VALUE="Argentin">argentin</OPTION>
<OPTION VALUE="Brit">brit</OPTION>
<OPTION VALUE="Finn">finn</OPTION>
<OPTION VALUE="Francia">francia</OPTION>
<OPTION VALUE="Kanada">kanada</OPTION>
<OPTION VALUE="Olasz">olasz</OPTION>
<OPTION VALUE="Nemet">német</OPTION>
<OPTION VALUE="Uj zeland">új zéland</OPTION>
<OPTION VALUE="Osztrak">osztrák</OPTION>
</SELECT>
nemzetiségűeket</b>
<P>
<TABLE DATASRC="#oDSO">
<THEAD>
<TR>
<TD width="70"><B>Évszám</B></TD>
<TD width="150"><B>Versenyző neve</B></TD>
<TD><B>Nemzetiség</B></TD>
</TR>
</THEAD>
<TR>
<TD bgcolor="silver"><SPAN DATAFLD="ev"></SPAN></TD>
<TD bgcolor="gray"><SPAN DATAFLD="nev"></SPAN></TD>
<TD bgcolor="silver"><SPAN DATAFLD="nemzetiseg"></SPAN></TD>
</TR>
</TABLE>
<SCRIPT TYPE="text/javascript" LANGUAGE="JavaScript">
<!--
function elozo_record() //a rekordhalmaz elemmutatóját állítja az előző elemre
{ //ha a mutató az 1. elemre mutat akkor az utolsóra állítja a mutatót
if(oDSO.recordset.AbsolutePosition==1)oDSO.recordset.MoveLast();
else oDSO.recordset.MovePrevious(); //ellenkező esetben az előző elemre állítja az elemmutatót
disp(); //mivel változott az elemmutató pozíciója frissíteni kell a kijelző tartalmát
}
function kovetkezo_record() //a rekordhalmaz elemmutatóját állítja a következő elemre, tehát az elozo_rekord() ellenkezőjét csinálja
{
if( oDSO.recordset.AbsolutePosition == oDSO.recordset.RecordCount )oDSO.recordset.MoveFirst();
else oDSO.recordset.MoveNext();
disp();
}
function record_mutat() //egy JavaScriptes üzenőablakban megmutatja az aktuális rekord tartalmát
{
alert("Év: "+oDSO.recordset.fields('ev')+"\nNév: "+oDSO.recordset.fields('nev')+"\nNemzetiség: "
+oDSO.recordset.fields('nemzetiseg'));
}
function disp() //a disp IDvel rendelkező input type="text" mező értékéhez rendeli hozzá az adatbázis aktuális
{ //hosszát és az elemmutató aktuális pozicióját
document.getElementById("disp").value = oDSO.recordset.AbsolutePosition + "/" + oDSO.recordset.RecordCount;
}
function uj_record() //új rekordot fűz az adatbázis végéhez
{
oDSO.recordset.AddNew(); //hozzáad egy üres elemet és ráállítja az elemmutatót
oDSO.recordset.fields('ev') = window.prompt("Add meg az évet",""); //az új üres elem 'ev' nevű mezőjét teszi
// egyenlővé a felhasználó által megadott értékkel, mivel az elemmutató az új elemre lett állítva
oDSO.recordset.fields('nev') = window.prompt("Add meg a nevet",""); //ugyanaz mint feljebb
oDSO.recordset.fields('nemzetiseg') = window.prompt("Add meg a nemzetiséget","");
disp(); //mivel megváltozott az elemmutató pozíciója és az adatbázis rekordjainak száma, frissíteni kell a kijelzőt
alert("Új rekord hozzáadása sikeres!"); //felhasználó informálása a sikeres rekord felviteléről
}
function record_torol() //törli az aktuális (elemmutató által mutatott) rekordot
{
oDSO.recordset.Delete();
disp(); //frissíti a kijelzőt, mert csökkent a rekordok száma az adatbázisban és az elemmutató az első elemre mutat
alert("Rekord törlése sikeres!"); //felhasználó informálása a sikeres törlésről
}
//-->
</SCRIPT>
</BODY>
</HTML>
OBJECT
elemmel illesztünk be a HTML oldalba. A TDC objektumnak paraméterként adjuk át az egyes feldolgozási utasításokat: szöveg kvalifikátort, elválasztót, kódólási formát és az URL-t. A TDC objektumhoz hozzárendeltünk egy onDataSetComplete
eseményt, amely akkor következik be (és hívja meg a disp()
metódust, mely funkciójáról később lesz szó), amikor az adatok betöltődtek.
Adatok rendezése
Ha az első SELECT
megváltozik (onChange
), megváltoztatja a TDC Sort
tulajdonság értékét a kiválasztott elem értékére (ami egyben az egyik oszlop neve is az adatbázisban) (TDC.Sort=('+'+this.value)
), amely hatására rendeződik az adatbázis a megadott módon. Biztos mindenkinek feltűnt a '+' jel az Sort
tulajdonság értékében. Jelentése nem más mint a rendezés iránya ('+'-normál rendezés, '-'-fordított rendezés). Minden rendezés illetve kiválasztás után frissítenünk kell a megjelenített adatokat (TDC.Reset()
)
Adatok kiválasztása
Működése annyiban különbözik a rendezéstől, hogy változtatás esetén (második SELECT
elem) a TDC Filter
tulajdonságának értékét változtatjuk a következő képpen: adatbázis sorának értéke egyenlő egy bizonyos értékkel (mi esetünkben a SELECT
-ben kiválasztott értékkel). Vagyis a mi példánkban: TDC.Filter=('nemzetiseg='+this.value)
jelentése: csak azokat a sorokat irasd ki, amelynél a nemzetiség megegyezik a SELECTben kiválasztottal.
Bízom benne, hogy mindenki DSO-k utáni étvágyát és érdeklődését legalább részlegesen ki tudtam elégíteni. A következő részben DOM objektum modell segítségével fogjuk végigjárni és megjeleníteni az XML dokumentumokat. Előtte viszont ajánlanám minden olvasó szíves figyelmébe a JavaScript alap szintű megértését, mivel az egész cikk ezen kliens oldali szkript nyelvre fog épülni.
A cikkben közölt forráskódok összetömörítve innen tölthetők le.