Ajaxを使用してコンポーネントの表示非表示を制御する場合は注意が必要です。

例えば下記のようなコードを書いたとします。 このコードはテキストフィールドに入力されたデータをAjaxを使用して表示しようとしています。

  1. public class ReRenderingPage extends WebPage {
  2. private boolean visible;
  3. public ReRenderingPage() {
  4. Form form = new Form("form");
  5. add(form);
  6. final TextField text = new TextField("text", new Model(""));
  7. form.add(text);
  8. final Label label = new Label("inputData", new Model(""));
  9. add(label);
  10. label.setOutputMarkupId(true);
  11. form.add(new AjaxButton("submit", form) {
  12. @Override
  13. protected void onSubmit(AjaxRequestTarget target, Form form) {
  14. visible = visible?false:true;
  15. label.setModelObject(text.getModelObject());
  16. label.setVisible(visible);
  17. target.addComponent(label);
  18. }
  19. });
  20. }
  21. }
  1. <html xmlns:wicket>
  2. <head>
  3. <title>ReRendering</title>
  4. </head>
  5. <body>
  6. <span wicket:id="inputData"></span>
  7. <form wicket:id="form">
  8. <input type="text" wicket:id="text"/>
  9. <input type="submit" wicket:id="submit" />
  10. </form>
  11. </body>
  12. </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を使用することで表示、非表示の制御を行うことが出来ます。

  1. final Label label = new Label("inputData", new Model(""));
  2. label.setOutputMarkupId(true);
  3. label.setOutputMarkupPlaceholderTag(true); //ここ重要!テストに出ます!
setOutputMarkupPlaceholderTagを使用することでCSSによる表示、非表示の制御が行われます。上記の場合だと非表示の場合でもHTML上では下記のようになります。
  1. <span style="display: none;" id="inputData1"/>