2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

JSFでid属性を指定する方法

Last updated at Posted at 2020-08-07
  • 環境
    • 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属性値にformIdh: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属性値にformIdh: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属性値にformIdh: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属性値にformIdh: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>
2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?