ASP.NET pro začátečníky
4. Webové formuláře
MENU

Zřejmě znáte klasické HTML tagy form, input atp. Pomocí nich nejčastěji probíhá komunikace směrem od klienta k serveru - je to ale všechno takové chaotické. Jak už jsme si říkali, služba WWW je bezstavová. Server absolutně netuší, co se tam u klienta děje, prostě jenom přijímá obecné požadavky na stránky. Tento problém se řeší několika způsoby.

Cookies jsou malé textové soubory, které si může webová stránka (a to jak server pomocí HTTP hlavičky, tak klientský skript) uložit na disku uživatele. Webový prohlížeč bude obsah tohoto souboru zasílat s každým dalším požadavkem na stránku z této domény a tím může server vcelku bezpečně rozpoznat, s jakým uživatelem má tu čest. Programátor si ale musí vše obstarat sám a navíc, a to je možná horší, si mnoho uživatelů ze strachu před neexistujícími bezpečnostními hrozbami cookies vypíná.

Sessions je technologie pracující na základě cookies, ale obsahuje mnohá zajímavá vylepšení. Předně to, že u klienta se ukládá jenom SessionID, což je řetězec, který uživatele jednoznačně identifikuje - všechna data se tak skrývají na serveru. To má dvě přednosti - můžeme tak dobře identifikovat přihlášeného uživatele bez bezpečnostních rizik a navíc je práce se sessions o něco snadnější než s cookies. Navíc sessions ani nemusí vyžadovat zapnuté cookies - jediný potřebný řetězec lze skrýt do URL (webové adresy) každé volané stránky - to už lepší technologie jako PHP a ASP.NET dělají automaticky.

Zatímco koláčky (cookie znamená česky koláček) se běžně užívají k dlouhodobějšímu ukládání údajů u klienta (na některých webech se například ukládá, kdy daný návštěvník navštívil tu kterou diskuzi a při příští návštěvě se zobrazuje údaj "12 nových příspěvků"), pomocí sessions se běžně řeží přihlašování, u kterého je obvyklá hodnota vypršení platnosti kolem dvaceti minut.

Oba dva systémy jsou vcelku užitečné a jednou si je pořádně probereme.

Pár drobností
Všechny příklady z tohoto dílu najdete v ZIP archivu na tomto CD. Můžete si je také okamžitě vyzkoušet na www.czech-ware.net/lansky/CHIP/4/priklady.html.
Webové formuláře
<%@ Page Language="VB" Debug="True" %>
<%@ Import Namespace="System.Drawing" %>

<SCRIPT RUNAT="server">
   Sub ZmenText(obj As Object, e As EventArgs)
      popisek.Text = "Stisknul jste tlačítko."
   End Sub
</SCRIPT>

<HTML>

<HEAD>
<TITLE>Programování v ASP.NET</TITLE>
</HEAD>

<BODY>
<FORM RUNAT="server">
<ASP:Label ID="popisek" RUNAT="server" Text="Nic se nestalo..." />
<ASP:Button ID="tlacitko" TEXT="Odeslat" OnClick="ZmenText"
   RUNAT="server" />
</FORM>
</BODY>

</HTML>

Poznáváte tento kód? Před dvěma měsíci jsme ho používali pro zběžné nakouknutí do systému webových formulářů (Web Forms). Nyní budeme pokračovat.

Serverový ovládací prvek je vlastně objekt, který je v ASP.NET umisťován přímo do HTML kódu. Jako každý jiný objekt může mít i tento vlastnosti, metody a události, se kterými můžeme pracovat z programového kódu.

Tyto objekty se nacházejí v BCL .NET Framoworku v prostoru názvů System.Web.UI.WebControls (viz WebControls v SDK nebo v MSDN). "O kousek dál" najdeme prostor názvů System.Windows.Forms, ve kterém jsou všechny potřebné ovládací prvky pro libovolnou klientskou aplikaci - opravdu není důvod dělat rozdíly mezi serverovými a klientskými programy.

Pokud chceme vložit ovládací prvek do stránky, měli bychom ho uzavřít do tagu <FORM RUNAT="server">. Pokud to tak neuděláme, může nám to ASP.NET oznámit chybovou hláškou, nebo se také může tvářit jako že se nic neděje a přitom to nemusí fungovat. Každý serverový ovládací prvek by měl mít atribut runat="server", aby ho server rozpoznal jako něco, s čím by si měl dělat starosti. A nesmíme zapomenout na atribut ID, pomocí kterého můžeme s vlastnostmi a metodami prvku pracovat z programového kódu.

Pár drobností

Na tomto místo by možná bylo záhodno uvést pár užitečných věcí souvisejících s webovými formuláři.

V mnoha kódech na Internetu například naleznete vlastnost objektu Page IsPostBack. Většinou se jedna o podmínky If Not Page.IsPostBack Then... Tímto se testuje, zda byla stránka uživatelem vyžádána poprvé (v rámci aktuálního stavu) nebo jestli už s ní uživatel pracuje (tj. kliknul na nějaké tlačítko atp.) Občas je to třeba - některé operace je záhodno vykonat jen jednou, při vstupu na stránku. Zvlášť pokud jsou časově náročné.

Možná vás napadlo, jestli by nebylo možné, aby si sám programátor něco uložit do stavového řetězce (viewstate). Samozřejmě to jde - používá se k tomu proměnná ViewState. Zápis nějakého údaje provádíme takto:

ViewState("Pocet_dni") = 139

Analogicky čtení dat:

neco.Value = ViewState("Pocet_dni")

Chcete-li o ViewState vědět ještě víc, přečtete si jeden velmi dobrý článek na ASPNetwork.cz.

Přehled základních ovládacích prvků

S prvkem Label jsme se již seznámili. Slouží k zobrazování textu, po nastavení parametru Text "vyplivne" tutéž hodnotu obklopenou tagem SPAN.

Ovládací prvek TextBox už je zajímavější. Použijeme-li ho, stane se z něj na stránce klasický element INPUT (s parametrem type="text") čekající na uživatelův vstup. Ten se nám po odeslání formuláře objeví ve vlastnosti Value.

Button funguje jako atribut INPUT s parametrem type="submit" - jde tedy o jednoduché odesílací tlačítko. Parametr TEXT u něj nabízí volbu popisku tohoto tlačítka. Nesmírně často u něj budeme užívat metody OnClick, kterou ošetříme uživatelovo odeslání daného formuláře.

Kupříkladu:

<%@ Page Language="VB" Debug="True" %>

<HTML>

<HEAD>
<TITLE>Příklad</TITLE>
</HEAD>

<BODY>

<SCRIPT RUNAT="server">
   Sub napsal(obj As Object, e As EventArgs)
      popisek.Text = "Napsal jsi mi: <i>" + vstup.Text + "</i>"
   End Sub
</SCRIPT>

<form runat="server">
<ASP:Label ID="popisek" Text="Proč nepíšeš? :-(" RUNAT="server" /><br><br>
<ASP:TextBox ID="vstup" RUNAT="server" />
<ASP:Button ID="tlacitko" TEXT="Odeslat" OnClick="napsal" RUNAT="server" />
</form>
   
</BODY>

</HTML>

Tento příklad demonstruje použití všech třech zmíněných prvků - TextBox od uživatele sebere informace, Button ji odešle a spustí určenou proceduru napsal a ta nastaví prvku Label potřebný text.

Půjdeme dále. Prvek CheckBox vytváří klasické zatrhávací tlačítko (podobně jako input type="checkbox"). Jeho zaškrtnutí můžeme nastavovat či kontrolovat pomocí vlastnosti Checked a popisek můžeme nastavit vlastností Text.

RadioButton vloží do výsledného HTML dokumentu přepínač - to je zatrhávací tlačítko, které se objevuje ve skupině, přičemž zatrženo může být jen jedno. Opět tu máme vlastnosti Checked a Text.

Chceme-li vytvořit více skupinek s RadioButtony, potřebujeme zajistit, aby se nám jednotlivá tlačítka přepínala správně uvnitř oddělených skupin. K tomu je výhodný serverový ovládací prvek RadioButtonList. Položky budou tvořit ovládací prvky typu ListItem. Vybranou položku můžeme identifikovat pomocí objektu SelectedItem. Jeden příklad vydá za tisíc slov:

<%@ Page Language="VB" Debug="True" %>

<HTML>

<HEAD>
<TITLE>Příklad</TITLE>
</HEAD>

<BODY>

<SCRIPT RUNAT="server">
   Sub odeslano(obj As Object, e As EventArgs)
      popisek.Text = "Zvolený věk: <i>" + prepinatka.SelectedItem.Text + "</i>"
   End Sub
</SCRIPT>

<form runat="server">
<asp:Label id="popisek" runat="server" />
<asp:RadioButtonList id="prepinatka" runat="server">
   <asp:ListItem> < 18 </asp:ListItem>
   <asp:ListItem> 18-25 </asp:ListItem>
   <asp:ListItem> 25-35 </asp:ListItem>
   <asp:ListItem> 35-50 </asp:ListItem>
   <asp:ListItem> 50-60 </asp:ListItem>
   <asp:ListItem> > 60 </asp:ListItem>
</asp:RadioButtonList>
<asp:Button id="tlacitko" text="Odeslat" runat="server" OnClick="odeslano" />
</form>

</BODY>

</HTML>

Podobný seznam lze vytvořit i s CheckBoxy za pomoci prvku CheckBoxList. Tam to ale nemá tak zřejmé opodstatnění jako v tomto případě.

HTML serverové ovládací prvky

Serverové ovládací prvky jsou dvojího druhu - zatím jsem představoval zástupce toho prvního, tzv. webových serverových ovládacích prvků. Vyznačují se zápisem typ <asp:Neco... a jsou schopny velmi pokročilého chování (např. prvek Calendar). Pak jsou tu také další, které se nazývají serverové ovládací prvky jazyka HTML.

Ty jsou založeny na standardním zápisu HTML tagů, například ve tvaru <input type=..., je třeba k nim však připojit ještě parametr runat="server", aby byly vůbec za serverové prvky považovány.

Jako příklad prvku tohoto typu si můžeme uvést třeba HtmlImage. S obyčejným obrázkem můžeme po přidání atributu runat="server" spoustu věcí - měnit jeho SRC (takže jej měnit v jiný), zarovnání, popisek, ohraničení atp. Protože obrázek sám nemá žádné události, musíme přidat něco, s čím můžeme ovládat chování příkladu - k tomu se dobře hodí prvek HtmlButton.

Pozor si musíme dát na to, že místo klasických OnClick událostí musíme používat názvy OnServerClick atp. U HTML elementů totiž můžeme používat jak skriptování serverové, tak klientské JavaScripty - jejich události je třeba nějak odlišit.

V tomto příkladu se po kliknutí na odkaz změní jeho text:

<%@ Page Language="VB" Debug="True" %>

<HTML>

<HEAD>
<TITLE>Příklad</TITLE>
</HEAD>

<BODY>

<SCRIPT RUNAT="server">
   Sub klik(i As Integer)
      obrazek.src = i.ToString + ".gif"
   End Sub
</SCRIPT>

<img runat="server" id="obrazek"
   src="1.gif"><br>
<button runat="server" id="cudlik1"
   onServerClick="klik(1)">Obrázek 1</button>
<button runat="server" id="cudlik2"
   onServerClick="klik(2)">Obrázek 2</button>

</BODY>

</HTML>
Vlastní ovládací prvky

Velmi zajímavá vlastnost těchto prvků tkví v tom, že si můžete vcelku snadno vytvořit další takové a tak šikovně umístit často se opakující kódy ze svých stránek do externích souborů.

Nejdříve je třeba vytvořit soubor s příponou ascx, který bude mít mírně modifikovanou hlavičku:

<%@ Control Language="VB" %>

Dále v něm můžeme libovolně pracovat, jako v normální stránce. Vstupní proměnné můžeme načítat přes deklaraci Public nazev As typ, která se bude nacházet mimo všechny metody a obsluhy událostí. Například:

<script runat="server">
  Public cinitel1 As Integer
  Public cinitel2 As Integer
  
  Sub Page_Load(obj As object, e As EventArgs)
     vysledek.Text = (cinitel1 * cinitel2).ToString   
  End Sub
</script>

<asp:Label id="vysledek" runat="server" />

Vlastní soubor pak musíme do stránky, ve které chceme tento prvek použít, vložit pomocí speciální konstrukce:

<%@ Register TagPrefix="pocitani" TagName="nasobeni" src="nasob.ascx" %>

TagPrefix je text, který budeme potřebovat při volání tohoto prvku - bude se nacházet před dvojtečkou, to je tam, kde jsme zatím vídali pouze standardní asp.

TagName je vlastní identifikátor prvku, dává se za dvojtečku při volání prvku.

Src samozřejmě určuje soubor, ve kterém jsme kód daného prvku schovali.

Takže daný externí soubor budeme volat:

<pocitani:nasobeni id="nasobeni1" cinitel1="15" cinitel2="3" runat="server" />

Toto je samozřejmě celkem hloupé použití této technologie. Mnohem zajímavější jsou možnosti na větších webech, kde takto můžeme automaticky vkládat hlavičky či třeba diskuze k jednotlivým článkům... Výhodou takovéhoto odklizení funkcí do externího souboru je to, že si tak zpřehledníte kód stránky a navíc určitě oceníte možnost změnit kód jednoho prvku na sto stránkách během pár sekund.

Závěrem

Gratuluji, zvládli jste základy technologie ASP.NET. V příštím díle se naučíme načítat data z textových souborů a trošku si setřídíme dosavadní znalosti při prvním pokusu o nějaký větší projekt - knihu návštěv.

Lukáš Lánský
Veškeré náměty, dotazy a připomínky pište na adresu lansky@czech-ware.net.