Ajaxを使用してコンポーネントの表示非表示を制御する場合は注意が必要です。
例えば下記のようなコードを書いたとします。 このコードはテキストフィールドに入力されたデータをAjaxを使用して表示しようとしています。
public class ReRenderingPage extends WebPage {
private boolean visible;
public ReRenderingPage() {
Form form = new Form("form");
add(form);
final TextField text = new TextField("text", new Model(""));
form.add(text);
final Label label = new Label("inputData", new Model(""));
add(label);
label.setOutputMarkupId(true);
form.add(new AjaxButton("submit", form) {
@Override
protected void onSubmit(AjaxRequestTarget target, Form form) {
visible = visible?false:true;
label.setModelObject(text.getModelObject());
label.setVisible(visible);
target.addComponent(label);
}
});
}
}
<html xmlns:wicket>
<head>
<title>ReRendering</title>
</head>
<body>
<span wicket:id="inputData"></span>
<form wicket:id="form">
<input type="text" wicket:id="text"/>
<input type="submit" wicket:id="submit" />
</form>
</body>
</html>
上記は一見問題無く動作するように見えます。実際に1度だけであればテキストフィールドに入力されたデータを表示、非表示はされますがそれ以降は表示がされなくなります。これは1度非表示になった場合はinputDataのタグが消えてしまい、サーバー側で表示用のDOMデータをレスポンスで返しても何処に対してデータを差し込めばよいか判断できなくなるためです。Wicket Ajax Debug Windowにも
ERROR: Component with id [[inputData1]] a was not found while trying to perform markup update.とエラー情報が出ます。
このような場合setOutputMarkupPlaceholderTagを使用することで表示、非表示の制御を行うことが出来ます。
final Label label = new Label("inputData", new Model(""));
label.setOutputMarkupId(true);
label.setOutputMarkupPlaceholderTag(true); //ここ重要!テストに出ます!
setOutputMarkupPlaceholderTagを使用することでCSSによる表示、非表示の制御が行われます。上記の場合だと非表示の場合でもHTML上では下記のようになります。
<span style="display: none;" id="inputData1"/>