boostrapでラジオボタンやチェックボックスを使用する場合、div, input, label要素にbootstrapのCSSクラスを指定する必要がある。
JSFでラジオボタンを使用する場合、selectOneRadio, selectBooleanCheckbox, selectManyCheckbox等を使用するが、これらのJSF要素が出力するHTML要素のコントロールができず、上記のようなCSSクラスを指定することは難しい。
ここでは、javascript(jQuery)とJSFのinputHiddenを使った方法を説明する。
方式
- ラジオボタンやチェックボックスは通常のHTMLで実現し、bootstrapのCSSクラスを指定する。ページ表示時やサブミット時にjavascript(jQuery)で、ラジオボタンやチェックボックスの値をJSFのinputHidden要素の格納する。
- inputHiddenの値は選択されたラジオボタンやチェックボックスの値をカンマ区切りで格納する。
- ページ表示時、ラジオボタンやチェックボックスの初期値を設定するためにinputHiddenの値をラジオボタンやチェックボックスに設定する。
- サブミット時は、ラジオボタンやチェックボックスの値をinputHiddenの値に設定する。
- より良い解決策は、カスタムのJSFコンポーネントを作成することだと思うが、これは将来の課題とする。
ソースコード例
ラジオボタン・チェックボックスとinputHiddenとの値のマッピングを行うために、mapHiddenToChecked, mapCheckedToHidden関数を作成しました。
混乱するのはHTMLとJSFの要素名やjQueryでの要素名の指定方法です。
JSF上で宣言した要素のIDは、HTML上ではフォームID + “:” + 要素のIDとなります。下記ののinputHidden要素(id=”radioval”)の場合は、”form:radioval”というIDになります。
次のjQuery(セレクタ)にて、ID指定で要素を選択する場合は$("#elementid")としますが、”:”や”.”は”\\”でエスケープする必要があるので、上記のID例の場合は”#form\\:radioval”となります。
<h:form id="form">
...
<!-- ラジオボタンのサンプル -->
<h:inputHidden id="radioval" value="#{bean.radioval}" />
<div class="form-check">
<input type="radio" class="form-check-input" name="radioname" value="1" />
<label class="form-check-label">値1</label>
</div>
<div class="form-check">
<input type="radio" class="form-check-input" name="radioname" value="2" />
<label class="form-check-label">値2</label>
</div>
<!-- チェックボックスのサンプル -->
<h:inputHidden id="checkval" value="#{bean.checkval}" />
<div class="form-check">
<input type="checkbox" name="checkname" value="A" class="form-check-input" />
<label class="form-check-label">値A</label>
</div>
<div class="form-check">
<input type="checkbox" name="checkname" value="B" class="form-check-input" />
<label class="form-check-label">値B</label>
</div>
...
<h:commandButton action="#{bean.submit()}" value="送信" ... onclick="doPrePost();" >
...
</h:form>
<script>
//<![CDATA[
...
$(function(){
// アルゴリズム欄、出力オプション欄の初期値の反映(hidden->checkbox)
mapHiddenToChecked("#form\\:radioval", "radioname");
mapHiddenToChecked("#form\\:checkval", "checkname");
})
// ハッシュアルゴリズム、出力オプションをhidden項目にマップする
function doPrePost(){
mapCheckedToHidden("radioname", "#form\\:radioval");
mapCheckedToHidden("checkname", "#form\\:checkval");
}
...
// hidden項目等の項目を複数チェックボックスの値にマップ
function mapHiddenToChecked(hiddenId, checkedName){
var vals = $(hiddenId).val();
var checks = vals != null ? vals.split(','): [];
for(i=0; i<checks.length; i++){
$("input[name=" + checkedName + "][value=" + checks[i] + "]").prop("checked", true);
}
}
// 複数チェックボックスの値をhidden項目等の項目にマップ
function mapCheckedToHidden(checkName, hiddenId){
var vals = "";
$("input[name=" + checkName + "]").each(function(){
if( $(this).prop("checked") ){
if( vals.length > 0){
vals += ",";
}
vals += $(this).val();
}
});
$(hiddenId).val(vals);
}
...