december, 2007 havi archívum

Év záró blogbejegyzés…

Posted: 2007. december 31. in Egyéb
Ma ismét véget ér egy év, pár óra múlva, és éjfélkor majd minden ember megfogadja, hogy jövőre is figyelni fogja a blogomon a történéseket!
Ha nem is feltétlenül ezt fogadjátok meg, akkor is nézzetek majd be, vagy iratkozzatok fel az RSS hírlevelekre, mert jövőre még több érdekességgel, tutoriallal és egyéb asp.net-es nyaklánkságokkal foglak kényeztetni benneteket.
 
Na jó a viccet és a marketing szöveget félretéve, a közeli jövőről annyit, hogy januárban megpróbálok valamivel termékenyebb lenni, mint decemberben, bár ez a vizsgáim eredményeinek függvényében dinamikusan változhat! (remélem azért nem fogok belerokanni).
A távolabbi terveim között az is szerepel, hogy miután befejezem az ACT-s tutorialokat, elindítok majd egy SilverLight 2.0-ás howto sorozatot. SL 2.0-ból március környékére igérik a végleges verziót, addigra talán én is kivégzem az Ajax Control Toolkit-et… (aki még nem tudott volna róla, a Silverlight 1.1-et november végétől SilverLight 2.0-nak kell hívni, ami végre ténylegesen tükrözi azt, hogy mekkora óriási különbség van az SL 1.0 és 1.1 között. Az elsőt még csak java script segítségével lehetett programozni, míg a 2.0-t már menedzselt kód segítségével lehet vezérelni!!!!).
Tervben van még az is, hogy az msportal-os asp.net 2.0 cikksorozatot is megpróbálom majd lassacskán befejezgetni és áttérünk ott is majd az ASP.NET 3.5-re!
 
 
Ilyenkor sokan szoktak tartani évzáró vagy évadzáró értékeléseket, én ezzel nem untatnék senkit… én most inkább köszönetet szeretnék mondani azoknak, akik támogattak a blogolásban, a tutorial készítésekben, stb… és természtesen mindazon asp.net-es fejlesztőknek, akik kérdéseikkel, illetve kéréseikkel bizalommal fordultak hozzám! 
 
Mielőtt még mindenki elsírná magát el is búcsúzok erre az évre, majd jővőre úgyis találkozunk!
 
BOLDOG ÚJ ÉVET KÍVÁNOK MINDENKINEK!!!
(az egyetemistáknak/főiskolásoknak (sorstársaknak) pedig kitartást és sikeres vizsgaidőszakot kívánok!!)
 

AJAX Control Toolkit –
FilteredTextBoxExtender

Ez egy példaalkalmazáshoz tartozó leírás! Az alkalmazás erről a címről tölthető el:
http://www.devportal.hu/portal/Detailed.aspx?NewsId=d3bcb62b-b544-4605-af1d-de5da30c015a vagy

http://cid-8dcaf3b0da4fb828.skydrive.live.com/embedrowdetail.aspx/ACTsorozat/ACT|_XIV|_FilteredTextBoxExtender.zip

Ma egy olyan vezérlővel ismerkedünk meg, mely megkönnyítheti a felhasználótól érkező input adat validását. Ez az extender nem más, mint a FilteredTextBoxExtender.
 
FilteredTextBoxExtender alapok
A FTBE, mint ahogy a nevéből is érződik, csak és kizárólag TextBox vezérlőkre akasztható rá. Funkcionalitásában a validator vezérlőkhöz nagyban hasonlít, működését tekintve viszont nagy eltérés tapasztalható. A validator vezérlők segítségével generált scriptek, csak akkor futnak le, amikor vagy elveszíti az adott vezérlő a fókuszt, vagy pedig teljes postback-et generáló eseményt vált ki a kliens (pl.: button_click).
Ezzel szemben az FTBE script az oldal betöltődésétől kezdve „mintavételez”. Szakmaiban megfogalmazva, a script elindít egy Timert, mely alapértelmezetten 250 ms-onként figyeli a klienstől érkező billentyűparancsokat. Ezeket utána szűri, vagyis nem engedi meg a felhasználónak, hogy a textbox-ba illegális karaktereket vigyen fel.
Mi is az illegális karakter? Az FTBE úgy működik, hogy megszabjuk, mely (vagy milyen típusú) karaktereket engedünk meg a kliensnek, hogy megadhasson az adott TextBox vezérlőnek, vagy éppen ellenkezőleg, melyeket nem. (Értelemszerűen azt kell beállítani, amelyiknél kevesebbet kell gépelni! ).

FilteredTextBoxExtender használata
Most egy olyan példaalkalmazást fogunk elkészíteni, aminek szinte semmi értelme sincs, de legalább jó állatorvosi ló! Tehát 3 beviteli-mezőt fogunk szűrni, az alábbi módokon:
– Csak kisbetűket lehet felvinni,
– Numerikus karaktereket, illetve műveleti-jeleket: 0-9, +, -, /, *, (, ),
– Csak mássalhangzókat.

Az elsőt valahogy így tudjuk a legegyszerűbben megvalósítani:

<asp:TextBox ID="txtbox_lowercase" runat="server"></asp:TextBox>
<ajaxToolkit:FilteredTextBoxExtender ID="FTBE_1" runat="server"
                   TargetControlID="txtbox_lowercase"
                   FilterType="LowercaseLetters" />

A FilterType tulajdonság azt szabja meg, mely karaktercsoportot engedélyezzük a kliensnek. Az alábbi értékeket állíthatjuk be:
LowercaseLetters: kisbetűk
UppercaseLetters: nagybetűk
Numbers: számjegyek
Custom: egyedi

Fontos és jegyezzük is meg, hogy egy adott Textbox vezérlőhöz, csak egyetlen egy FTBE kapcsolható! Ezért a FilterType tulajdonságnál egyszerre, akár több karaktercsoportot is megszabhatunk, ehhez összesen csak annyit kell tennünk, hogy vesszővel válasszuk el a csoportneveket egymástól. Nézzünk is rá egy példát:
 
<asp:TextBox ID="txtbox_math" runat="server"></asp:TextBox>
<ajaxToolkit:FilteredTextBoxExtender ID="FTBE_2" runat="server"
                   TargetControlID=" txtbox_math"
                   FilterType="Numbers, Custom"
                   ValidChars="+-*/()" />

Ha Custom FilterType-ot is használunk, akkor muszáj beállítanunk a ValidChars tulajdonságot is. A ValidChars-nál, ellentétben a neten található példakódokkal, nem kell veszővel elválasztani az „érvényes” karaktereket egymástól, szimplán csak fel kell őket sorolni.
Néha előfordulhat, hogy a komplementer halmazt (vagyis az invalid karakterek halmazát) egyszerűbb lenne megadni, mint az összes valid karaktert. Erre is kapunk támogatást az FTBE-től, nézzük is meg miként:

<asp:TextBox ID="txtbox_consonant" runat="server"></asp:TextBox>
<ajaxToolkit:FilteredTextBoxExtender ID="FTBE_3" runat="server"
                   TargetControlID="txtbox_consonant"
                   FilterMode="InvalidChars"
                   InvalidChars=" aAáÁeEéÉiIíÍoOöÖőŐuUüÜűŰ" />

Amint az a kódból is látszik, a FilterType-ot nem kell nekünk kézzel beállítanunk, mivel az alapértelmezett értéke a Custom.
Az InvalidChars tulajdonságnál értelemszerűen azokat a karaktereket soroljuk fel, amelyet tiltani szeretnénk. Ahhoz, hogy a többi karaktert viszont elfogadjuk a FilterMode-ot át kell állítanunk InvalidChars-ra. Ez azt eredményezi a scriptünknél, hogy a leütött billentyűk közül csak azokat fogja átengedi a szűrőn, akik nem szerepelnek a feketelistán. (FilterMode alapértelmezetten ValidChars).

Az FTBE-nek van még egy említést érdemelő tulajdonsága: a FilterInterval. Ezzel a tulajdonsággal a Timer objektum Interval értékét tudjuk beállítani, vagyis hogy milyen gyakran történjen mintavételezés. Az alapértelmezett 250 milliszekundum.

Egy-két okosság
Az egyik dolog, ami tesztelés közben fel fog tűnni, hogy a szóközt nem fogja elfogadni automatikusan az FTBE. Ezen nem is lepődünk meg annyira, hiszen a szóköz is egy karakter csak nincs vizuális megjelenése. Ellenben kerülhetünk olyan szituációba is, mint például az utolsó példakódnál, hogy az Invalid karaktereket szabtunk meg, de mégse fogja elfogadni a rendszer a szóközt. Ilyenkor a megoldás az, hogy a ValidChars tulajdonság segítéségével kibővítjük az alapban elfogadott karakterek halmazát (Numbers, LowerCaseLetters, UpperCaseLetters), vagyis: ValidChars=" ".

A másik dolog, amit nem árt, ha észbe tartunk, hogy ez a fajta input-védelem nagyon egyszerűen kijátszató! Ugyanúgy, mint a validatároknál itt is az ellenőrző script egy az egyben benne van az oldalban, amelyet lementve, majd kikommentezve a megfelelő függvényhívást, ha futattunk, máris nehéz helyzetbe hoztuk a fejlesztőt! Ezért ne feledjük, mindig ellenőrizzük szerver oldalon is bejövő adatokat, hiszen minden input az ördögtől származik!

Túl a 10000-ren!!!!!

Posted: 2007. december 13. in Egyéb
Igen, megvan!
Ma hajnalban átléptük a bűvös 10ezres látogatásottságot!
 
Köszönöm nektek!!!!

AJAX Control Toolkit –
DynamicPopulateExtender

Ez egy példaalkalmazáshoz tartozó leírás! Az alkalmazás erről a címről tölthető el:
http://www.devportal.hu/portal/Detailed.aspx?NewsId=ee62366d-0b1d-4ba2-bc7e-0febaad87391 vagy

http://cid-8dcaf3b0da4fb828.skydrive.live.com/embedrowdetail.aspx/ACTsorozat/ACT|_XIII|_DynamicPopulateExtender.zip

Ebben a cikkben a DynamicPopulateExtender-rel ismerkedünk meg, ami leginkább az UpdatePanel + UpdateProgress vezérlők összegyúrására hasonlít!
 
DynamicPopulateExtender alapok
A DPE nagy vonalakban arra való, hogy aszinkron kérések segítségével ki tudjuk cserélni az oldalunk egy bizonyos markup részét, egy WebService vagy egy Script által visszaadott HTML markuppal. Ehhez mindösszesen 3 dologra van szükségünk. Egy vezérlőre, amelynek az egyik eseményéhez egy trigger-t (kioldó-t) rendelhetünk. Fontos, és jegyezzük is meg, hogy csak olyan HTML vezérlőt használhatunk erre a célra, amely nem generál automatikusan Postback-et. Tehát az ASP.NET-es button, linkbutton nem jó, sőt a „sima” html-es submit se! Az <input type="button" viszont már igen, ha mindenféleképpen gombhoz ragaszkodunk. (Mint ahogy fentebb is szó volt róla, bármilyen olyan HTML vezérlőhöz kapcsolható trigger, ami nem generál postbacket, tehát a radiobutton, checkbox, stb. is jó (lentebb látunk majd ezekre is egy példát!)).
A másik vezérlő, amire feltétlenül szükségünk van, az egy konténervezérlő, amelynek a tartalmát tudjuk kicserélni. Tehát nem egy vezérlő markup-ját tudjuk kicserélni, hanem a vezérlőn belül eltárolt szöveget! Így az alábbi pár vezérlő használható konténerként: Panel, Label (Repeater/DataList – ezeket nem volt időm kipróbálni, de állítólag működik velük is!)
A harmadik dolog, amire szükségünk van egy DPE és egy hozzátartozó script vagy webservice, ami generálja a kódot. Nézzünk is, egyből két példát a DynamicPopulate használatára!

DynamicPopulateExtender használata

Egy egyszerű példa
Most egy olyan alkalmazást fogunk elkészíteni, ami egy címke szövegét cseréli le postback nélkül. (A stílusosztályok, melyekre hivatkozok a kódokban, a letölthető példaalkalmazásban megtalálhatóak!) Lássunk is neki!
Először is szükségünk lesz egy HTML button vezérlő, NEM Submit-ra, hanem sima button-re. Ezek után, kell még nekünk egy Label vezérlő és egy DPE. Állítsuk be őket az alábbi módon:

<input id="btn" type="button" value="Kattanj rám" runat="server" /><br/>
<asp:Label ID="lbl_container" runat="server">
    Alapból beállított szöveg
</asp:Label>
<ajaxToolkit:DynamicPopulateExtender ID="DPE_1" runat="server"
            TargetControlID="lbl_container"
            PopulateTriggerControlID="btn"
            CustomScript="GetMarkup()">
</ajaxToolkit:DynamicPopulateExtender>

A TargetControlID-val azt állíthatjuk be, hogy mely konténervezérlő szövegrészét szeretnénk majd lecseréltetni!
A PopulateTriggerControlID azt a vezérlőt szabja meg, amely default eseményének bekövetkeztekor, végrehajtódjon a markup csere. Jelenestben ez a btn nyomógomb, melynek a click eseményékor hajtódik majd végre a populate trigger.
A CustomScript-nél megadott script hajtódik végre, amikor a trigger kiold. (Fontos, hogy a zárójelek ne maradjanak le a függvény végéről, mert különben a függvény kódja lesz az új markup kód! )

Most már csak annyi dolgunk van, hogy megírjuk a GetMarkup() függvényünket. Egyetlen egy megkötésünk van csak a függvénnyel kapcsolatban, hogy string-gel térjen vissza. Íme egy egyszerű példa a megvalósítására:

<script type="text/jscript">
    function GetMarkup()
    {
        return "<h1>Dinamikusan generált HTML szöveg</h1>";
    }
</script>

És készen vagyunk! Futtassuk, nézegessük!
Ha összesen ennyit tudna ez a vezérlő, akkor eléggé rossz pontozást kapnának tőlem az ACT fejlesztői, de szerencsére ennél azért valamivel többre is képes a DPE. Na, lássuk!

Egy kicsit bonyolultabb példa
Egy olyan alkalmazást szeretnénk megvalósítani, ami azt tudja, hogy választókapcsolók segítségével dinamikusan változzon egy Panel szövege. Itt egyből több problémába is belefutunk.
Az első probléma az, hogy több objektumunk is van, amiknél a trigger-nek ki kell oldani, de csak egyetlen egy vezérlőt tudunk megadni a PopulateTriggerControlID tulajdonságánál. Ezt a problémát úgy fogjuk megoldani, hogy mi „kézzel” (java script függvény segítségével) fogjuk kikényszeríteni, hogy kioldjon a trigger.
Ez mind szép és jó, de hogyan fogjuk azonosítani, hogy melyik vezérlő hatására oldott ki a trigger? Eszünk be jut, hogy a többi ACT vezérlőnél erre a problémára a contextKey stringet használtunk. A GetMarkup() függvényünknek adhatunk egy contextKey paramétert, de sajnos automatikusan nem fogja az AJAX rendszer neki átadni a contextKey értékeket. (Ha megnézzük az AjaxControlToolkit\DynamicPopulate\DynamicPopulateBehavior.js fájlt, akkor láthatjuk, hogy tényleg nem passzolja át a rendszer, hanem csak egyszerűen meghívja a CustomScript metódust). Erre a megoldás, a jól bevált WebService barátunk lesz.

Most, hogy a felmerült problémákat orvosoltuk, ideje belefogni az alkalmazás kifejlesztésébe.
Először adjunk az oldalhoz 4db radio típusú HTML input vezérlőt, és állítsuk be őket az alábbi módon: (adjunk az oldalhoz egy Panel-t is!)

<input type="radio" name="rbFormat" id="r1" value=’1′
        onclick="CallUpdate(this.value);" checked="checked" /> H1
<input type="radio" name="rbFormat" id="r2" value=’2′
        onclick="CallUpdate(this.value);" /> H2
<input type="radio" name="rbFormat" id="r3" value=’3′
        onclick="CallUpdate(this.value);" /> H3
<input type="radio" name="rbFormat" id="r4" value=’4′
        onclick="CallUpdate(this.value);" /> H4

<asp:Panel ID="pnl_container" runat="server" CssClass="dynamicPopulate_Normal" />

Ami a kódból egyedül magyarázatra szorul az a CallUpdate metódus. Ahhoz, hogy bármilyek radio gomb hatására kioldódjon a trigger, mi nekünk kell kézzel meghívnunk a DPE populate metódusát. Ehhez egy segédmetódust használnunk (a CallUpdate-t), amelynek átadjuk paraméterül a kiválasztott radiobutton értékét, ami ezentúl már contextKey-ként  funkcionálni. Nézzük, hogyan is néz ki a CallUpdate metódusunk:

<script type="text/jscript">
    function CallUpdate(value)
    {
       var extender= $find(‘DPE1’);
        if (extender)
  {
            extender.populate(value);
        }
    }
    Sys.Application.add_load(function(){CallUpdate(‘1’);});
</script>

Ez a függvény, akkor fog meghívódni, amikor rákattintunk valamelyik választókapcsolóra, vagyis amikor a kiválasztott elem megváltozik.
Először a rendszertől el kell kérnünk a DynamicPopulateExtender-t (mi a példaalkalmazásban DPE1 azonosítóra kereszteltük el a DPE-nket). Ezt eltároljuk egy extender nevű változóban, majd megvizsgáljuk, hogy létezik-e az objektum. (Ez a vizsgálat, azért került bele a kódba, hogy ha nincs meg a vezérlő, akkor ne dobjon hibát a java script).
Utána meghívjuk az DPE populate metódusát és átadjuk neki paraméterként a contextKey-t.
A CallUpdate function után lévő sor feladata az, hogy az oldal betöltődésekor is kioldódjon a trigger, vagyis kerüljön valamilyen szöveg a panelünkbe már a legelején is.

Adjunk az oldalhoz egy DPE vezérlőt, és az alábbi módon állítsuk be:

<ajaxToolkit:DynamicPopulateExtender ID="DPE1"  runat="server"
            TargetControlID="pnl_container"
            UpdatingCssClass="dynamicPopulate_Updating"
            ClearContentsDuringUpdate="true"           
            PopulateTriggerControlID="pnl_container"
            ServiceMethod="GetHTMLCode">
</ajaxToolkit:DynamicPopulateExtender>

Az UpdatingCssClass tulajdonság segítségével, az UpdateProgress-hez hasonló dolgot tudunk megvalósítani, vagyis a HTML content generálás alatt megszabhatjuk, hogy mi jelenjen meg a felhasználónak. Általában egy animált töltés gif-et szokás beállítani háttérként.
A ClearContentsDuringUpdate-tel mindösszesen annyit állíthatunk be, hogy amíg végrehajtódik az aszinkron kérés, addig maradjon-e az „előző” szöveg, vagy törölje a teljes context-et. (alapértelmezetten true)
A ServiceMethod értelemszerűen a webmetódus nevét szabja meg. Azért nincs ServicePath tulajdonságunk, mert a GetHTMLCode-ot az aspx fájlban tároljuk. Íme a kódja:

<script runat="server">
    [System.Web.Services.WebMethod]
    [System.Web.Script.Services.ScriptMethod]
    public static string GetHtmlCode(string contextKey){
        System.Threading.Thread.Sleep(800);
        return String.Format("<h{0}>Minta szöveg</h{0}>",contextKey);
    }
</script>

Két fontos dolog:
– Ne felejtsük el egyik attribútumot se, mert különben nem fog működni. (Az első azt mondja meg a rendszer, hogy ő egy webmetódus, a másik pedig, hogy a scriptek számára is elérhető!)
– Csak úgy fog működni a webmetódus, ha static-ra állítjuk a láthatóságát a függvényünket.

Természetesen éles projekt esetén a szálaltatás nem kell, most csak azért van benne, hogy localhost-on is ki tudjuk próbálni, hogy működik-e az UpdateCssClass.