下記記事にて、JSFのタグを紹介しました。
実はこの記述方法は、古い(昔の)JSFのお作法であり最近はHTMLフレンドリーマークアップと呼ばれる手法が主流です。
そもそもHTMLフレンドリーマークアップが何かというと、HTML5になりHTMLタグに新しい属性等がたくさん追加されたため、その都度JSFタグを変更するのが困難であるからということと、デザイナーとの協業をやりやすくするために生まれたが考え方で実現方法は2つあります。
- パススルーアトリビュート
- パススルーエレメント
パススルーアトリビュートは普通のHTMLっぽい記述方法であり、パススルーエレメントはJSFタグに追加で記述できる属性で、今回紹介するのはパススルーアトリビュートです。
パススルーエレメントについては下記記事で紹介しています。
では、最近のJSF開発ではすべてHTMLフレンドリーマークアップを使えばいいか?というと個人的には懐疑的です。逆に記述が複雑になってしまう場合もありケースバイケースだと思っています。
そこでケース別におすすめの記述方法を紹介します。
※パススルーアトリビュートを利用する場合は使い方はXML名前空間に下記を追加してください。最後にサンプルソースがあるのでそちらも参考にしてください。
xmlns:jsf=”http://xmlns.jcp.org/jsf”
目次
表示
「EL式」を利用しましょう。
#{bean.colDisp}
テキストボックス
「パススルーアトリビュート」を利用しましょう。
<input type='text' jsf:id='colText' jsf:value='#{bean.colText}'/>
パスワード
「パススルーアトリビュート」を利用しましょう。
<input type='password' jsf:id='colPass' jsf:value='#{bean.colPass}'/>
隠しフィールド
「パススルーアトリビュート」を利用しましょう。
<input type='hidden' jsf:id='colHid' jsf:value='#{bean.colHidden}' />
ファイル
「パススルーアトリビュート」を利用しましょう。
<input type='file' jsf:id='coFile' jsf:value='#{bean.colFile}' />
ファイル項目を利用する場合はformの属性に「enctype=”multipart/form-data”」を指定してください。
テキストエリア
「パススルーアトリビュート」を利用しましょう。
<textarea>#{tagBean.colTextarea}</textarea>
ラジオボタン
「JSFタグ」を利用しましょう。
要素固定であればパススルーアトリビュートでも簡単に記述はできそうですが、一般的なシステムでは要素固定と要素が動的なケース(マスターの値から要素を作るようなケース)が混在すると思います。その際に記述が分かれていると読みにくいので「JSFタグ」を利用してしまうのが一番シンプルだと思います。
固定要素
<h:selectOneRadio value="#{bean.colFixedRadio}"> <f:selectItem itemValue="1" itemLabel="サンプル1"/> <f:selectItem itemValue="2" itemLabel="サンプル2"/> <f:selectItem itemValue="3" itemLabel="サンプル3"/> </h:selectOneRadio>
動的要素
<h:selectOneRadio value="#{bean.colDynaRadio}"> <f:selectItems value="#{bean.radioItems}" /> </h:selectOneRadio>
セレクトボックス
「JSFタグ」を利用しましょう。
理由はラジオボタンと同じです。
固定要素
<h:selectOneMenu value="#{bean.colFixedSelect}"> <f:selectItem itemValue="1" itemLabel="サンプル1"/> <f:selectItem itemValue="2" itemLabel="サンプル2"/> <f:selectItem itemValue="3" itemLabel="サンプル3"/> </h:selectOneMenu>
動的要素
<h:selectOneMenu value="#{bean.colDynaSelect}"> <f:selectItems value="#{bean.selectItems}" /> </h:selectOneMenu>
チェックボックス
「JSFタグ」を利用しましょう。
理由はラジオボタンと同じです。
固定要素
<h:selectManyCheckbox value="#{bean.colFixedCheck}"> <f:selectItem itemValue="1" itemLabel="サンプル1"/> <f:selectItem itemValue="2" itemLabel="サンプル2"/> <f:selectItem itemValue="3" itemLabel="サンプル3"/> </h:selectManyCheckbox>
動的要素
<h:selectManyCheckbox value="#{tagBean.colDynaCheck}"> <f:selectItems value="#{tagBean.checkItems}" /> </h:selectManyCheckbox>
固定要素も、動的要素もサーバー側(ManagedBean)側はString配列で受けることができます。
/** チェックボックス(固定) */ private String[] colFixedCheck; /** チェックボックス(動的) */ private String[] colDynaCheck;
リンク
「パススルーアトリビュート」を利用しましょう。
<a jsf:outcome="index">初期表示</a>
ボタン
「パススルーアトリビュート」を利用しましょう。
<button jsf:action="#{bean.post}">送信</button>
サンプルソース
faceletsとManagedBeanのサンプルです。
tag.xhtml
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h ="http://xmlns.jcp.org/jsf/html" xmlns:f ="http://xmlns.jcp.org/jsf/core" xmlns:ui ="http://xmlns.jcp.org/jsf/facelets" xmlns:jsf="http://xmlns.jcp.org/jsf"> <head> </head> <body> <form jsf:id='form' enctype="multipart/form-data"> <table> <tr> <td>表示</td> <td>#{tagBean.colDisp}</td> <td>EL式</td> </tr> <tr> <td>テキストボックス</td> <td> <input jsf:id='colText' type='text' jsf:value='#{tagBean.colText}' /> </td> <td>パススルーアトリビュート</td> </tr> <tr> <td>パスワード</td> <td> <input jsf:id='colPass' type='password' jsf:value='#{tagBean.colPass}' /> </td> <td>パススルーアトリビュート</td> </tr> <tr> <td>隠しフィールド</td> <td> <input jsf:id='coHidden' type='hidden' jsf:value='#{tagBean.colHidden}' /> </td> <td>パススルーアトリビュート</td> </tr> <tr> <td>ファイル</td> <td> <input jsf:id='coFile' type='file' jsf:value='#{tagBean.colFile}' /> </td> <td>パススルーアトリビュート</td> </tr> <tr> <td>テキストエリア</td> <td><textarea>#{tagBean.colTextarea}</textarea></td> <td>パススルーアトリビュート</td> </tr> <tr> <td>ラジオボタン(固定)</td> <td> <h:selectOneRadio value="#{tagBean.colFixedRadio}"> <f:selectItem itemValue="1" itemLabel="サンプル1"/> <f:selectItem itemValue="2" itemLabel="サンプル2"/> <f:selectItem itemValue="3" itemLabel="サンプル3"/> </h:selectOneRadio> </td> <td>JSFタグ</td> </tr> <tr> <td>ラジオボタン(動的)</td> <td> <h:selectOneRadio value="#{tagBean.colDynaRadio}"> <f:selectItems value="#{tagBean.radioItems}" /> </h:selectOneRadio> </td> <td>JSFタグ</td> </tr> <tr> <td>セレクトボックス(固定)</td> <td> <h:selectOneMenu value="#{tagBean.colFixedSelect}"> <f:selectItem itemValue="1" itemLabel="サンプル1"/> <f:selectItem itemValue="2" itemLabel="サンプル2"/> <f:selectItem itemValue="3" itemLabel="サンプル3"/> </h:selectOneMenu> </td> <td>JSFタグ</td> </tr> <tr> <td>セレクトボックス(動的)</td> <td> <h:selectOneMenu value="#{tagBean.colDynaSelect}"> <f:selectItems value="#{tagBean.selectItems}" /> </h:selectOneMenu> </td> <td>JSFタグ</td> </tr> <tr> <td>チェックボックス(固定)</td> <td> <h:selectManyCheckbox value="#{tagBean.colFixedCheck}"> <f:selectItem itemValue="1" itemLabel="サンプル1"/> <f:selectItem itemValue="2" itemLabel="サンプル2"/> <f:selectItem itemValue="3" itemLabel="サンプル3"/> </h:selectManyCheckbox> </td> <td>JSFタグ</td> </tr> <tr> <td>チェックボックス(動的)</td> <td> <h:selectManyCheckbox value="#{tagBean.colDynaCheck}"> <f:selectItems value="#{tagBean.checkItems}" /> </h:selectManyCheckbox> </td> <td>JSFタグ</td> </tr> <tr> <td>リンク</td> <td> <a jsf:outcome="index">初期表示</a> </td> <td>パススルーアトリビュート</td> </tr> <tr> <td>ボタン</td> <td> <button jsf:action="#{tagBean.post}">送信</button> </td> <td>パススルーアトリビュート</td> </tr> </table> </form> </body> </html>
tagBean.xhtml
package com.ittoybox.bean; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.annotation.PostConstruct; import javax.faces.model.SelectItem; import javax.faces.view.ViewScoped; import javax.inject.Named; import javax.servlet.http.Part; @Named @ViewScoped public class TagBean implements Serializable { /** 表示項目 */ private String colDisp; /** テキスト */ private String colText; /** パスワード */ private String colPass; /** hidden */ private String colHidden; /** ファイル */ private Part colFile; /** テキストエリア */ private String colTextarea; /** ラジオボタン(固定) */ private String colFixedRadio; /** ラジオボタン(動的) */ private String colDynaRadio; /** セレクトボックス(固定) */ private String colFixedSelect; /** セレクトボックス(動的) */ private String colDynaSelect; /** チェックボックス(固定) */ private String[] colFixedCheck; /** チェックボックス(動的) */ private String[] colDynaCheck; /** ラジオボタン(動的)の要素 */ private List<SelectItem> radioItems; /** セレクトボックス(動的)の要素 */ private List<SelectItem> selectItems; /** チェックボックス(動的)の要素 */ private List<SelectItem> checkItems; /** * 初期表示処理 */ @PostConstruct public void init() { this.colDisp = "1"; this.colText = "text"; this.colPass = ""; this.colHidden = "hidden"; this.colTextarea = "textarea"; this.colFixedRadio = "1"; this.colDynaRadio = "2"; this.colFixedSelect = "3"; this.colDynaSelect = ""; //未選択 this.colFixedCheck = new String[]{"1","2","3"}; this.colDynaCheck = new String[]{"1","3"}; //ラジオボタンの要素を動的に作成 List<SelectItem> radioItems = new ArrayList<>(); SelectItem radioItem1 = new SelectItem("1","サンプル1"); radioItems.add(radioItem1); SelectItem radioItem2 = new SelectItem("2","サンプル2"); radioItems.add(radioItem2); SelectItem radioItem3 = new SelectItem("3","サンプル3"); radioItems.add(radioItem3); this.radioItems = radioItems; //セレクトボックスの要素を動的に作成 List<SelectItem> selectItems = new ArrayList<>(); SelectItem selectItem1 = new SelectItem("1","サンプル1"); selectItems.add(selectItem1); SelectItem selectItem2 = new SelectItem("2","サンプル2"); selectItems.add(selectItem2); SelectItem selectItem3 = new SelectItem("3","サンプル3"); selectItems.add(selectItem3); this.selectItems = selectItems; //チェックボックスの要素を動的に作成 List<SelectItem> checkItems = new ArrayList<>(); SelectItem checkItem1 = new SelectItem("1","サンプル1"); checkItems.add(checkItem1); SelectItem checkItem2 = new SelectItem("2","サンプル2"); checkItems.add(checkItem2); SelectItem checkItem3 = new SelectItem("3","サンプル3"); checkItems.add(checkItem3); this.checkItems = checkItems; } public String post() { int count = Integer.valueOf(this.colDisp); count++; this.colDisp = String.valueOf(count++); return null; } ・・・setter/getter(省略)・・・ }