Formulářové komponenty
V tomto díle tipů a triků pro framework Wicket se podíváme na formulářové komponenty:
- TextField, v html
<input type="text"/>
- PasswordTextField, v html
<input type="password"/>
- TextArea, v html
<textarea></textarea>
- RadioGroup a Radio, v html
<input type="radio"/>
- DropDownChoice, v html
<select></select>
- CheckBox, v html
<input type="checkbox"/>
Formulářové komponenty
Ukážeme si použití výše uvedených komponent v jednoduchém formuláři, to jak z nich získat uživatelem zadaná data, jak nastavit viditelnost určité komponenty a jak tuto viditelnost měnit pomocí Ajaxu na základě události.
Pro hezčí zobrazení formuláře budeme v této lekci používat následující soubor stylů.
.css
body { width: 500px; margin-left: auto; margin-right: auto; font-size: larger; } form { border: 1px solid black; padding: 5px; } select,input[type=submit],label { margin: 5px 10px; padding: 5px 10px; } label { width: 200px; display: inline-block; } .bold { font-weight: bold; } .feedback { color: red; margin: 10px 0; padding: 5px; }
Nejdříve si vytvoříme jednoduchý formulář, který bude obsahovat pouze tlačítko pro odeslání.
.java
FeedbackPanel feedback = new FeedbackPanel("feedback"); add(feedback); Form form = new Form("form") { @Override protected void onSubmit() { System.out.println("Form submitted"); } }; add(form); Button submit = new Button("submit"); form.add(submit);
.html
<div wicket:id="feedback" class="feedback"></div> <form wicket:id="form"> <input wicket:id="submit" type="submit" value="Submit" /> </form>
Vytvořili jsme formulář, s tlačítkem pro odeslání a také jsme do stránky přidali panel (FeedbackPanel) pro zobrazení výstupu případných informací, týkajících se validace komponent.

Po stisknutí tlačítka by se do konzole měl vypsat text ("Form submitted"), který je definován v metodě:
@Override protected void onSubmit() { System.out.println("Form submitted"); }
Ta se provede při každém odeslání formuláře.
Ve formuláři budeme chtít získat od uživatele:
- uživatelské jméno (povinné)
- heslo (povinné)
- nějaký text (povinné)
- údaj o jeho/jejím pohlaví
- údaje navázané na zvolené pohlaví (od muže počet let vojenské služby, od ženy počet dětí)
- zda souhlasí s podmínkami
My pro práci s daty budeme používat PropertyModel. Ve spojení s formuláři se ve Wicketu velmi často též používá CompoundPropertyModel. Zmínku o tomto modelu nalezente v tomto dílu tutoriálu.
Přidání proměnných, ve kterých bude uložen vstup od uživatele.
.java
private String text; private String username; private String password; private String gender; private Integer service; private Integer children; private Boolean agree;
TextField, PasswordTextField, TextArea
Formulář budeme vytvářet postupně. Nejdříve přidáme komponenty pro zadání uživatelského jména, hesla a textu.
.java
TextField usernameTF = new TextField("username", new PropertyModel<String>(this, "username")); usernameTF.setRequired(true); form.add(usernameTF); PasswordTextField passwordTF = new PasswordTextField("password", new PropertyModel<String>(this, "password")); form.add(passwordTF); TextArea textTA = new TextArea("text", new PropertyModel<String>(this, "text")); textTA.setRequired(true); form.add(textTA);
.html
<label for="tf">Uživalské jméno *</label><input type="text" wicket:id="username" id="tf" /><br/> <label for="passwd">Heslo *</label><input type="password" wicket:id="password" /><br/> <label for="ta">Text *</label><textarea wicket:id="text" id="ta" rows="4" cols="20"></textarea><br/>

Nastavení povinnosti komponent (vstup od uživatele bude povinný).
usernameTF.setRequired(true); textTA.setRequired(true);
Komponenta PasswordTextField je povinná defaultně.
Všimněte si, že každá komponenta má kromě id též PropertyModel, který má jako parametr this (tato WebPage) a textový řetězec, který odpovídá názvu proměnné:
new PropertyModel<String>(this, "username")
načítá a ukládá data do:
private String username;
U ostatních je to obdobné.
DropDownChoice
Nyní vytvoříme WebMarkupContainer, což je komponenta - kontejner pro další komponenty. Rozdíl mezi WebMarkupContainer a Panel je ten, že panel má vlastní soubor .html, kdežto WebMarkupContainer ne. Panel se proto používá pro vytvoření složitějších a komplexnějších částí.
Do kontejneru umístíme dvě komponenty DropDownChoice (v html se jedná o select) pro výběry (počet let vojenské služby, počet dětí). Každá z těchto komponent bude mít přidělen model, který jí bude poskytovat data pro zobrazení a PropertyModel, který bude uchovávat vstup od uživatele.
.java
// Model for serviceDDCH IModel<List<Integer>> serviceModel = new AbstractReadOnlyModel<List<Integer>>() { @Override public List<Integer> getObject() { return Arrays.asList(0, 1, 2); } }; DropDownChoice serviceDDCH = new DropDownChoice("service", new PropertyModel<Integer>(this, "service"), serviceModel) { @Override protected void onConfigure() { setVisible(gender != null && gender.equals("man")); } }; // Model for childrenDDCH IModel<List<Integer>> childrenModel = new AbstractReadOnlyModel<List<Integer>>() { @Override public List<Integer> getObject() { return Arrays.asList(0, 1, 2, 3, 4, 5, 6 ,7 , 8, 9, 10); } }; DropDownChoice childrenDDCH = new DropDownChoice("children", new PropertyModel<Integer>(this, "children"), childrenModel) { @Override protected void onConfigure() { setVisible(gender != null && gender.equals("woman")); } }; // Container that contains drop down choices final WebMarkupContainer container = new WebMarkupContainer("container"); container.add(serviceDDCH); container.add(childrenDDCH); container.setOutputMarkupId(true); form.add(container);
.html
<div wicket:id="container"> <select wicket:id="service"></select> <select wicket:id="children"></select> </div>
Vysvětlení:
IModel<List<Integer>> serviceModel = new AbstractReadOnlyModel<List<Integer>>() { @Override public List<Integer> getObject() { return Arrays.asList(0, 1, 2); } };
Vytvoří model, který bude vracet seznam čísel (0, 1, 2), a který potom bude používat komponenta serviceDDCH (viz níže).
PropertyModel<Integer>(this, "service")
Načítá a ukládá data (getObject(), setObject()) do
private String service
.
DropDownChoice serviceDDCH = new DropDownChoice(…) { @Override protected void onConfigure() { setVisible(gender != null && gender.equals("man")); } };
Vytvoří komponentu DropDownChoice a zároveň přetíží její metodu:
protected void onConfigure()
Nastavujeme viditelnost komponenty:
setVisible(gender != null && gender.equals("man"));
V případě, že hodnota proměnné gender bude not null a zároveň se hodnota této proměnné bude rovnat "man", komponenta bude viditelná.
container.add(serviceDDCH); container.add(childrenDDCH); container.setOutputMarkupId(true);
Přidává do kontejneru komponenty serviceDDCH a childrenDDCH a kontejneru nastavuje outputMarkupId na true (to je potřeba v případě, že budeme chtít aktualizovat komponentu pomocí Ajaxu - v případě Wicketu to znamená, že jí přidělíme behavior).
Pokud si nyní zobrazíte stránku, nic se oproti předchozí verzi nezměnilo. Proměnná gender má hodnotu null, takže ani jedna z komponent DropDownChoice není viditelná.
V přístím dílu tipů a triků tento formulář dokončíme.