Unit 09 - 在 Facelets Page 中使用 HTML 5 元素
目標
- 瞭解如何將 HTML 5 標籤標示成為 Facelets Tag (Pass-Through element)
- 瞭解如何在 Facelets Tag 中使用 HTML 5 標籤的元素 (Pass-Throuth attribute)
知識:
JSF 2.2 之後可以將 HTML 5 的元素或者特定的元素屬性送進去 JSF Engine 中處理.
Use Case 1: 在 Facelets Page 中使用 HTML 5 的”年-月”輸入元素
1
2
3
4
<label for="start">Start month:</label>
<input type="month" id="start" name="start"
min="2018-03" value="2018-05">
Ref: <input type="month">
@ developer.mozilla.org
要將此元素送進去 JSF engine 處理, 要使用 http://xmlns.jcp.org/jsf
namespace.
1
2
3
<label for="month">Expired Date</label>
<input jsf:id="month" type="month" value="#{processCard.expireDateStr}" />
在 <input>
中使用了 jsf
namespace, JSF engine 處理此元素時, 會將之視為 Facelets 元素, 為其建立相對應的 Facelets Tag.
所以, 我們可以在 <input>
中使用 EL 語法將元素屬性和 Bean 的屬性綁定在一起。
這種元素我們稱之為 Pass-Through Element。
JSF Engine 處理 Pass-Through Element 時會自動為 HTML 5 元素建立對應的 Facelets 元素, 兩者之間的對應關係參考 Table 8-4 How Facelets Renders HTML5 Elements。
例如, <a jsf:action=#{bean.actionMethod}> Click </a>
會產生相對應的 <h:commandButton action=#{bean.actionMethod}>
。
Use Case 2: 在 Facelet Tag 中使用 HTML 5 Input 的 placeholder
屬性
HTML 5 Input 提供 placeholder
屬性 HTML input placeholder Attribute.
但此屬性在 <h:InputXXX>
類別的 facelets tag 尚未支援. 要在 JSF Enging render 出來的結果中正確顯示此 placeholder
屬性, 必須將其送入 JSF Enging 中. 此種元素屬性稱之為 Pass-Through Attribute.
此時, 使用 http://xmlns.jcp.org/jsf/passthrough
namespace, 將特定的元素屬性標示為 Pass-Through Attribute。此元素會和 Facelet Tag 一起進入 JSF Engine, 並在 render 結果中出現.
例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:jsf="http://xmlns.jcp.org/jsf"
xmlns:ps="http://xmlns.jcp.org/jsf/passthrough"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
...
<label for="form:card"> Card: </label>
<input jsf:id="card" type="text" label="Card"
value="#{processCard.card}"
required="true"
requiredMessage="長度至少 13 碼"
ps:placeholder="長度至少 13 碼"
>
<f:validateLength minimum="13"/>
</input>
</html>
另外, 也可以使用 f:passThroughAttribute
傳送單個 HTML Element 屬性, 或者 f:passThroughAttributes
傳送多個屬性。參考 8.9 HTML5-Friendly Markup - Java Platform, Enterprise Edition: The Java EE Tutorial (Release 7)
實作練習
修改 Unit08 練習中的 fillCreditCardForm.xhtml
:
- 將表單中的 Amount 欄位該成使用
<input type="number">
輸入數字. - 將表單中的 Card 欄位加入
placeholder
屬性, 顯示 “長度至少 13 碼”
修改後的結果如下:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:jsf="http://xmlns.jcp.org/jsf"
xmlns:ps="http://xmlns.jcp.org/jsf/passthrough"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:head>
<title>Unit08: Fill form</title>
</h:head>
<h:body>
<h1>填寫信用卡</h1>
<h:form id="form">
<h:panelGrid columns="3">
Amount"
<input jsf:id="amount" type="number" label="Amount"
value="#{processCard.amount}"
required="true">
<f:convertNumber minFractionDigits="2" />
<f:validateDoubleRange minimum="10" maximum="10000"/>
</input>
<h:message for="amount" styleClass="errorMessage"/>
<label for="form:card"> Card: </label>
<input jsf:id="card" type="text" label="Card"
value="#{processCard.card}"
required="true"
requiredMessage="長度至少 13 碼"
ps:placeholder="1234567890123"
>
<f:validateLength minimum="13"/>
</input>
<h:message for="card" styleClass="errorMessage"/>
Expired Date (HTML 5 Month element):
<input jsf:id="month" type="month" value="#{processCard.expireDateStr}" />
</h:panelGrid>
<h:commandButton value="Process" action="/result" />
<h:commandButton value="Cancel" action="/index" immediate="true" />
</h:form>
</h:body>
</html>
複習問題
- 什麼是 “Pass-Through Element” ? 為什麼要設計此功能? 使用情境為何?
- 什麼是 “Pass-Through Attribute” ? 為什麼要設計此功能? 使用情境為何?
技術挑戰
PrimeFaces 的 p:inputText
有支援 placeholder
屬性. 此外, 還有提供豐富的輸入元件. 嘗試將 fillCreditCardForm.xhtml
上的輸入改成 PrimeFaces 的輸入元件. 參考: PrimeFaces Showcase