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>