| まえがき セットアップ サンプル解説 hello.html add.html forEachList.html forEachResult.html forEach2List.html converter.html validator.html checkbox.html selectOneMenu.html ## まえがき JSPを使っていて、ちょっとレイアウトを確認したいだけなのに、いちいちアプリケーションサーバを立ち上げて、デ プロイしないといけないことに、苛立ちを覚えたことはありませんか。デザイナとの連携に苦労したことはないでしょう か｡S2JSFを使うと、ViewのテンプレートをHTMLで記述できるようになります。もうJSPに悩まされる必要はなくなるのです ｡ ## セットアップ Seasar2と同様にJDK1.4以上が必要です。S2JSFVx.x.x.zipを解凍してできたs2jsfディレクトリをEclipseで、 ｢ファイル→インポート→既存のプロジェクトをワークスペースへ｣でインポートしてください。 サンプルはS2JSFExamleVx.x.x.jarとして別途用意されているので、ダウンロードして解凍してください。先程と同様 に、Eclipseで、｢ファイル→インポート→既存のプロジェクトをワークスペースへ｣でインポートします。サンプルは、Tomcat5、Tomcat Pluginを使うことを前提にしています。もし、 まだインストールしていない場合は、インストールしておいてください。 Tomcatを起動し、ブラウザでhttp://localhost:8080/s2jsf-exampleにアクセスすると、S2JSFのサンプルを見ることが 出来ます。 ## サンプル解説 ### hello.html ブラウザで、http://localhost:8080/s2jsf-example/hello/hello.html?message=aaaにアクセスしてみましょう。 Hello aaaと表示されるはずです｡このサンプルでは、次のことを学びます｡ S2JSF用の名前空間の宣言。 レイアウト機能。 taglibの利用方法｡ inject属性によるタグの指定。 titleタグの使い方。 リンクでページ遷移する方法｡ ページ遷移のときにパラメータを渡す方法｡ navigation-ruleの記述方法｡ ValueBindingを使って文字列を出力する方法｡ それでは、HTMLの中身を見てみましょう｡
    01:<html xmlns:m="http://www.seasar.org/maya" m:extends="/WEB-INF/layout/layout.html">
    02:<head>
    03:<meta http-equiv="Content-Type" content="text/html; charset=Windows-31j" />
    04:<title>Hello</title>
    05:</head>
    06:<body>
    07:    <span m:inject="f:param" m:name="layoutTitle" m:value="Hello"/>
    08:    <span m:inject="s:insert" m:name="body">
    09:        Hello <span m:value="#{message}">hoge</span>
    10:    </span>
    11:</body>
    12:</html>
1行目のxmlns:m="http://www.seasar.org/maya"で名前空間を指定しています｡この URI(http://www.seasar.org/maya)は固定です｡プレフィックスのmは任意の値を指定することが出来ますが、慣例的にmを 使うことになっています｡ 次のextends属性で、継承するレイアウトを指定しています｡一貫したLook & Feelを提供するために、ページのレ イアウトが、ヘッダー、メニュー、ボディ、フッターで構成され、個別のページはボディ部分だけが異なるというのは、 よく見かけるパターンではないでしょうか｡このようなニーズにこたえるために、S2JSFでは、ベースになるページでレイ アウトを定義し、個別のページでは、ベースとなるページを継承して特定の部分(例えばボディ)だけを上書きするという ことが可能になっています｡それでは、layout.htmlを見てみましょう｡
    01:<html xmlns:m="http://www.seasar.org/maya">
    02:<head>
    03:<meta http-equiv="Content-Type" content="text/html; charset=Windows-31j" />
    04:<link m:inject="s:link" rel="stylesheet" type="text/css" href="/css/global.css"/>
    05:<title m:value="#{layoutTitle}"/>
    06:</head>
    07:<body>
    08:<table border="0" cellspacing="5">
    09:<tr>
    10:  <td colspan="2"><span m:inject="s:insert" m:src="/WEB-INF/layout/header.html"/></td>
    11:</tr>
    12:<tr>
    13:  <td width="140" valign="top">
    14:    <span m:inject="s:insert" m:src="/WEB-INF/layout/menu.html"/>
    15:  </td>
    16:  <td valign="top" align="left">
    17:    <span m:inject="s:insert" m:name="body"/>
    18:  </td>
    19:</tr>
    20:<tr>
    21:  <td colspan="2">
    22:    <hr/>
    23:  </td>
    24:</tr>
    25:<tr>
    26: <td colspan="2">
    27:    <span m:inject="s:insert" m:src="/WEB-INF/layout/footer.html"/>
    28:  </td>
    29:</tr>
    30:</table>
    31:</body>
    32:</html>
4行目のlinkタグを見てください｡inject属性でs:linkというタグ名を指定しています｡このタグ名の記述の仕方は、JSP の場合と一緒です｡sというプレフィックスは、WEB-INF/classes(WEB-INF/src)のjsf.diconに記述されています｡jsf.dicon の該当部分は次のようになります｡
    <component class="org.seasar.jsf.runtime.JsfConfigImpl">
        <initMethod name="addTaglibUri">
            <arg>"h"</arg>
            <arg>"http://java.sun.com/jsf/html"</arg>
        <initMethod>
        <initMethod name="addTaglibUri">
            <arg>"f"</arg>
            <arg>"http://java.sun.com/jsf/core"</arg>
        <initMethod>
        <initMethod name="addTaglibUri">
            <arg>"s"</arg>
            <arg>"http://www.seasar.org/jsf"</arg>
        </initMethod>
    </component>
inject属性を指定することで、任意のHTMLのタグを任意のJSF用のJSPのタグに変換できます｡既存のJSF用のtaglibがそ のまま再利用できるのです｡ 5行目でtitleを指定しています｡layoutTitleの実際の値は、このレイアウトを継承したページで指定します｡ 10行目のinsertタグのsrc属性でヘッダー用のページを挿入しています｡ヘッダー用のページは次のようになっています ｡
    <html xmlns:m="http://www.seasar.org/maya">
    <body>
        <span m:inject="s:insert">
            <img m:inject="h:graphicImage" m:url="/images/seasar.gif"/>
        </span>
    </body>
    </html>
挿入されるページでは、name属性のないinsertタグの中に挿入したい内容を記述します｡insertタグの外側にプレビュ ー用にタグを書くことも出来ます｡その場合、実行時には、insertタグの外側は無視されます｡次は、menu.htmlを見てみましょう｡
    <html xmlns:m="http://www.seasar.org/maya">
    ...
    <body>
        <span m:inject="s:insert">
            <form>
                <ul>
                    <li>
                        <a m:action="hello">Hello
                            <span m:inject="f:param" m:name="message" m:value="World"/>
                        </a>
                    </li>
                    <li>
                        <a m:action="add">Add</a>
                    </li>
                    ...
                </ul>
            </form>
        </span>
    </body>
    </html>
anchorタグのaction属性でリンクをクリックしたときに、遷移するページ名を指定します｡action属性は、${変数名.メソッド名}という形式で、JavaBeansのメソッドを呼び出すことも出来ますが、単に文字列を指定した場合は、指定したページに遷移するという意味になります｡このhelloというページ名はWEB-INF/faces-config.xmlで設定されています｡それでは、該当個所を見ていましょう｡
    <navigation-rule>
        <navigation-case>
            <from-outcome>hello</from-outcome>
            <to-view-id>/hello/hello.html</to-view-id>
            <redirect/>
        </navigation-case>
    </navigation-rule>
from-outcomeでページ名(遷移先名)を指定します｡to-view-idで指定するのが、実際のパスです｡redirectタグを書くとリダイレクト、書かないとフォワードされることになります｡menu.htmlの説明に戻ります｡ anchorタグの子タグでf:paramタグを指定することにより、遷移先のページへパラメータを渡すことが出来ます｡layout.htmlの説明に戻ります｡ 17行目の<span m:inject="s:insert" m:name="body"/>でボディ部分を定義しています｡こ のようにname属性で名前を付けておくと、このレイアウトを継承したページで同じように<span m:inject="s:insert" m:name="body">...,</span>を定義することで、親のページの内容 を上書きすることが出来ます｡それでは、hello.htmlの説明に戻ります｡ 7行目の<span m:inject="f:param" m:name="layoutTitle" m:value="Hello"/> でlayout.htmlで定義したlayoutTitleの値を設定しています｡親のページにパラメータを渡すには、このようにbodyタグの 子タグとしてf:paramタグを記述します｡ 8行目から10行目の<span m:inject="s:insert" m:name="body">で、親ページで定義した 内容を上書きします｡ 9行目の<span m:value="#{message}">hoge</span>でHTMLに文字列を出力します｡#{...}の記述 は、ValueBindingと呼ばれ、動的に値を変える場合に使います｡#{変数名}のように指定した場合は、リクエストの属性、 パラメータ、セッションの属性、S2Containerの順番で検索し、最初に見つかった値を設定します｡#{変数名.プロパティ名 }のように指定した場合は、先程と同様に変数名を解決し、その変数のプロパティの値を設定します｡この例では、リクエ ストのmessageパラメータの内容が出力されることになります｡ボディのhogeは実行時には無視されます｡ブラウザで直接プ レビューするときにレイアウトを確認しやすくするためのダミーデータになります｡HTMLに出力される文字列を動的に変え たい場合は、このようにspanタグのvalue属性で指定します｡ ### add.html このサンプルでは、次のことを学びます｡ 入力値をJavaBeansのプロパティと連動させる方法。 ボタンをクリックしたときにJavaBeansのメソッドを呼び出す方法。 Actionにsetterメソッドを定義してリクエスト、セッション、S2Containerのオブジェクトをプロパティに自動設定する方法。 それでは、HTMLの中身を見てみましょう｡
    01:<html xmlns:m="http://www.seasar.org/maya" m:extends="/WEB-INF/layout/layout.html">
    02:<head>
    03:<meta http-equiv="Content-Type" content="text/html; charset=Windows-31j" />
    04:<title>Add</title>
    05:</head>
    06:<body>
    07:  <span m:inject="f:param" m:name="layoutTitle" m:value="Add"/>
    08:  <span m:inject="s:insert" m:name="body">
    09:    <form>
    10:      <span m:inject="h:messages" m:globalOnly="false" m:showDetail="true"/>
    11:      <input type="text" m:value="#{addDto.arg1}"/> +
    12:      <input type="text" m:value="#{addDto.arg2}"/> =
    13:      <span m:value="#{addDto.result}"/>
    14:      <input type="submit" value="calculate" m:action="#{addAction.calculate}"/>
    15:    </form>
    16:  </span>
    17:</body>
    18:</html>
headタグの部分は、実行時には無視されます｡ブラウザでのプレビュー用です｡ 10行目の<span m:inject="h:messages" m:globalOnly="false" m:showDetail="true"/>で、エラーが起きたときのメッセージを出力する準備をしています｡globalOnly属性がtrueの場合、個別の入力項目には関係のない(globalな)エラーのメッセージだけが出力されます｡falseにするとglobalなメッセージも個別のメッセージも出力するようになります。 11行目の<input type="text" m:value="#{addDto.arg1}"/>で、入出力用のタグとJavaBeansのプロパティを連動させています｡入力した値は、バリデーションがOKなら、JavaBeansのプロパティに格納され、NGの場合は、入力された値がそのままページに表示されることになります｡このように入出力値の管理をきちんと行ってくれるところが、JSFの偉いところです｡StrutsのようにActionFormでとりあえずStringで受け取るなんて事をする必要がないのです｡ addDtoはどこで定義されているのでしょうか｡addDtoは、examples/jsf/dicon/add.diconの中で、次のように定義されています｡
    <component name="addDto" class="examples.jsf.dto.AddDto" instance="request"/>
instance属性がrequestになっているので、addDtoはrequestのスコープで管理されることになります｡また、add.diconは、ルートの定義であるapp.diconから次のようにincludeされています。
    <include path="examples/jsf/dicon/add.dicon"/>
14行目の<input type="submit" value="calculate" m:action="#{addAction.calculate}"/>で、ボタンがクリックされたときにJavaBeansのメソッドを呼び出す設定をしています｡ボタンやリンクのaction属性で、#{変数名.メソッド名}のように記述することをMethodBindingと呼びます｡MethodBindingで呼び出されるメソッドは、引数がなく、戻り値がStringでなければいけません｡addActionはadd.diconで次のように定義されています｡
    <component name="addAction" class="examples.jsf.action.impl.AddActionImpl" instance="request"/>
Actionクラスは、入力された内容をプロパティ経由で受け取ることになるので、instance属性をrequestにします。それでは、AddActionインターフェース、AddActionImplクラスを見てみましょう｡インターフェースと実装を必ず分離しなければならないということはないのですが、このように分離したほうが、仕様が明確に伝わり易いと思います｡
    package examples.jsf.action;

    public interface AddAction {

        public String calculate();
    }
    package examples.jsf.action.impl;

    import examples.jsf.action.AddAction;
    import examples.jsf.dto.AddDto;
    import examples.jsf.logic.AddLogic;

    public class AddActionImpl implements AddAction {

        private AddDto addDto;
        private AddLogic addLogic;

        public void setAddDto(AddDto addDto) {
            this.addDto = addDto;
        }

        public void setAddLogic(AddLogic addLogic) {
            this.addLogic = addLogic;
        }

        public String calculate() {
            int result = addLogic.calculate(addDto);
            addDto.setResult(result);
            return null;
        }
    }
入力された値を受け取るために、addDtoというプロパティのsetterメソッドを定義しています｡S2JSFは、MethodBindingで指定したメソッドを呼び出す直前にsetterメソッドの定義されているプロパティがないか調べ、もしある場合は、プロパティ名と同様の変数が、リクエストの属性、パラメータ、セッションの属性、S2Containerに存在するか調べ、もし存在する場合には、自動的にsetterメソッドを呼び出し、その変数を設定します｡ addLogicという変数は、どこにも定義されていないのですが、プロパティの型がインターフェースの場合、S2Containerによって、そのインターフェースを実装したクラスが自動的に設定されます｡AddLogicを実装したクラスは、add.diconで次のように定義されています｡
    <component class="examples.jsf.logic.impl.AddLogicImpl"/>
MethodBindingで呼び出したメソッドの戻り値がnullの場合は、自分自身に遷移することになります｡ ### forEachList.html このサンプルでは、次のことを学びます｡ forEachタグによる繰り返し。 anchorタグでプレビュー時にページ遷移させる方法。 buttonrタグでプレビュー時にページ遷移させる方法。 それでは、HTMLの一部を見てみましょう｡
    01:<form>
    02:    <table border="1">
    03:        <tr bgcolor="#7777FF">
    04:            <th>Key</th>
    05:            <th>Name</th>
    06:            <th colspan="2">to ResultPage</th>
    07:        </tr>
    08:        <span m:inject="s:forEach" m:items="#{forEachDtoList}"
    09:            m:var="e" m:varIndex="i">
    10:        <tr>
    11:            <td><span m:value="#{e.key}">111</span></td>
    12:            <td><span m:value="#{e.name}">aaa</span></td>
    13:            <td><a href="forEachResult.html" m:action="forEachResult">to ResultPage
    14:                    <span m:inject="f:param" m:name="index" m:value="#{i}"/>
    15:                </a>
    16:            </td>
    17:            <td>
    18:                <input type="button" m:action="forEachResult" value="to ResultPage"
    19:                    onclick="location.href='forEachResult.html'">
    20:                    <span m:inject="f:param" m:name="index" m:value="#{i}"/>
    21:                </input>
    22:            </td>
    23:        </tr>
    24:        </span>
    25:    </table>
    26:</form>
8行目のforEachタグで繰り返しを指定します｡items属性で繰り返す対象を、var属性で繰り返す際に個々の要素にアクセスするときの名前を、varIndex属性で繰り返す際にインデックスにアクセスするときの名前を指定します｡ 11行目のようにvar属性でつけた名前.プロパティという形でアクセスすることが出来ます｡ 13行目のanchorタグでhref属性とaction属性を両方指定しています｡このように両方指定した場合、hrefは実行時には無視されます｡ブラウザで直接プレビューしたときに、ページを遷移させるために記述しているのです｡子タグのparamタグでページ遷移のときのパラメータを指定することができます｡ 18行目のbuttonタグもaction属性とonclick属性を指定しています｡onclick属性のlocation.href='forEachResult.html'の部分は実行時には無視されます｡ブラウザで直接プレビューしたときに、ページを遷移させるために記述しているのです｡子タグのparamタグでページ遷移のときのパラメータを指定することができます｡ ### forEachResult.html このサンプルでは、次のことを学びます｡ ページの初期処理。 Actionにgetterメソッドを定義してプロパティをリクエストやセッションに自動設定する方法。 それでは、HTMLを見てみましょう｡
    01:<html xmlns:m="http://www.seasar.org/maya"
    02:    m:action="#{forEachResultInitAction.initialize}"
    03:    m:extends="/WEB-INF/layout/layout.html">
    04:<head>
    05:<meta http-equiv="Content-Type" content="text/html; charset=Windows-31j" />
    06:<title>ForEach</title>
    07:</head>
    08:<body>
    09:<span m:inject="f:param" m:name="layoutTitle" m:value="ForEach"/>
    10:<span m:inject="s:insert" m:name="body">
    11:     Key:<span m:value="#{forEachDto.key}">111</span>
    12:     Name:<span m:value="#{forEachDto.name}">aaa</span><br />
    13:     <a href="forEachList.html">previous</a>
    14:</span>
    15:</body>
    16:</html>
2行目のhtmlタグのaction属性で、ページを初期化するメソッドを指定しています｡それでは、Actionクラスを見てみましょう｡
    package examples.jsf.action.impl;

    import java.util.List;

    import examples.jsf.action.ForEachResultInitAction;
    import examples.jsf.dto.ForEachDto;

    public class ForEachResultInitActionImpl implements ForEachResultInitAction {

        private int index;

        private List forEachDtoList;

        private ForEachDto forEachDto;

        public void setIndex(int index) {
            this.index = index;
        }

        public void setForEachDtoList(List forEachDtoList) {
            this.forEachDtoList = forEachDtoList;
        }

        public ForEachDto getForEachDto() {
            return forEachDto;
        }

        public String initialize() {
            forEachDto = (ForEachDto) forEachDtoList.get(index);
            return null;
        }
    }
前のページで、anchorタグやbuttonタグのパラメータでindexを渡していたことを思い出してください｡setIndex()メソッドを定義しておけば、S2JSFが自動的にパラメータの値を設定してくれます｡また、setForEachDtoList()メソッドを定義しておくことで、examples/jsf/dicon/foreach.diconに定義されているforEachDtoListを参照できます｡initMethodタグを使えば、任意のメソッドを呼び出せるので、自由自在にオブジェクトを組み立てることが出来ます｡
    <component name="forEachDtoList" class="java.util.ArrayList" instance="session">
        <initMethod name="add" >
            <arg>
                <component class="examples.jsf.dto.ForEachDto" >
                    <property name="key">"111"</property>
                    <property name="name">"aaa"</property>
                </component>
            </arg>
        </initMethod>
        <initMethod name="add" >
            <arg>
                <component class="examples.jsf.dto.ForEachDto" >
                    <property name="key">"222"</property>
                    <property name="name">"bbb"</property>
                </component>
            </arg>
        </initMethod>
    </component>
initialize()メソッドで指定されたインデックスに基づくオブジェクトをforEachDtoプロパティに設定しています｡forEachDtoプロパティには、getterメソッドが定義されているので、initialize()メソッドが実行された後、S2JSFによって、forEachDtoプロパティの値が自動的にリクエストの属性(forEachDto)に設定されます｡public static final String プロパティ名_EXPORT = "session";のように定数を宣言することで、リクエストではなくセッションの属性に設定することも出来ます｡ ### forEach2List.html このサンプルでは、次のことを学びます｡ 入力系のタグを含んだforEachタグによる繰り返し。 それでは、HTMLの一部を見てみましょう｡
    01:<form>
    02:    <table border="1">
    03:        <tr bgcolor="#7777FF">
    04:            <th>delete</th>
    05:            <th>input</th>
    06:        </tr>
    07:        <span m:inject="s:forEach" m:items="#{forEach2DtoList}" m:var="e">
    08:        <tr>
    09:            <td><input type="checkbox" m:value="#{e.delete}"/></td>
    10:            <td><input type="text" m:value="#{e.input}"</td>
    11:        </tr>
    12:        </span>
    13:    </table>
    14:    <input type="submit" value="update" m:action="#{forEach2ListAction.update}"/>
    15:    <input type="submit" value="add row" m:action="#{forEach2ListAction.addRow}"/>
    16:</form>
このページでは、add rowボタンをクリックすると新規の行が挿入され、deleteのチェックボックスをチェックしてupdateボタンをクリックすることで行を削除することができます｡また、入力値を書き換えてupdateボタンをクリックすることでinputの内容を更新することも出来ます｡ 入力系のタグを含んでいるといっても、forEachタグの使い方に特に違いはありません｡Actionクラスは次のようになります｡
    package examples.jsf.action.impl;

    import java.util.Iterator;
    import java.util.List;

    import examples.jsf.action.ForEach2ListAction;
    import examples.jsf.dto.ForEach2Dto;

    public class ForEach2ListActionImpl implements ForEach2ListAction {

        private List forEach2DtoList;

        public void setForEach2DtoList(List forEach2DtoList) {
            this.forEach2DtoList = forEach2DtoList;
        }

        public String update() {
            for (Iterator i = forEach2DtoList.iterator(); i.hasNext(); ) {
                ForEach2Dto dto = (ForEach2Dto) i.next();
                if (dto.isDelete()) {
                    i.remove();
                }
            }
            return null;
        }

        public String addRow() {
            forEach2DtoList.add(new ForEach2Dto());
            return null;
        }
    }
### converter.html このサンプルでは、次のことを学びます｡ converter属性の使い方。 それでは、HTMLの一部を見てみましょう｡
    <form>
        <span m:inject="h:messages" m:globalOnly="false" m:showDetail="true"/>
        <input type="text" m:value="#{converterDto.aaa}"
            m:converter="#{inputDateTimeConverter}"/><br />
        <span m:value="#{converterDto.aaa}"
            m:converter="#{outputDateTimeConverter}"/><br />
        <input type="submit" value="submit"/>
    </form>
ほとんどの入出力用のタグは、converter属性を持っていて、Javaのオブジェクトの値を文字列に変換したり、入力された文字列を適切なオブジェクトの型に変換するためのコンバータを指定することができます｡この例におけるコンバータは、examples/jsf/dicon/allconverter.diconで次のように定義されています｡
    <component name="inputDateTimeConverter" class="javax.faces.convert.DateTimeConverter">
        <property name="pattern">"yyyyMMdd"</property>
    </component>
    <component name="outputDateTimeConverter" class="javax.faces.convert.DateTimeConverter">
        <property name="pattern">"yyyy/MM/dd"</property>
    </component>
このようにコンバータをHTMLで個別に定義するのではなく、diconファイルで一元管理することで、コンバータの定義が分散することを防ぐことが出来ます｡ ### validator.html このサンプルでは、次のことを学びます｡ validatorタグの使い方。 messageタグの使い方。 それでは、HTMLの一部を見てみましょう｡
    <form>
        <span m:inject="h:messages" m:globalOnly="true"/>
        UserName(2 letters or more):
        <input id="userName" type="text"
            m:value="#{validatorDto.userName}" m:required="true">
            <span m:inject="s:validator" m:binding="#{userNameLengthValidator}"/>
        </input>
        <span m:inject="h:message" m:for="userName"/><br />
        <input type="submit" value="submit"/>
    </form>
バリデーションをかけたい場合、バリデーションの対象となるタグ(id:userName)の子タグとしてvalidatorタグを記述します｡実際のバリデータは、validatorタグのbinding属性で指定します｡この例におけるバリデータは、examples/jsf/dicon/allvalidator.diconで次のように定義されています｡
    <component name="userNameLengthValidator" class="javax.faces.validator.LengthValidator">
        <property name="minimum">2</property>
    </component>
このようにバリデータをHTMLで個別に定義するのではなく、diconファイルで一元管理することで、バリデータの定義が分散することを防ぐことが出来ます｡ バリデーションエラーになったときに表示させるメッセージは、messageタグで組み込みます｡for属性で対象となるタグのidを指定します｡messagesタグでglobalOnly属性をfalseにすることで、messagesタグに表示させることも出来ますが、どのタグでバリデーションエラーがおきたのかをわかりやすくするために、個別のタグのバリデーションエラーは、messageタグを使って表示させたほうが良いと思います｡ ### checkbox.html このサンプルでは、次のことを学びます｡ checkboxの使い方。 それでは、HTMLの一部を見てみましょう｡
    <form>
        <input type="checkbox" m:value="#{checkboxDto.aaa}"/>hoge<br />
        <span m:value="#{checkboxDto.aaa}"/><br />
        <input type="submit" value="submit"/>
    </form>
特に難しいところはありませんね｡うれしいのは、チェックボックスをオフにしたときも、それがサーバサイドにきちんと伝わることです｡ ### selectOneMenu.html このサンプルでは、次のことを学びます｡ selectの使い方。 それでは、HTMLの一部を見てみましょう｡
    01:<form>
    02:    <select m:value="#{selectOneMenuDto.aaa}">
    03:        <option value="1">One</option>
    04:        <option value="2">Two</option>
    05:        <option value="3">Three</option>
    06:    </select><br />
    07:    <span m:value="#{selectOneMenuDto.aaa}"/><br />
    08:
    09:    <select m:value="#{selectOneMenuDto.bbb}"
    10:        m:items="#{selectOneMenuBbbItems}">
    11:        <option value="">Please select</option>
    12:        <option value="1">One</option>
    13:        <option value="2">Two</option>
    14:    </select><br />
    15:    <span m:value="#{selectOneMenuDto.bbb}"/><br />
    16:
    17:    <select m:value="#{selectOneMenuDto.ccc}"
    18:        m:items="#{selectOneMenuCccItems}"
    19:        m:itemValue="deptno"
    20:        m:itemLabel="dname"
    21:        m:nullLabel="Please select">
    22:        <option value="">Please select</option>
    23:        <option value="10">ACOUNTING</option>
    24:    </select><br />
    25:    <span m:value="#{selectOneMenuDto.ccc}"/><br />
    26:
    27:    <input type="submit" value="submit"/>
    28:</form>
2行目からはじまるselectタグは、子タグのoptionタグで直接要素を指定しています｡ 9行目からはじまるselectタグは、items属性で要素を指定しています｡items属性を指定した場合、子タグのoptionタグは実行時には無視されます｡あくまでもブラウザでのプレビュー用です｡selectOneMenuBbbItemsは、examples/jsf/dicon/selectonemenu.diconで次のように定義されています｡
    <component name="selectOneMenuBbbItems" class="java.util.ArrayList">
        <initMethod name="add" >
            <arg>
                <component class="javax.faces.model.SelectItem">
                    <property name="label">"Please select"</property>
                </component>
            </arg>
        </initMethod>
        <initMethod name="add" >
            <arg>
                <component class="javax.faces.model.SelectItem">
                    <property name="value">1</property>
                    <property name="label">"One"</property>
                </component>
            </arg>
        </initMethod>
        <initMethod name="add" >
            <arg>
                <component class="javax.faces.model.SelectItem">
                    <property name="value">2</property>
                    <property name="label">"Two"</property>
                </component>
            </arg>
        </initMethod>
        <initMethod name="add" >
            <arg>
                <component class="javax.faces.model.SelectItem">
                    <property name="value">3</property>
                    <property name="label">"Three"</property>
                </component>
            </arg>
        </initMethod>
        <initMethod name="add" >
            <arg>
                <component class="javax.faces.model.SelectItem">
                    <property name="value">4</property>
                    <property name="label">"Four"</property>
                </component>
            </arg>
        </initMethod>
    </component>
この例では、SelectItemを使って要素を定義しています。 17行目からはじまるselectタグは、items属性で要素を指定しています｡この例の場合、個々の要素はJavaBeansなので、さらにitemValue属性とitemLabel属性で、どのプロパティを値として使うのか、どのプロパティをラベルとして使うのかを指定します｡nullLabel属性を使いnullを設定する場合のラベルを指定することもできます｡selectOneMenuCccItemsは、examples/jsf/dicon/selectonemenu.diconで次のように定義されています｡
    <component name="selectOneMenuCccItems" class="java.util.ArrayList">
        <initMethod name="add" >
            <arg>
                <component class="examples.jsf.entity.Department">
                    <property name="deptno">10</property>
                    <property name="dname">"ACOUNTING"</property>
                </component>
            </arg>
        </initMethod>
        <initMethod name="add" >
            <arg>
                <component class="examples.jsf.entity.Department">
                    <property name="deptno">20</property>
                    <property name="dname">"RESEARCH"</property>
                </component>
            </arg>
        </initMethod>
        <initMethod name="add" >
            <arg>
                <component class="examples.jsf.entity.Department">
                    <property name="deptno">30</property>
                    <property name="dname">"SALES"</property>
                </component>
            </arg>
        </initMethod>
        <initMethod name="add" >
            <arg>
                <component class="examples.jsf.entity.Department">
                    <property name="deptno">40</property>
                    <property name="dname">"OPERATIONS"</property>
                </component>
            </arg>
        </initMethod>
    </component>
| © Copyright The Seasar Project and the others 2004, all rights reserved. |