ひがやすを技術ブログ

電通国際情報サービスのプログラマ

Tapestry入門記(7) Select, Option, Foreach

今回は、前回やったRadioSeasarのドロップダウンバージョンを作ってみます。
最初はSelectSeasar.html


<form jwcid="@Form" listener="ognl:listeners.refresh">
<select jwcid="@Select">
<span jwcid="@Foreach"
source="ognl:@hello.SelectSeasar@SEASARS" value="ognl:seasar">
<option jwcid="@Option"
selected="ognl:optionSelected"
label="ognl:seasar"/>
</span>
<option jwcid="$remove$" value="0" selected="selected">redseasar</option>
<option jwcid="$remove$" value="1">blueseasar</option>
</select>
<input type="submit" value="refresh" />

<img jwcid="selectedImage" src="../images/redseasar.gif" />
</form>
selectタグは特に問題ないでしょう。
次のForeachコンポーネントは初お目見えです。
sourceで配列やListなどのオブジェクトを指定するとループして
ループのたびにvalueで指定したプロパティに値を設定してくれます。
@hello.SelectSeasar@SEASARSは次のような配列です。
public static final String[] SEASARS = {"redseasar", "blueseasar"};
ループのたびにSelectSeasar#setSeasar()が呼び出され、
最初のループでは"redseasar"、次のループでは"blueseasar"がセットされます。
Optionコンポーネントでは、表示のときにループの中で、
SelectSeasar#isOptionSelected()、SelectSeasar#getSeasar()が呼び出され、
更新のときにループの中で、
SelectSeasar#setOptionSelected()、SelectSeasar#setSeasar()が呼び出されます。
更新のときにもループの中でそれぞれにOptionが呼び出されるというところが
ポイントです。前回のRadioでは更新のときに個々のRadioが呼び出されるわけではなく
RadioGroupのselectedプロパティに値は一度設定されるだけでした。
後、jwcidが$remove$のものは実行時には削除されます。
ブラウザでだけでもたときもきちんと表示されるようにつけてあります。
ページ仕様は特に新しいことはありません。

<component id="selectedImage" type="Image">
<binding name="image" expression="selectedImage"/>
</component>
<context-asset name="redseasar" path="images/redseasar.gif" />
<context-asset name="blueseasar" path="images/blueseasar.gif" />
最後はSelectSeasar.javaです。

public class SelectSeasar extends BasePage {

public static final String[] SEASARS =
{"redseasar", "blueseasar"};
private String selectedSeasar_ = SEASARS[0];
private String seasar_;

public String getSeasar() {
return seasar_;
}

public void setSeasar(String seasar) {
System.out.println(seasar);
seasar_ = seasar;
}

public String getSelectedSeasar() {
return selectedSeasar_;
}

public void setSelectedSeasar(String selectedSeasar) {
selectedSeasar_ = selectedSeasar;
}

public boolean isOptionSelected() {
return selectedSeasar_.equals(seasar_);
}

public void setOptionSelected(boolean selected) {
if (selected) {
selectedSeasar_ = seasar_;
}
}

public void refresh(IRequestCycle cycle) {
}

public IAsset getSelectedImage() {
return getAsset(selectedSeasar_);
}
}

ポイントは、setOptionSelected()です。ループの中で呼ばれるので、
選択されたときにだけ、selectedSeasarプロパティに選択された値を設定しています。
selectedSeasarプロパティは選択されたSeasarを格納するプロパティ、
seasarプロパティは、ループの中で設定される一時的なプロパティです。