wicket:enclosureというタグがイイ感じっぽい

AjaxFallbackDefaultDataTableを詳しく調べてみようと思いWicketのソースを眺めてたら見たことないタグを発見。

<wicket:enclosure>

こいつは何者なのかと思い調べるとhttp://cwiki.apache.org/WICKET/wickets-xhtml-tags.htmlに載ってました。
どうやら上記タグにて囲った部分に関してまるごと表示、非表示の制御ができる模様。

例えば下記のようなPageクラスとHtmlを作成するとします。

<html>
    <head>
    </head>
    <body>
        <h1>Hogeページです。</h1>
        <wicket:enclosure>
            <h2>サブタイトルです。</h2>
            <span wicket:id="data"></span>
        </wicket:enclosure>
    </body>
</html>
public class FooPage extends WebPage {
    public FooPage() {
        add(new Label("data", "こんにちは").setVisible(false));
    }
}

これで実行するとh1の部分だけ表示されて、h2の部分は表示されなくなります。
このwicket:enclosure内にあるWicketコンポーネントが表示可能(Component#isVisible == true)であればそのまま表示し、そうでない場合(Component#isVisible == false)は囲まれた部分を丸ごと非表示にしてくれます。

これを使わずに同じ動作をするプログラムを書く場合は、上記の場合だとh2にwicket:idを付け、FooPageのコンストラクタ内にてWebMarkupContainerをaddし、表示非表示の制御を書かなければなりません。それをwicket:enclosureは勝手に判断してくれる優れもの!このこデキる子!

ちなみにwicket:enclosureにて囲った中に複数のコンポーネントがある場合はchildという要素を指定し、そのコンポーネントが表示可能かどうかで全体の表示非表示を制御できるようです。例えばこんな感じ

<html>
    <head>
    </head>
    <body>
        <h1>Hogeページです。</h1>
        <!-- childという要素にてwicket:idを指定 -->
        <wicket:enclosure child="data">
            <h2>サブタイトルです。</h2>
            <h2>もう1つサブタイトルです。</h2>
            <span wicket:id="data"></span>
            <span wicket:id="data2"></span>
        </wicket:enclosure>
    </body>
</html>
public class FooPage extends WebPage {

    public FooPage() {
        add(new Label("data", "こんにちは").setVisible(false));
        add(new Label("data2", "こんにちは2"));
    }
}

また、例えばListViewを使用して検索結果の一覧を表示させるような場合でも、ListViewで指定するのはあくまで繰り返しの部分のみであり、 TABLEのヘッダー部分は検索結果が0件の場合でもそのまま表示されてしまいます。0件の場合にはヘッダー部分を表示させないみたいなことするには前述の通りWebMarkupContainerをヘッダー部分に設定し(ry というような処理が必要ですが下記のようにすれば楽に非表示にできます。

public class FooPage extends WebPage {

    public FooPage() {
    List<String> emptyList = Collections.emptyList();
        ListView<String> view = new ListView<String>("nameList", emptyList) {
            @Override
            protected void populateItem(ListItem<String> item) {
                item.add(new Label("name",item.getModelObject()));
            }

            @Override
            public boolean isVisible() {
                return !getList().isEmpty();
            }
        };
        add(view);
    }
}
<html>
    <head>
    </head>
    <body>
        <h1>Hogeページです。</h1>
        <!-- childという要素にてwicket:idを指定 -->
        <wicket:enclosure child="nameList">
            <table>
                <thead>
                    <tr>
                        <th>Name</th>
                    </tr>
                </thead>
                <tbody>
                    <tr wicket:id="nameList">
                        <td><span wicket:id="name"></span></td>
                    </tr>
                </tbody>
            </table>
        </wicket:enclosure>
    </body>
</html>

まぁ、頻繁に使うようなものではないでしょうが、覚えておいて損はないかなと思いメモとして残してみました。例によって間違ってる箇所等ありましたらご指摘お願いします。