Formulářové controly jsou umístěny ve vlastním namespace. Proto jejich tagy začínají f:, na rozdíl od je: používaného u ostatních controlů systému JellyPot. Celý formulář se umísťuje do serverového tagu <form>. Ten se může ve stránce vyskytovat jen jedenkrát (vlastnost ASP.NET).
JellyPot podporuje dva typy formulářů – <f:CollectionForm> a <f:EmailForm>. My se nejprve podíváme na jednodušší <f:CollectionForm>, který slouží k uložení dat z formuláře do databáze. <f:EmailForm>, který navíc umí data poslat na zvolený email, si ukážeme v další kapitole.
Do <f:CollectionForm> se umísťují dvě šablony:
- formTemplate – kód formuláře, který se zobrazí na stránce
- sentTemplate – kód, který se zobrazí po odeslání formuláře
Pro práci s formulářovými poli můžeme ve formTemplate používat následující controly:
- <f:input> – slouží k vygenerování
<input type="text"/> - <f:textarea> – slouží k vygenerování
<textarea> - <f:check> – slouží k vygenerování
<input type="checkbox" /> - <f:select> – slouží k vygenerování
<select> - <f:hidden> – slouží k vygenerování
<input type="hidden" />– pole, jehož hodnota není zobrazena uživateli, obvykle se vyplňuje javascriptem - <f:const> – pole, které obsahuje buď předem danou neměnnou hodnotu, nebo systémovou hodnotu typu aktuální čas, IP adresa klienta, URL aktuální stránky, user-agent atp.
- <f:sendbutton> –
<input type="submit" />– tlačítko pro odeslání formuláře
Kontaktní formulář
Vraťme se k našemu příkladu s blogem. Na stránku „O autorovi“ bychom chtěli přidat jednoduchý formulář pro poslání zprávy autorovi. Na konec stránky /cs/about.aspx vložíme tento kód:
...
<form method="post" runat="server">
<f:CollectionForm runat="server" id="contact" targetCollection="message">
<formTemplate>
<label>Vaše jméno* <f:input runat="server"
id="name"
targetField="name" />
</label>
<label>Email* <f:input runat="server"
id="email"
targetField="email" />
</label>
<label>Zpráva <f:textarea runat="server"
id="message"
targetField="message" />
</label>
<f:sendButton runat="server" textValue="Odeslat" />
</formTemplate>
<sentTemplate>
<p>Zpráva byla odeslána. Díky!</p>
</sentTemplate>
</f:CollectionForm>
</form>
...
Atributem targetCollection controlu <f:CollectionForm> říkáme, že data z odeslaného formuláře chceme uložit do kolekce message. Jednotlivé formulářové prvky mají atributy targetField – ty říkají, do kterého pole určené kolekce se hodnota uloží. Atribut id je povinný, slouží k identifikaci formulářových prvků uvnitř systému JellyPot a také k vygenerování atributů name ve finálním HTML.
V našem příkladu tedy musíme do Site.config doplnit kolekci message a typ jejích prvků MessageItem:
...
<Vars>
<Collection name="message" itemType="MessageItem" />
</Vars>
...
<Types>
<Type name="MessageItem">
<SimpleText name="name" />
<SimpleText name="email" />
<Text name="message" />
</Type>
</Types>
...
Diskuze pod články
V atributu targetCollection controlu <f:collectionForm> lze použít i relativní cestu ke kolekci. Toho využijeme pro vytvoření diskuze pod články. Do Site.config doplníme typ BlogPostCommentItem a rozšíříme typ BlogPostItem:
...
<Types>
<Type name="BlogPostCommentItem">
<SimpleText name="email" />
<SimpleText name="name" />
<DateTime name="added" />
<Text name="message" />
</Type>
<Type name="BlogPostItem">
<SimpleText name="title" />
<DateTime name="published" />
<Text name="text" />
<Collection name="comment" itemType="BlogPostCommentItem" />
</Type>
</Types>
...
(Pozn.: Na pořadí typů v sekci Types nezáleží.)
Na konec /cs/blogpost.aspx před značku </je:content> ukončující obsah pro region main vložíme formulář:
<je:content runat="server" forRegion="main">
...
<form runat="server" method="post">
<f:collectionForm runat="server" id="forumPost" targetCollection=".comment">
<formTemplate>
<label>Jméno* <f:input runat="server"
id="name"
targetField="name" />
</label>
<label>Email* <f:input runat="server"
id="email"
targetField="email" />
</label>
<label>Zpráva* <f:textarea runat="server"
id="message"
targetField="message" />
</label>
<f:const runat="server" constType="DateTime" id="added" targetField="added" />
<f:sendButton runat="server" textValue="Odeslat" />
</formTemplate>
<sentTemplate>
<p>Přidáno!</p>
</sentTemplate>
</f:collectionForm>
</form>
</je:content>
Tím máme zařízeno, že uživatelé můžou přidávat pod jednotlivé články komenty. Vložené komenty ale ještě musím pod článkem vypsat. To už ale umíme. V principu se to nijak neliší např. od vypsání přehledu článků na homepage. Kompletní kód stránky bude vypadat takto:
<%@ Page %>
<%@ Register TagPrefix="uc" TagName="teaser" Src="~/controls/teaser.ascx" %>
<je:container runat="server" expect="blogPost">
<je:master runat="server" href="~/masters/main.master" />
<je:content runat="server" forRegion="head">
<title><je:item runat="server" field=".title" /></title>
</je:content>
<je:content runat="server" forRegion="main">
<je:item runat="server" field=".title" tag="h1" />
<je:item runat="server" field=".published" tag="time" />
<je:avar runat="server" href="category.aspx" container=".category">
<je:item runat="server" field=".category.title" />
</je:avar>
<je:item runat="server" field=".text" tag="p" />
<h2>Diskuse</h2>
<je:repeater runat="server" source=".comment">
<item>
<div class="comment">
<je:item runat="server" field=".name" tag="" />
<je:item runat="server" field=".added" tag="time" />
<je:item runat="server" field=".message" />
</div>
</item>
</je:repeater>
<h3>Přidejte příspěvek</h3>
<form runat="server" method="post">
<f:collectionForm runat="server" id="forumPost" targetCollection=".comment">
<formTemplate>
<label>Jméno* <f:input runat="server"
id="name"
targetField="name" />
</label>
<label>Email* <f:input runat="server"
id="email"
targetField="email" />
</label>
<label>Zpráva* <f:textarea runat="server"
id="message"
targetField="message" />
</label>
<f:const runat="server" constType="DateTime" id="added" targetField="added" />
<f:sendButton runat="server" textValue="Odeslat" />
</formTemplate>
<sentTemplate>
<p>Přidáno!</p>
</sentTemplate>
</f:collectionForm>
</form>
</je:content>
</je:container>