; last updated - 3 minutes read

I've read a lot about the new JSF 2.2 HTML5 input fields, but until today I didn't realize I hadn't read a comprehensive introduction about this feature. I used to be happy with the short examples I was presented at conferences. However, there's more than just <input type="text" jsf:value="#{my.favoriteBean.attribute}" />. As it happens, the documentation hides in plain sight. The JavaEE Javadoc tells you everything you have to know about the Mapping between HTML tags and JSF components. For the sake of convenience, this article summarizes the key points.

The general idea is to enable a web designer to design your JSF page without running a server. So it's native HTML, and it should display nicely in a browser if opened as a simple HMTL file. Putting it in a nutshell, renaming a JSF file from *.xhtml to *.html doesn't modify the design of the page.

So most important HTML attributes are supported. Many of these tags are translated to their corresponding core JSF tags without further ado:

  • <head /> becomes <h:head />
  • <link /> becomes <h:outputStylesheet />
  • <script /> becomes <h:outputScript />
  • <body /> becomes <h:body />
  • <form /> becomes <h:form />
  • <label /> becomes <h:outputLabel />
  • <textarea /> becomes <h:inputTextarea />
  • <img /> becomes <h:h:graphicImage />

Well... that's almost true. The tags are only translated if one of their attributes belongs to the new namespace "http://xmlns.jcp.org/jsf". Following the usual coding conventions, this means you need at least one "jsf:" attribute. I wonder if there's an application having such an attributes in its <h:head> or <h:body> statement. So, effectively <head> is never converted to <h:head>.

The remaining four HTML tags are treated in a more versatile and flexible way. JSF evaluates an attribute of the tag to decide which JSF components is used:

  • <a jsf:action="..." /> and <a jsf:actionListener="..." /> become <h:commandLink />
  • <a jsf:value="..." /> becomes <h:outputLink />
  • <a jsf:outcome="..." /> becomes <h:link />
  • <button jsf:outcome="..." /> becomes <h:button />
  • <button /> (without JSF attribute) becomes <h:commandButton />
  • <select jsf:multiple="..." /> becomes <h:selectManyListbox />
  • <select jsf: /> becomes <h:selectOneListbox />

This last component is the input field, which is translated to so many different widgets it deserves a table of its own. Attribute that decides what becomes of an <input /> is the type attribute:

  • type="button" makes it an <h:commandButton />
  • type="checkbox" makes it an <h:selectBooleanCheckbox />
  • type="file" makes it an <h:inputFile />
  • type="hidden" makes it an <h:inputHidden />
  • type="password" makes it an <h:inputSecret />
  • type="reset" makes it an <h:commandButton />
  • type="submit" makes it an <h:commandButton />
  • Every other type makes it an <h:inputText />. This includes color, date, datetime, datetime-local, email, month, number, range, search, time, url, week.

Note that it really depends on the type. Omit the type, and you end up with a rather useless HTML <input /> field that isn't connected to JSF. This is even the case if you add a jsf:value:

results in this HTML code:

It's not even part of the JSF component tree. This becomes visible if you put several <input /> field in a <panelGrid /> without adding the type attributes. The input fields are treated as a single JSF component and put into the same column (or rather: table cell) of the panel grid.


Comments