Unit 17 - 顯示訊息及對話框: 使用 PrimeFaces 元件
Unit 17
問題
使用者點擊按鈕且系統處理商業邏輯完成後, 應用系統在 Browser 顯示訊息或者對話框.
訊息顯示的 UI 可以在分類成:
- 可選擇性的點擊確認
- 必要性的點擊確認
- 例如: Dialog 或者 Modal Window
可選擇之方案
可選擇性的點擊確認的訊息顯示
訊息顯示後, 使用者的不需要中斷目前的操作, 回應訊息.
使用 PrimeFaces 的 p:growl
facelet.
Src: Growl component @ PrimeFaces Showcase
必要性的點擊確認的訊息顯示
訊息顯示後, 使用者的被中斷目前的操作, 回應訊息.
制式對話框
組成包括:
- 對話框標題
- 訊息
- 一個或多個按鈕
使用 PrimeFaces 的 p:confirmDialog
facelet.
Src: ConfirmDialog component @ PrimeFaces Showcase
自訂對話框
使用 JSF 頁面做為對話框, JSF 頁面依照需求自訂。
使用 PrimeFaces 的 Dialog Framework.
Src: PrimeFaces Showcase
實作練習 1: 使用 PrimeFaces 的 p:growl
facelet 顯示非強制性訊息
Step 建立一個 Java Web Project. 該專案使用 Maven builder.
Step 加入 JavaServer Faces framework 到專案
Step 在 pom.xml
加入 PrimeFaces 的 Dependency
1
2
3
4
5
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>7.0</version>
</dependency>
Step 建立 growl.xhtml
. 加入以下的 codes:
1
2
3
4
5
6
7
<p:growl id="growl" showDetail="true">
<p:autoUpdate />
</p:growl>
<h:form>
<p:commandButton value="p:messages"
action="#{messageBean.showMessage()}"/>
</h:form>
Step 建立一個 CDI Bean messageBean
, 建立方法 showMessage()
:
1
2
3
4
5
6
7
8
9
10
11
public String showMessage() {
//取得目前的 FacesContext
FacesContext facesContext = FacesContext.getCurrentInstance();
String clientId = "";
// 建立訊息
FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO,
"Info", "This is the information");
// 將訊息加入 Context, 由 p:grawl 顯示
facesContext.addMessage(clientId, facesMessage);
return null;
}
使用 PrimeFaces 內的 jQuery
PrimeFaces 內已經內含 jQuery. 如果再用 <script>
引入外部的 jQuery.js 會導致錯誤.
解決方式
- 如果頁面中有使用 PrimeFaces 的標籤, 則會自加引入 jQuery.js
- 如果頁面中沒有使用, 則在該頁面中加引入 PrimeFaces 內的 jQuery.js
1
<h:outputScript library="primefaces" name="jquery/jquery.js" />
Ref: How to use jQuery and jQuery plugins with PrimeFaces
實作練習 2: 制式對話框(1)
使用 p:confirmDialog
製作制式對話框
新增以下程式碼到 confirmDialog.xhtml
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<h:form>
<p:growl id="message" showDetail="true" />
<!-- Mark 1 -->
<p:commandButton type="button" onclick="PF('cd').show()" value="Destroy the World"/>
<!-- Mark 2 -->
<p:confirmDialog message="Are you sure about destroying the world?"
header="Initiating destroy process"
severity="alert" widgetVar="cd"
responsive="true">
<!-- Mark 3 -->
<p:commandButton value="Yes Sure" action="#{messageBean.showMessage()}"
update="message" oncomplete="PF('cd').hide()"/>
<p:commandButton value="Not Yet" onclick="PF('cd').hide();" type="button" />
</p:confirmDialog>
/h:form>
Mark 1 程式解說
- 在
p:commandButton
中使用onclick
屬性指定按鈕點擊時要執行的 JavaScript. PF('cd').show()
中PF
是 PrimeFaces 元件的選擇器,cd
則是使用wigetVar
屬性定義的變數。這個變數在p:confirmDialog
中被定義。show()
是p:confirmDialog
widget 的方法, 可以開啟 dialog; 使用close()
則可以關閉對話框。- 所以, 當點擊 Mark 1 下方的
p:commandButton
後, 會開啟p:confirmDialog
。
Mark 2 程式解說
- 使用
responsive
屬性, 依螢幕大小自動調整對話框的位置。
Mark 3 程式解說
- Mark 3 的兩個
p:commandButton
是對話框中按鈕。 - 第一個
p:commandButton
使用了三個屬性:action
,update
,oncomplete
。當點擊此按鈕後的執行過程:- 執行
action
屬性所關聯的 bean method - 執行 AJAX 更新, 更新
update
屬性所指定的元素 id - 執行
oncomplete
屬性的 JavaScript 程式碼
- 執行
進一步參考 Confirm Dialog @ PrimeFaces Documentation
實作練習 3: 制式對話框(2)
Use PrimeFaces.current().dialog().showMessageDynamic(facesMessage)
to show message.
Step. 建立頁面 dialogMessage.xhtml
1
2
3
4
<h:form>
<p:commandButton value='Notification'
action='#{messageBean.showDialogMessage("Hello")}' />
</h:form>
Step. 建立 action method
1
2
3
4
public void showDialogMessage(String info){
FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_INFO, info, info + " more details ...");
PrimeFaces.current().dialog().showMessageDynamic(facesMessage);
}
實作練習 4: 自訂對話框
Step 建立頁面 /dialogs/myDialog.xhml
, 其 head 及 body 如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<h:head>
<!-- Mark 1 -->
<title>Your Dialog Title</title>
</h:head>
<h:body>
<!-- Mark 2 -->
<h1> #{param['dialog-title']} </h1>
<p>
#{param['dialog-message']}
</p>
<p>
<h:form>
<!-- Mark 3 -->
<p:commandButton value="Train" action='#{messageBean.selectOption("train")}' />
<p:commandButton value="Bus" action='#{messageBean.selectOption("Bus")}'/>
<p:commandButton value="No Idea" action='#{messageBean.selectOption("No selection")}'/>
</h:form>
</p>
</h:body>
Mark 1
- 頁面的
title
元素的內容將成為對話框的標題
Mark 2
- 顯示此對話框時所傳送的請求參數。使用
param
自動變數取得 HTTP Request 中的參數。param
為 Map 資料結構,[]
內為 key 值。
Mark 3
- 對話框的按鈕
- 點擊後執行 bean method
selectOption(option:String)
, 此方法會:- 取得傳入參數
- 將傳入參數傳回給 host page, 使用 AJAX 方式
- 關閉對話框
Step 建立對話框的 host page: dialogFramework
1
2
3
4
5
6
7
8
<h:form>
<p:commandButton value="Show Dialog" action="#{messageBean.showDialog()}">
<p:ajax event="dialogReturn" listener="#{messageBean.onSelectTransportation}"
update="yourSelection"/>
</p:commandButton>
</h:form>
Your Selection: <h:outputText id="yourSelection"
value="#{messageBean.selectedTransportation}" />
- 點擊
p:commandButton
會執行showDialog()
方法, 開啟對話框 p:ajax
讓我們監聽關閉對話框所產生的 AJAX eventdialogReturn
p:ajax
的listener
屬性指定 event handler, 執行事件處理邏輯p:ajax
的update
屬性指定 AJAX Request 處理完成後, 要更新的頁面元素的 ID
Step 建立開啟、關閉及取得對話框回傳值的 action methods 及 action listener
建立開啟對話框的 bean method
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public String showDialog() {
// Dialog Options
Map<String, Object> options = new HashMap<String, Object>();
options.put("modal", true);
options.put("width", 640);
options.put("height", 340);
options.put("contentWidth", "100%");
options.put("contentHeight", "100%");
options.put("headerElement", "customheader");
// the JSF page to open as a dialog
String outcome = "/dialogs/myDialog";
// Request parameters sent to the target JSF page
Map<String, List<String>> params = new HashMap<>();
params.put("dialog-title", Arrays.asList("Select your transportation"));
params.put("dialog-message", Arrays.asList("Which one do you prefer?"));
// Open the target JSF page as a dialog
PrimeFaces.current().dialog().openDynamic(outcome, options, params);
return null;
}
- 在 Host Page 的 action method 執行
1
PrimeFaces.current().dialog().openDynamic(outcome, options, params);
以開啟對話框。
建立點擊對話框按鈕時執行的 action method
1
2
3
4
public String selectOption(String option){
PrimeFaces.current().dialog().closeDynamic(option);
return null;
}
- 在 Dialog Page 的 action method 執行:
1
PrimeFaces.current().dialog().closeDynamic(option);
以關閉對話框。
closeDynamic
方法中的參數將被傳入到產生的 AJAX event, 供 Host Page 使用
建立處理 dialogReturn
AJAX event 的 event listener 方法
1
2
3
4
public void onSelectTransportation(SelectEvent event){
String value = (String) event.getObject();
this.selectedTransportation = value;
}