- 環境
- CentOS Linux release 7.8.2003 (Core)
- Eclipse IDE for Enterprise Java Developers.Version: 2020-03 (4.15.0)
- openjdk version "11.0.7" 2020-04-14 LTS
- JSF 2.3.9
JSFではid属性値がxhtmlでしてした値と異なる値で出力されることがある。
本にはname属性について記載されていたがid属性もコンポーネントツリーと対応関係がわかるようになっているのかもしれない。
FacesServletは、コンポーネントツリーからHTMLファイルを生成してブラウザに送信します。このような変換をレンダリングといいます。
レンダリングしてHTMLファイルにした後でも、内部にあるコンポーネントツリーとの対応関係がわかるように、バッキングビーンにバインドされるHTMLのタグには、次に示すようなname属性が埋め込まれます。
番号 : <input type="text" name="j_idt6:j_idt8" /><br />
わかりやすいJava EE ウェブシステム入門 - 秀和システム
問題1 : h:formタグの内側でid属性は指定した値にならない
h:formタグの外側では指定した通りのid属性値になる
h:inputText
のid属性値にoutOfFormを指定すると
<h:inputText id="outOfForm" value="formタグの外側では指定した通りのidになる" />
input
のid属性値はoutOfFormになる。
<input id="outOfForm" type="text" name="outOfForm" value="formタグの外側では指定した通りのidになる">
h:formタグの内側では「formタグのid属性値:指定したid属性値」になる
h:formタグにid属性を指定しないと「自動の属性値:指定したid属性値」になる
h:form
タグのid属性は指定しないで、h:inputText
のid属性値にinOfFormを指定すると
<h:form>
<h:inputText id="inOfForm" value="h:formタグにid属性を指定しないと「自動の属性値:指定したid属性値」になる" />
</h:form>
input
のid属性値はj_idt5:inOfFormになる。
<form id="j_idt5" name="j_idt5" method="post" action="/tryJsf/base.jsf" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="j_idt5" value="j_idt5">
<input id="j_idt5:inOfForm" type="text" name="j_idt5:inOfForm" value="h:formタグにid属性を指定しないと「自動の属性値:指定したid属性値」になる">
<input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="-6757148234097573315:8183558224686661226" autocomplete="off">
</form>
h:formタグにid属性を指定すると「formタグのid属性値:指定したid属性値」になる
h:form
タグのid属性値にformId、h:inputText
のid属性値にinOfFormを指定すると
<h:form id="formId">
<h:inputText id="inOfForm" value="h:formタグにid属性を指定すると「formタグのid属性値:指定したid属性値」になる" />
</h:form>
input
のid属性値はformId:inOfFormになる。
<form id="formId" name="formId" method="post" action="/tryJsf/base.jsf" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="formId" value="formId">
<input id="formId:inOfForm" type="text" name="formId:inOfForm" value="h:formタグにid属性を指定すると「formタグのid属性値:指定したid属性値」になる">
<input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="1982632179815695771:1244710352148896782" autocomplete="off">
</form>
解決策1 : h:formタグにprependId="false"を指定するとid属性値が指定した値になる
prependId
Flag indicating whether or not this form should prepend its id to its descendent's id during the clientId generation process. If this flag is not set, the default value is true.
JSF 2.2 View Declaration Language: Facelets Variant
(ざっくり訳)id生成中にformのIDをその子孫のIDの前に付加するかどうかを示すフラグ。デフォルト値はtrueです。
h:form
タグのid属性値にformId、h:inputText
のid属性値にinOfFormを指定すると
<h:form id="formId" prependId="false">
<h:inputText id="inOfForm" value="h:formタグにprependId=falseを指定するとid属性が指定した値になる" />
</h:form>
input
のid属性値はinOfFormになる。
<form id="formId" name="formId" method="post" action="/tryJsf/base.jsf" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="formId" value="formId">
<input id="inOfForm" type="text" name="inOfForm" value="h:formタグにprependId=falseを指定するとid属性が指定した値になる">
<input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="-3193809963809428842:-8198161006116065679" autocomplete="off">
</form>
問題2 : ui:repeatタグ内側でid属性値は指定した値にならない
h:formタグの外側でも内側でも「自動の属性値:index番号:指定したid属性値」になる
h:inputText
のid属性値にinOfRepeatを指定すると
<ui:repeat var="item" varStatus="stat" value="#{idBean.array}">
<h:inputText id="inOfRepeat#{stat.index}" value="h:formタグの内側でui:repeatタグを使うとid属性値は指定した値にならない" />
</ui:repeat>
input
のid属性値はj_idt5:{index番号}:inOfRepeatになる。
<input id="j_idt5:0:inOfRepeat" type="text" name="j_idt5:0:inOfRepeat">
<input id="j_idt5:1:inOfRepeat" type="text" name="j_idt5:1:inOfRepeat">
h:formタグにid属性を指定しないと「自動の属性値:自動の属性値:index番号:指定したid属性値」になる
h:form
タグのid属性は指定しないで、h:inputText
のid属性値に**inOfRepeat{index番号}**を指定すると
<h:form>
<ui:repeat var="item" varStatus="stat" value="#{idBean.array}">
<h:inputText id="inOfRepeat#{stat.index}" value="h:formタグの内側でui:repeatタグを使うとid属性値は指定した値にならない" />
</ui:repeat>
</h:form>
input
のid属性値はj_idt5:j_idt9:{index番号}:inOfRepeatになる。
<form id="j_idt5" name="j_idt5" method="post" action="/tryJsf/base.jsf" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="j_idt5" value="j_idt5">
<input id="j_idt5:j_idt9:0:inOfRepeat" type="text" name="j_idt5:j_idt9:0:inOfRepeat">
<input id="j_idt5:j_idt9:1:inOfRepeat" type="text" name="j_idt5:j_idt9:1:inOfRepeat">
<input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="8291831575234858658:4144786523139149206" autocomplete="off">
</form>
h:formタグにid属性を指定すると「formタグのid属性値:自動の属性値:index番号:指定したid属性値」になる
h:form
タグのid属性値にformId、h:inputText
のid属性値に**inOfRepeat{index番号}**を指定すると
<h:form id="formId">
<ui:repeat var="item" varStatus="stat" value="#{idBean.array}">
<h:inputText id="inOfRepeat#{stat.index}" value="h:formタグの内側でui:repeatタグを使うとid属性値は指定した値にならない" />
</ui:repeat>
</h:form>
input
のid属性値はformId:j_idt9:{index番号}:inOfRepeatになる。
<form id="formId" name="formId" method="post" action="/tryJsf/base.jsf" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="formId" value="formId">
<input id="formId:j_idt9:0:inOfRepeat" type="text" name="formId:j_idt9:0:inOfRepeat">
<input id="formId:j_idt9:1:inOfRepeat" type="text" name="formId:j_idt9:1:inOfRepeat">
<input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="-9123594053057548780:-7376239985257011779" autocomplete="off">
</form>
h:formタグにprependId="false"を指定してもid属性値は指定した値にならない
h:form
タグにprependId="false"
を指定しても
<h:form id="formId" prependId="false">
<ui:repeat var="item" varStatus="stat" value="#{idBean.array}">
<h:inputText id="inOfRepeat#{stat.index}" value="h:formタグの内側でui:repeatタグを使うとid属性値は指定した値にならない" />
</ui:repeat>
</h:form>
form
タグのid属性値がくっつかなくなるだけ。
<form id="formId" name="formId" method="post" action="/tryJsf/base.jsf" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="formId" value="formId">
<input id="j_idt9:0:inOfRepeat" type="text" name="j_idt9:0:inOfRepeat">
<input id="j_idt9:1:inOfRepeat" type="text" name="j_idt9:1:inOfRepeat">
<input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="-915378070197893309:-5208595187307997788" autocomplete="off">
</form>
解決策1 : jsfのタグをやめてhtmlのタグで書く
注意 : id属性値が一意になるように考えて書かないと残念なことになる
とてつもなく微妙な策である。
input
のid属性値に**inOfRepeat{index番号}**を指定すると
<h:form id="formId">
<ui:repeat var="item" varStatus="stat" value="#{idBean.array}">
<input tyep="text" id="inOfRepeat#{stat.index}" value="h:formタグの内側でui:repeatタグを使うとid属性値は指定した値にならない" />
</ui:repeat>
</h:form>
input
のid属性値は**inOfRepeat{index番号}**になる。
JSFワールドから外れているためprependId="false"
がなくてもh:form
タグのid属性値が影響しない。
<form id="formId" name="formId" method="post" action="/tryJsf/base.jsf" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="formId" value="formId">
<input tyep="text" id="inOfRepeat0" value="h:formタグの内側でui:repeatタグを使うとid属性値は指定した値にならない">
<input tyep="text" id="inOfRepeat1" value="h:formタグの内側でui:repeatタグを使うとid属性値は指定した値にならない">
<input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="-3641841499499477715:2017944983286472561" autocomplete="off">
</form>
解決策2 : ui:repeatタグをやめてc:forEachタグを使う
注意 : id属性値が一意になるように考えて書かないと残念なことになる
JSTL Coreタグ(c:)は、JSPより継承されたタグなのでJSF的なところが薄いのか・・・
h:form
タグのid属性値にformId、h:inputText
のid属性値に**inOfRepeat{index番号}**を指定すると
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core"> <!--<<<追記-->
<h:form id="formId">
<c:forEach var="item" varStatus="stat" items="#{idBean.array}">
<h:inputText id="inOfRepeat#{stat.index}" value="h:formタグの内側でui:repeatタグを使うとid属性値は指定した値にならない"/>
</c:forEach>
</h:form>
input
のid属性値は**formId:inOfRepeat{index番号}**になる。
<form id="formId" name="formId" method="post" action="/tryJsf/base.jsf" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="formId" value="formId">
<input id="formId:inOfRepeat0" type="text" name="formId:inOfRepeat0" value="h:formタグの内側でui:repeatタグを使うとid属性値は指定した値にならない">
<input id="formId:inOfRepeat1" type="text" name="formId:inOfRepeat1" value="h:formタグの内側でui:repeatタグを使うとid属性値は指定した値にならない">
<input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="7276136016284590450:-4018393601695065919" autocomplete="off">
</form>
h:form
タグのid属性値をくっつけたくなければprependId="false"
を指定する。
<h:form id="formId" prependId="false">
...以降前と同じ...
<form id="formId" name="formId" method="post" action="/tryJsf/base.jsf" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="formId" value="formId">
<input id="inOfRepeat0" type="text" name="inOfRepeat0" value="h:formタグの内側でui:repeatタグを使うとid属性値は指定した値にならない">
<input id="inOfRepeat1" type="text" name="inOfRepeat1" value="h:formタグの内側でui:repeatタグを使うとid属性値は指定した値にならない">
<input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="-4294574413761401134:-7748270303136609237" autocomplete="off">
</form>