下記記事にて、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(省略)・・・
}