2008年11月28日金曜日

RAD v7.5 試用版 を使ってJSFとEJB3.0・・・(10)

一覧表示した行を、ラジオボタンで選択できるようにします。
残念ながらカスタムタグを開発する必要があります。
(JSTLでもこの手の実装に苦労した記憶が・・・どうして標準の機能に無いんだろう??)

以下のページを参考にしました。というか、一部型のエラーが出たりしたので、変数をStringからObjectに変更してtoString()してますが、ほとんどそのまんまです。(感謝)

※RAD環境ではweb.xmlへのtaglib要素の追加は不要でした。web-app_2_5.xsdだから?よく分かってません。

Group radio buttons inside a JSF dataTable component
Write a custom JSF tag for enhancing radio button behavior
By Srijeeb Roy, JavaWorld.com, 02/27/07
(JAVAWORLD)
http://www.javaworld.com/javaworld/jw-02-2007/jw-02-jsf.html

ずいぶんとdeprecatedになってしまっているようですが、Webをダラダラ調べたところ、気にせず使うのが一番いいみたい。まだこれといった代替方法は確立されていないようです。

■準備
MySampleJSFの中にそのまま作ってもよいのですが、jarに分けたほうがカッコよいのでユーティリティ・モジュールプロジェクトとして作成します。

まずファイル > 新規 > その他 > 新規Javaユーティリティ・モジュールプロジェクト > "MySampleCTG" を作成。

MySampleJSF のプロパティを開き、Java EE モジュール依存関係 > Webライブラリータブ(J2EEモジュールではなく)を開いてMySampleCTGにチェックを入れます。

準備完了。

■カスタムタグの作成
以下のステップが必要です。結構大変ですね。

1. 以下の三つのクラスを作成します。
1-1. コンポーネント クラス(MySampleCTGプロジェクトに作成)
1-2. レンダー クラス(同上)
1-3. カスタム・タグ クラス(同上)
2. TLDファイルを作成します。(MySampleJSFプロジェクトに作成。MySampleCTGのMETA-INFではうまく行きませんでした)
3. faces-config.xmlにコンポーネント要素を追加します。(同上)
4. jspにタグを書きます。(同上)

1-1. コンポーネントクラス(UICustomSelectOneRadio)
package test.ctg;

import javax.el.ValueExpression;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;

public class UICustomSelectOneRadio extends UIInput {

// 1. 属性をクラス変数として定義
private String name = null;
private String overrideName = null;
private String styleClass = null;
private String style = null;
private String disabled = null;
private String itemLabel = null;
private Object itemValue = null;
private String onClick = null;
private String onMouseOver = null;
private String onMouseOut = null;
private String onFocus = null;
private String onBlur = null;

// 2. 動的に属性を取得するためのメソッドを定義
public String returnValueBindingAsString(String attr) {
// サンプルコードは一部Deprecatedだったので適宜変更しています。
ValueExpression valueExpression = getValueExpression(attr);
if (valueExpression != null) {
return valueExpression.getValue(this.getFacesContext()
.getELContext()).toString();
} else {
return null;
}
}

// 3. setter, getterを定義. getterでreturnValueBindingAsStringを使っている
// ので注意
public String getName() {
if (name != null) {
return name;
}
return returnValueBindingAsString("name");

}

public void setName(String name) {
this.name = name;
}

public String getOverrideName() {
if (overrideName != null) {
return overrideName;
}
return returnValueBindingAsString("overrideName");
}

public void setOverrideName(String overrideName) {
this.overrideName = overrideName;
}

public String getStyleClass() {
if (styleClass != null) {
return styleClass;
}
return returnValueBindingAsString("styleClass");
}

public void setStyleClass(String styleClass) {
this.styleClass = styleClass;
}

public String getStyle() {
if (style != null) {
return style;
}
return returnValueBindingAsString("style");
}

public void setStyle(String style) {
this.style = style;
}

public String getDisabled() {
if (disabled != null) {
return disabled;
}
return returnValueBindingAsString("disabled");
}

public void setDisabled(String disabled) {
this.disabled = disabled;
}

public String getItemLabel() {
if (itemLabel != null) {
return itemLabel;
}
return returnValueBindingAsString("itemLabel");
}

public void setItemLabel(String itemLabel) {
this.itemLabel = itemLabel;
}

public Object getItemValue() {
if (itemValue != null) {
return itemValue;
}
return returnValueBindingAsString("itemValue");
}

public void setItemValue(Object itemValue) {
this.itemValue = itemValue;
}

public String getOnClick() {
if (onClick != null) {
return onClick;
}
return returnValueBindingAsString("onClick");
}

public void setOnClick(String onClick) {
this.onClick = onClick;
}

public String getOnMouseOver() {
if (onMouseOver != null) {
return onMouseOver;
}
return returnValueBindingAsString("onMouseOver");
}

public void setOnMouseOver(String onMouseOver) {
this.onMouseOver = onMouseOver;
}

public String getOnMouseOut() {
if (onMouseOut != null) {
return onMouseOut;
}
return returnValueBindingAsString("onMouseOut");
}

public void setOnMouseOut(String onMouseOut) {
this.onMouseOut = onMouseOut;
}

public String getOnFocus() {
if (onFocus != null) {
return onFocus;
}
return returnValueBindingAsString("onFocus");
}

public void setOnFocus(String onFocus) {
this.onFocus = onFocus;
}

public String getOnBlur() {
if (onBlur != null) {
return onBlur;
}
return returnValueBindingAsString("onBlur");
}

public void setOnBlur(String onBlur) {
this.onBlur = onBlur;
}

// 4. restoreStateとsaveStateメソッドを実装します。
@Override
public void restoreState(FacesContext context, Object state) {
Object[] values = (Object[]) state;
super.restoreState(context, values[0]);
styleClass = (String) values[1];
style = (String) values[2];
disabled = (String) values[3];
itemLabel = (String) values[4];
itemValue = (String) values[5];
onClick = (String) values[6];
onMouseOver = (String) values[7];
onMouseOut = (String) values[8];
onFocus = (String) values[9];
onBlur = (String) values[10];
name = (String) values[11];
overrideName = (String) values[12];
}
@Override
public Object saveState(FacesContext context) {
Object[] values = new Object[13];
values[0] = super.saveState(context);
values[1] = styleClass;
values[2] = style;
values[3] = disabled;
values[4] = itemLabel;
values[5] = itemValue;
values[6] = onClick;
values[7] = onMouseOver;
values[8] = onMouseOut;
values[9] = onFocus;
values[11] = name;
values[12] = overrideName;
return (values);
}

// 5. getFamilyを実装します。faces-config.xmlにこの名前を指定します。
@Override
public String getFamily() {
return ("CustomSelectOneRadio");
}
}

次はレンダークラス(HTMLCustomSelectOneRadioRenderer)です。
package test.ctg;

import java.io.IOException;
import java.util.Map;

import javax.faces.component.UIComponent;
import javax.faces.component.UIData;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.Renderer;

public class HTMLCustomSelectOneRadioRenderer extends Renderer {

@SuppressWarnings("unchecked")
@Override
public void decode(FacesContext context, UIComponent component) {
if ((context == null) || (component == null)) {
throw new NullPointerException();
}
UICustomSelectOneRadio aUICustomSelectOneRadio = null;
if (component instanceof UICustomSelectOneRadio) {
aUICustomSelectOneRadio = (UICustomSelectOneRadio) component;
} else {
return;
}
Map map = context.getExternalContext().getRequestParameterMap();
String name = getName(aUICustomSelectOneRadio, context);
if (map.containsKey(name)) {
String value = map.get(name).toString();
if (value != null) {
setSubmittedValue(component, value);
}
}
}

public void setSubmittedValue(UIComponent component, Object obj) {

if (component instanceof UIInput) {
((UIInput) component).setSubmittedValue(obj);
}
}

private String getName(UICustomSelectOneRadio aUICustomSelectOneRadio,
FacesContext context) {

UIComponent parentUIComponent = getParentDataTableFromHierarchy(aUICustomSelectOneRadio);
if (parentUIComponent == null) {
return aUICustomSelectOneRadio.getClientId(context);
} else {
if (aUICustomSelectOneRadio.getOverrideName() != null
&& aUICustomSelectOneRadio.getOverrideName().equals("true")) {
return aUICustomSelectOneRadio.getName();
} else {
String id = aUICustomSelectOneRadio.getClientId(context);
int lastIndexOfColon = id.lastIndexOf(":");
String partName = "";
if (lastIndexOfColon != -1) {
partName = id.substring(0, lastIndexOfColon + 1);
if (aUICustomSelectOneRadio.getName() == null) {
partName = partName + "generatedRad";
} else
partName = partName + aUICustomSelectOneRadio.getName();
}
return partName;
}
}
}

private UIComponent getParentDataTableFromHierarchy(UIComponent uiComponent) {
if (uiComponent == null) {
return null;
}
if (uiComponent instanceof UIData) {
return uiComponent;
} else {
// try to find recursively in the Component tree hierarchy
return getParentDataTableFromHierarchy(uiComponent.getParent());
}
}

@Override
public void encodeEnd(FacesContext context, UIComponent component)
throws IOException {
if ((context == null) || (component == null)) {
throw new NullPointerException();
}

UICustomSelectOneRadio aUICustomSelectOneRadio = (UICustomSelectOneRadio) component;

if (component.isRendered()) {
ResponseWriter writer = context.getResponseWriter();

writer.write("<input type=\"radio\"");

writer.write(" id=\"" + component.getClientId(context) + "\"");
writer.write(" name=\"" + getName(aUICustomSelectOneRadio, context)
+ "\"");
if (aUICustomSelectOneRadio.getStyleClass() != null
&& aUICustomSelectOneRadio.getStyleClass().trim().length() > 0) {
writer
.write(" class=\""
+ aUICustomSelectOneRadio.getStyleClass()
.trim() + "\"");
}
if (aUICustomSelectOneRadio.getStyle() != null
&& aUICustomSelectOneRadio.getStyle().trim().length() > 0) {
writer.write(" style=\""
+ aUICustomSelectOneRadio.getStyle().trim() + "\"");
}
if (aUICustomSelectOneRadio.getDisabled() != null
&& aUICustomSelectOneRadio.getDisabled().trim().length() > 0
&& aUICustomSelectOneRadio.getDisabled().trim().equals(
"true")) {
writer.write(" disabled=\"disabled\"");
}
if (aUICustomSelectOneRadio.getItemValue() != null) {
writer.write(" value=\""
+ aUICustomSelectOneRadio.getItemValue().toString().trim() + "\"");
}
if (aUICustomSelectOneRadio.getOnClick() != null
&& aUICustomSelectOneRadio.getOnClick().trim().length() > 0) {
writer.write(" onclick=\""
+ aUICustomSelectOneRadio.getOnClick().trim() + "\"");
}
if (aUICustomSelectOneRadio.getOnMouseOver() != null
&& aUICustomSelectOneRadio.getOnMouseOver().trim().length() > 0) {
writer.write(" onmouseover=\""
+ aUICustomSelectOneRadio.getOnMouseOver().trim()
+ "\"");
}
if (aUICustomSelectOneRadio.getOnMouseOut() != null
&& aUICustomSelectOneRadio.getOnMouseOut().trim().length() > 0) {
writer
.write(" onmouseout=\""
+ aUICustomSelectOneRadio.getOnMouseOut()
.trim() + "\"");
}
if (aUICustomSelectOneRadio.getOnFocus() != null
&& aUICustomSelectOneRadio.getOnFocus().trim().length() > 0) {
writer.write(" onfocus=\""
+ aUICustomSelectOneRadio.getOnFocus().trim() + "\"");
}
if (aUICustomSelectOneRadio.getOnBlur() != null
&& aUICustomSelectOneRadio.getOnBlur().trim().length() > 0) {
writer.write(" onblur=\""
+ aUICustomSelectOneRadio.getOnBlur().trim() + "\"");
}

if (aUICustomSelectOneRadio.getValue() != null
&& aUICustomSelectOneRadio.getValue().equals(
aUICustomSelectOneRadio.getItemValue())) {
writer.write(" checked=\"checked\"");
}
writer.write(">");
if (aUICustomSelectOneRadio.getItemLabel() != null) {
writer.write(aUICustomSelectOneRadio.getItemLabel());
}
writer.write("</input>");
}
}
}

■カスタム・タグクラス(HTMLCustomSelectOneRadioTag)
package test.ctg;

import javax.faces.FactoryFinder;
import javax.faces.application.Application;
import javax.faces.application.ApplicationFactory;
import javax.faces.component.UIComponent;
import javax.faces.el.ValueBinding;
import javax.faces.webapp.UIComponentELTag;
import javax.faces.webapp.UIComponentTag;

public class HTMLCustomSelectOneRadioTag extends UIComponentELTag {

public HTMLCustomSelectOneRadioTag() {
name = null;
value = null;
styleClass = null;
style = null;
disabled = null;
itemLabel = null;
itemValue = null;
onClick = null;
onMouseOver = null;
onMouseOut = null;
onFocus = null;
onBlur = null;
overrideName = null;
}

public String getDisabled() {
return disabled;
}

public String getItemLabel() {
return itemLabel;
}

public String getItemValue() {
return itemValue;
}

public String getName() {
return name;
}

public String getOnBlur() {
return onBlur;
}

public String getOnClick() {
return onClick;
}

public String getOnFocus() {
return onFocus;
}

public String getOnMouseOut() {
return onMouseOut;
}

public String getOnMouseOver() {
return onMouseOver;
}

public String getOverrideName() {
return overrideName;
}

public String getStyle() {
return style;
}

public String getStyleClass() {
return styleClass;
}

public String getValue() {
return value;
}

public void setDisabled(String string) {
disabled = string;
}

public void setItemLabel(String string) {
itemLabel = string;
}

public void setItemValue(String string) {
itemValue = string;
}

public void setName(String string) {
name = string;
}

public void setOnBlur(String string) {
onBlur = string;
}

public void setOnClick(String string) {
onClick = string;
}

public void setOnFocus(String string) {
onFocus = string;
}

public void setOnMouseOut(String string) {
onMouseOut = string;
}

public void setOnMouseOver(String string) {
onMouseOver = string;
}

public void setOverrideName(String string) {
overrideName = string;
}

public void setStyle(String string) {
style = string;
}

public void setStyleClass(String string) {
styleClass = string;
}

public void setValue(String string) {
value = string;
}

protected void setProperties(UIComponent component) {
super.setProperties(component);
UICustomSelectOneRadio aUICustomSelectOneRadio =
(UICustomSelectOneRadio) component;
if (name != null) {
if (UIComponentTag.isValueReference(name)) {
aUICustomSelectOneRadio.setValueBinding("name",
getValueBinding(name));
} else {
aUICustomSelectOneRadio.getAttributes().put("name", name);
}
}
if (value != null)
if (UIComponentTag.isValueReference(value))
aUICustomSelectOneRadio.setValueBinding("value",
getValueBinding(value));
else
aUICustomSelectOneRadio.getAttributes().put("value", value);
if (styleClass != null)
if (UIComponentTag.isValueReference(styleClass))
aUICustomSelectOneRadio.setValueBinding("styleClass",
getValueBinding(styleClass));
else
aUICustomSelectOneRadio.getAttributes().put("styleClass",
styleClass);
if (style != null)
if (UIComponentTag.isValueReference(style))
aUICustomSelectOneRadio.setValueBinding("style",
getValueBinding(style));
else
aUICustomSelectOneRadio.getAttributes().put("style", style);
if (disabled != null)
if (UIComponentTag.isValueReference(disabled))
aUICustomSelectOneRadio.setValueBinding("disabled",
getValueBinding(disabled));
else
aUICustomSelectOneRadio.getAttributes().put("disabled",
disabled);
if (itemLabel != null)
if (UIComponentTag.isValueReference(itemLabel)) {
aUICustomSelectOneRadio.setValueBinding("itemLabel",
getValueBinding(itemLabel));
} else {
System.out.println("itemLabel=" + itemLabel);
aUICustomSelectOneRadio.getAttributes().put("itemLabel",
itemLabel);
}
if (itemValue != null)
if (UIComponentTag.isValueReference(itemValue))
aUICustomSelectOneRadio.setValueBinding("itemValue",
getValueBinding(itemValue));
else
aUICustomSelectOneRadio.getAttributes().put("itemValue",
itemValue);
if (onClick != null)
if (UIComponentTag.isValueReference(onClick))
aUICustomSelectOneRadio.setValueBinding("onClick",
getValueBinding(onClick));
else
aUICustomSelectOneRadio.getAttributes().put("onClick", onClick);
if (onMouseOver != null)
if (UIComponentTag.isValueReference(onMouseOver))
aUICustomSelectOneRadio.setValueBinding("onMouseOver",
getValueBinding(onMouseOver));
else
aUICustomSelectOneRadio.getAttributes().put("onMouseOver",
onMouseOver);
if (onMouseOut != null)
if (UIComponentTag.isValueReference(onMouseOut))
aUICustomSelectOneRadio.setValueBinding("onMouseOut",
getValueBinding(onMouseOut));
else
aUICustomSelectOneRadio.getAttributes().put("onMouseOut",
onMouseOut);
if (onFocus != null)
if (UIComponentTag.isValueReference(onFocus))
aUICustomSelectOneRadio.setValueBinding("onFocus",
getValueBinding(onFocus));
else
aUICustomSelectOneRadio.getAttributes().put("onFocus", onFocus);
if (onBlur != null)
if (UIComponentTag.isValueReference(onBlur))
aUICustomSelectOneRadio.setValueBinding("onBlur",
getValueBinding(onBlur));
else
aUICustomSelectOneRadio.getAttributes().put("onBlur", onBlur);
if (overrideName != null)
if (UIComponentTag.isValueReference(overrideName))
aUICustomSelectOneRadio.setValueBinding("overrideName",
getValueBinding(overrideName));
else
aUICustomSelectOneRadio.getAttributes().put("overrideName",
overrideName);
}

public ValueBinding getValueBinding(String valueRef) {
ApplicationFactory af = (ApplicationFactory) FactoryFinder
.getFactory("javax.faces.application.ApplicationFactory");
Application a = af.getApplication();
return a.createValueBinding(valueRef);
}

private String name;
private String value;
private String styleClass;
private String style;
private String disabled;
private String itemLabel;
private String itemValue;
private String onClick;
private String onMouseOver;
private String onMouseOut;
private String onFocus;
private String onBlur;
private String overrideName;

@Override
public String getComponentType() {
return "component.CustomSelectOneRadio";
}

@Override
public String getRendererType() {
return "renderer.CustomSelectOneRadio";
}
}

2. mysample.tldファイルです。
/WEB-INF/tldに置いてください。
<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">

<taglib>
<!-- ============== Tag Library Description Elements ============= -->
<tlib-version>0.03</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>Custom JavaServerFaces Framework Tag Library</short-name>
<uri>http://www.srijeeb.com/jsf/tags-html</uri>
<tag>
<name>radioButton</name>
<tag-class>test.ctg.HTMLCustomSelectOneRadioTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>name</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>String</type>
</attribute>
<attribute>
<name>overrideName</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>String</type>
</attribute>
<attribute>
<name>id</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>String</type>
</attribute>
<attribute>
<name>value</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>String</type>
</attribute>
<attribute>
<name>styleClass</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>String</type>
</attribute>
<attribute>
<name>style</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>String</type>
</attribute>
<attribute>
<name>disabled</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>String</type>
</attribute>
<attribute>
<name>rendered</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>Boolean</type>
</attribute>
<attribute>
<name>itemLabel</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>String</type>
</attribute>
<attribute>
<name>itemValue</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
<type>String</type>
</attribute>
<attribute>
<name>onClick</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>String</type>
</attribute>
<attribute>
<name>onMouseOver</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>String</type>
</attribute>
<attribute>
<name>onMouseOut</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>String</type>
</attribute>
<attribute>
<name>onFocus</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>String</type>
</attribute>
<attribute>
<name>onBlur</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>String</type>
</attribute>
</tag>
</taglib>

重要:TLDファイルをMySampleCTG/src/META-INF配下に置いたらうまく動きませんでした。web.xmlとかJSPをいろいろいじってみたのですがダメでした。

エラー例)
com.ibm.ws.jsp.inputsource.JspInputSourceImpl JspInputSourceImpl Failed to create inputsource contextURL =[file:/C:/Documents and Settings/user_name/IBM/rationalsdp/workspace/MySampleJSF/WebContent/ relativeURL =[http://www.srijeeb.com/jsf/tags-html]
java.net.MalformedURLException
at java.net.URL.<init>(URL.java:601)
...

おそらくそれと関連してると思われるのですが、WASテスト環境の調子も悪くなりました。
[08/11/27 13:14:21:000 JST] 0000001e annotations E ArchiveInputStreamData iterate unable to open file iterator
java.util.zip.ZipException: ZipFile closed
...のようなエラーが毎回出るようになった・WASの「公開」プロセスが0%のまま進まない、など。

ユーティリティプロジェクトは動作が怪しいですね。はっきり言って使わないほうがいいと思います。(昔のWSADでも動作が怪しかった記憶があります)
重要:ClassNotFoundエラーが出たら、MySampleCTGフォルダを右クリック Java EE > EARライブラリの更新 をしたら直ることがあります。MySampleCTG配下を編集したら「EARライブラリの更新」を実行するようにしましょう。

3. faces-config.xmlにコンポーネント要素を追加します。
以下の要素を追加してください。
 <component>
<component-type>component.CustomSelectOneRadio</component-type>
<component-class>test.ctg.UICustomSelectOneRadio
</component-class>
<component-extension>
<component-family>CustomSelectOneRadio</component-family>
<renderer-type>renderer.CustomSelectOneRadio</renderer-type>
</component-extension>
</component>
<render-kit>
<renderer>
<component-family>CustomSelectOneRadio</component-family>
<renderer-type>renderer.CustomSelectOneRadio</renderer-type>
<renderer-class>test.ctg.HTMLCustomSelectOneRadioRenderer
</renderer-class>
</renderer>
</render-kit>

4. jspにタグを書きます。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><%@page
language="java" contentType="text/html; charset=windows-31j"
pageEncoding="windows-31j"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="/WEB-INF/tld/mysample.tld" prefix="custom"%>
<html>
<head>
<title>list</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-31j">
</head>
<body>
<h2>リスト MySample</h2>
<f:view>
<h:dataTable value="#{listBean.mySamples}" var="item" border="1">
<h:column>
<f:facet name="header">
<h:outputText value="Select" />
</f:facet>
<custom:radioButton id="myRadioId1" name="myRadioCol"
overrideName="true" value="#{item.myid}"
itemValue="#{item.myid}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="ID" />
</f:facet>
<f:verbatim>id: </f:verbatim>
<h:outputText value="#{item.myid}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="VAL" />
</f:facet>
<f:verbatim>value: </f:verbatim>
<h:outputText value="#{item.myFlag}" />
</h:column>
</h:dataTable>
</f:view>
</body>
</html>s

以上です。表示だけはできるようになったはず。
(やれやれ。何で標準機能にしないんだろう・・・)

次回、radioボタンで送信されたデータを取得します。
.

0 件のコメント: