Aleš Woska
8.1.2015

Tvorba formulářů pomocí Apache Wicket



Poslední dobou působí AspectWorks na čím dál více projektech, které využívají framework Wicket. Tento příspěvek pokrývá úplné základy možností tvorby webových formulářů ve Wicketu. To vše pomocí ukázek kódu a formou blízkou tutorialu.

1. Zakomponování frameworku do projektu

Projekt musí obsahovat třídu poděděnou od Wicket třídy WebApplication – té se říká Application object. Tato třída musí přepsat metodu getHomePage(), která vrací název třídy ovládající homepage.

import org.apache.wicket.protocol.http.WebApplication;

public class SimpleWicketApplication extends WebApplication {
  public HelloWorldApplication() {} 
  @Override public Class getHomePage() { return SimpleWicketPage.class; } 
} 

 Ještě musíme aplikaci definovat v souboru web.xml, jak jsem uvedl v příkladu:

<web-app>
  <display-name>Wicket Examples</display-name>
  <filter>
    <filter-name>SimpleWicketApplication</filter-name>
    <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
    <init-param>
      <param-name>applicationClassName</param-name>
      <param-value>com.aspectworks.examples.SimpleWicketAppliacation</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>SimpleWicketApplication</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

 

2. Vytvoření jednoduché stránky

Pro jednoduchost zatím vytvoříme stránku pouze s jedním textovým prvkem. Třída ovládající stránku musí být poděděna od Wicket třídy WebPage. Nový prvek na stránku vložíme jednoduše zavoláním metody add().

import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;

public class SimpleWicketPage extends WebPage {
  public SimpleWicketPage () {
    add(new Label("message", "Hello World!")); 
  }
} 

Metodě add jsme předali objekt typu Label, jehož konstruktor přijímá dva argumenty – první je název prvku, druhý je obsah, v tomto případě to bude text prvku na stránce. Ve stejném package, jako se nachází třída stránky musí být umístěn soubor šablony. Ten se musí jmenovat stejně jako třída, s příponou html. Tento soubor popisuje, jak má vypadat HTML stránka dané třídy.

<html>
  <body>
    <span wicket:id="message"></span>
  </body>
</html>

Šablona obsahuje pouze jeden Span prvek. Přidáme mu atribut s názvem wicket:id, který identifikuje název prvku definovaný ve třídě. V tomto případě to bude „message“, protože ve třídě SimpleWicketPage jsme na stránku přidali objekt typu Label s tímto identifikátorem. Na stránce wicket vyrenderuje hodnotu „Hello World!“. Tímto jsme vytvořili jednoduchý Wicket projekt se statickou stránkou, nyní ukážu, jak vytvořit a zpracovat formulář.

3. Vytvoření formuláře

Vytvoříme jednoduchý formulář, který do seznamu vozidel přidá nové. Vozidlo bude obsahovat SPZ  a rok výroby. Nejprve vytvoříme POJO pro vozidlo:

public class Vehicle {
  private String spz;
  private Integer year;

  public Vehicle() {} 
  public String getSpz() {return spz; } 
  public void setSpz(String spz) { this.spz = spz; } 
  public Integer getYear() { return year; } 
  public void setModel(Integer year) { this.year = year; } 
  public String toString() { return "Vehicle " + model + " manufactured in " + year; }
} 

Když máme definované POJO, můžeme formulář pro tuto třídu. To uděláme vytvořením nové třídy poděděné od Wicket třídy Form. Jako typ předáme ValueMap, která uchovává dvojice klíč-hodnota, což je pro tento formulář dostačující:

public final class VehicleForm extends Form<ValueMap> {
  private VehiclePage page;
  
  public VehicleForm(final String id, VehiclePage page) {
    // Vytvorime formular pro seznam prvku 
    super(id, new CompoundPropertyModel<ValueMap>(new ValueMap()));
    // Ulozime si referenci na stranku obsahujici formulat
    this.page = page;
    // textove pole pro SPZ 
    add(new TextField<String>("spz").setType(String.class)); 
    /* Textove pole pro rok vyroby. Nemuzeme vytvořit prvek pro jednoduche datove typy, pouze pro objektove. */
    add(new TextField<Integer>("year").setType(Integer.class)); 
  } 
  
  /** 
   * Prepiseme metodu onSubmit, která zpracuje odeslani formulare 
   */ 
   @Override public final void onSubmit() { 
      // ziskame objekt se zadanymi udaji 
      ValueMap values = getModelObject();
      // Vytvorime objekt z udaju z formulare
      Vehicle vehicle = new Vehicle();
      vehicle.setSpz((String)values.get("spz"));
      vehicle.setYear((Integer)values.get("year"));
      /* Pridame nove vozidlo do seznamu. Porusuje to sice pravidla MVC (page je view), ale takto to uvadim pro jednoduchost. */ 
      page.addVehicle(vehicle); 
  }
} 

 Zbývá vytvořit stránku obsahující formulář:

public final class VehiclePage extends WebPage {
  // seznam vozidel 
  private List<Vehicle> vehicleList = new ArrayList<Vehicle>();
  
  public void addVehicle(Vehicle vehicle) { vehicleList.add(vehicle); }
  public VehiclePage() {
    // Pridame formular pro vozidlo. Argument je wicket identifikator prvku. 
    add(new VehicleForm("vehicleForm"));
    // Pridame seznam vozidel na stranku 
    add(new PropertyListView<Vehicle>("vehicles", vehicleList) {
      @Override public void populateItem(final ListItem<Vehicle> listItem) {
        listItem.add(new Label("spz"));
        listItem.add(new Label("year"));
      }
    });
  }
}

 Pro tuto stránku musíme definovat šablonu:

<form wicket:id="vehicleForm">
  Add new vehicle:
  <br />
  SPZ: <input type="text" wicket:id="spz" /> 
  Year: <input type="text" wicket:id="year" /> 
  <input type="submit" value="Submit" /> 
</form>
<span wicket:id="vehicles"></span>

Wicket přiřadí formulář VehicleForm k HTML prvku s atributem wicket:id=“vehicleForm“ (opět porovnává textové identifikátory), jednotlivá pole formuláře také přiřadí dle identifikátorů (spz a year). Seznam vozidel přiřadí Span prvku s identifikátorem „vehicles“. Podobně jako předchozím příkladu musíme ještě dopsat Application object a popsat jej v souboru pom.xml. Wicket podporuje navíc například validátory, další typy polí a možnost vícejazyčných textů, ale o tom až v dalším příspěvku.

Vaše emailová adresa nebude zveřejněna

Komentáře

Děkujeme za váš komentář
Další
  • Anonym

    Zkuste si tu stranku zobrazit na ipadu

  • mna by zaujimal dovod vyuzivania wicket-u oproti takemu jsf. pokial firma ma ludi ovladajuci dobre nejaky framework tak preco prechadzat na iny? ak by ste zmenili strategiu a presli by ste na nove js frameworky, alebo by ste presli na scalu a zaroven by ste menili takmer cely stack technologii tak to pochopim ale preco teraz prechadzat na wicket? predpokladam, ze ako firma mate dlhorocne skusenosti s jsf (rozne verzie) + rozne nadstavby/rozsirenia k tomu

  • Robert Novotny

    Vďaka za článok! Je však ValueMap naozaj potrebný? Nedalo by sa bindovať rovno na inštanciu Vehiclu? Ušetrilo by sa presýpanie dát z beanu do beanu.

  • Anonym

    @tutor ako (konzervativny) manazer zdielam tvoj nazor, avsak vzhladom na to, ako su ludia nadseni z prace s wicketom, rozhodnutie "skusit ho" nepokladam za zle ;-)