6. diel - Wicket - Formulár a model
V tomto diele tutoriále vytvoríme stránku s kontaktným formulárom. Ten bude slúžiť k tomu, aby nám mohli návštevníci stránok napísať a poslať správu.
Najskôr ale vyriešime drobný nedostatok z přechozí lekcie. Budeme chcieť, aby sa text titulku okna menil okamžite pri zmene locale. Aktuálne sa v titulku okna zobrazí text, ktorý odovzdávame pri konštrukcii objektu Label titleLB. Je potrebné nastaviť objektu titleLB model a tento model (dáta, ktoré model vracia) meniť podľa jazykového nastavenia.
V balíčku cz.mujweb.basepage vytvoríme triedu modelu. Každý model obsahuje metódu GetObject (), ktorá vracia dáta a metódu setObject (), ktoré dáta zmení (metódu public void detach () nebudeme potrebovať, a preto ju necháme prázdnu). Náš model je jednoduchý.
TitleModel.java
public class TitleModel implements IModel { private String title = ""; @Override public void detach() { } @Override public Object getObject() { return title; } @Override public void setObject(Object object) { title = (String) object; } }
V triede BasePage.java vytvoríme inštanciu tohto modelu a pri konštrukcii titleLB ju odovzdáme ako parameter. Metódu public abstract String getTitle (); už potrebovať nebudeme, namiesto nej vytvoríme public abstract void setTitleModelObject ();
BasePage.java
public abstract class BasePage extends WebPage { protected IModel titleModel; public BasePage() { Link homePageLink = new Link("homePage") { … }; add(homePageLink); Link photosPageLink = new Link("photosPage") { … }; add(photosPageLink); add(new Link("en") { … }); add(new Link("cs") { … }); titleModel = new TitleModel(); Label titleLB = new Label("title", titleModel); add(titleLB); } public abstract void setTitleModelObject(); }
Vytvárame protected premennú titleModel, ktorá bude prístupná v triedach, ktoré z BasePage.class budú dediť.
protected IModel titleModel;
Ďalej do premennej titleModel priradíme inštanciu TitleModelu a použijeme ju ako parameter Label konstruktoru. Ďalej potom musíme metódu setTitleModelObject zavolať. Výsledkom je to, že zakaždým, keď sa titleLB bude vykresľovať, zavolá metódu GetObject () svojho modelu a dáta, ktoré touto metódou dostane, zobrazí.
titleModel = new TitleModel(); Label titleLB = new Label("title", titleModel); add(titleLB); setTitleModelObject();
Teraz musíme v HomePage.java a v PhotosPage.java zmazať teraz už nepotrebnú metódu public String getTitle () a namiesto toho implementovať metódu public void setTitleModelObject (). Metóda setTitleModelObject () nastaví objekt metódy (v našom prípade textový reťazec) na novú hodnotu. Táto nová hodnota sa použije pri ďalšom vykreslenie objektu titleLB.
HomePage.java
@Override public void setTitleModelObject() { titleModel.setObject(getString("title.homePage")); }
PhotosPage.java
@Override public void setTitleModelObject() { titleModel.setObject(getString("title.photosPage")); }
Teraz sme dosiahli predchádzajúce funkcionality iným spôsobom. Pri vytvorení stránky je nastavený titulok podľa jazykového nastavenia. Aby sa titulok zmenil pri kliknutí na odkaz, je potrebné zmeniť dáta modelu pri kliknutí. To vykonáme v metóde public void onClick () odkazu (zavoláme metódu setTitleModelObject ()).
BasePage.java
add(new Link("en") { @Override public void onClick() { Session.get().setLocale(Locale.ENGLISH); setTitleModelObject(); } }); add(new Link("cs") { @Override public void onClick() { Session.get().setLocale(new Locale("cs")); setTitleModelObject(); } });
Formulár
Formuláre vo wicketu úzko spolupracujú s modelmi = objektmi, ktoré spracúvajú a poskytujú dáta. Wicket nám umožňuje napísať si vlastné modely (ako sme videli v predchádzajúcej časti), ale zároveň pre najčastejšie situácie prichádza s pripravenými modelmi. Práve spracovanie formulárov je častou činnosťou a modely pre prácu s formulárom sú vo Wicektu pripravené.
Pre prácu s formulármi je priamo vytvorený CompoundPropertyModel, ktorý využíva dedičnosti modelov. To znamená, že nemusíme priraďovať model každej komponente vo formulári, ale pridáme model formulári a komponenta, pokiaľ nemá model priradený, sa opýta nadradenej komponenty (napr. Formuláre). Ak ako id komponenty zvolíme názov property ušetríme si veľa písania. Model si odvodí, že daná property sa vzťahuje k danej komponente.
V projekte si vytvoríme nový balík (package) napr. Cz.mujweb.contatpage a v ňom triedu formulára, triedu kontaktné stránky a súbor .html
ContactForm.java
public class ContactForm extends Form { private String email; private String text; public ContactForm(String id) { super(id); System.out.println("form working"); setDefaultModel(new CompoundPropertyModel(this)); add(new TextField("email")); add(new TextArea("text")); } @Override protected void onSubmit() { System.out.println("Zadaný email: " + email); System.out.println("Zadaný text: " + text); } }
Náš formulár obsahuje dve property.
private String email; private String text;
Ďalej formulári nastavíme ako model CompoundPropertyModel. setDefaultModel (new CompoundPropertyModel (this));
Do formulára vložíme dve komponenty. Dáme im id, ktoré zodpovedá názvu danej property vo formulári.
add(new TextField("email")); add(new TextArea("text"));
Nakoniec prekryjeme metódu onSubmit (), ktorá sa vykoná po odoslaní formulára. Zatiaľ nám bude stačiť, že hodnoty property vypíšeme.
@Override protected void onSubmit() { System.out.println("Zadaný email: " + email); System.out.println("Zadaný text: " + text); }
ContactPage.java
public class ContactPage extends BasePage { public ContactPage() { Form form = new ContactForm("form"); add(form); } @Override public void setTitleModelObject() { titleModel.setObject(getString("title.contactPage")); } }
ContactPage.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <wicket:extend> <form wicket:id="form"> <input type="text" wicket:id="email" id="email"/><br/> <textarea wicket:id="text" id="text" cols="40" rows="6"/><br/> <input type="submit" value="Odeslat"/> </form> </wicket:extend> </body> </html>
BasePage.java
Link contactPageLink = new Link("contactPage") { @Override public void onClick() { setResponsePage(ContactPage.class); } }; add(contactPageLink);
BasePage.html
<div id="menu"> <ul> <li><a href="#" wicket:id="homePage"><wicket:message key="menu.homePage"/></a></li> <li><a href="#" wicket:id="photosPage"><wicket:message key="menu.photos"/></a></li> <li><a href="#" wicket:id="contactPage"><wicket:message key="menu.contact"/></a></li> </ul> </div>
WicketApplication_cs.properties
title.contactPage=Kontaktní stránka menu.contact=Kontakt
WicketApplication.properties
title.contactPage=Contact page menu.contact=Contact
Výsledok v konzole po odoslaní formulára.
Zadaný email: [email protected] Zadaný text: Pokusný text.
Stránka s formulárom sa síce zobrazí a je funkčný, ale má ďaleko k dokonalosti. Na stránku pridáme lokalizovaný nadpis, lokalizujeme nápis tlačidlá a pridáme lokalizované popisky ku komponentom.
WicketApplication_cs.properties
text.contact=Kontaktní formulář form.email=Email form.text=Komentář form.submit=Odeslat
WicketApplication.properties
text.contact=Contact form form.email=Email form.text=Comment form.submit=Submit
ContactPage.html
<wicket:extend> <h2><wicket:message key="text.contact"/></h2> <form wicket:id="form"> <input type="text" wicket:id="email" id="email"/><label for="email"><wicket:message key="form.email"/></label><br/> <textarea wicket:id="text" id="text" cols="40" rows="6"/><label for="text"><wicket:message key="form.text"/></label><br/> <input type="submit" wicket:message="value:form.submit"/> </form> </wicket:extend>
style.css
form { padding-top: 5px; padding-bottom: 5px; } form label { padding-left: 5px; } form input { margin-bottom: 5px; margin-top: 5px; }
Pekné, nie? Ale k užitočnosti to má zatiaľ ďaleko - to napravíme v budúcom diele, kde sa pozrieme na prepojenie našej stránky a databázy.