PDF:

Các ứng dụng Craft Ajax sử dụng JSF với CSS và
Javascript, Phần 1: Tăng cường diện mạo của các trang
JSF của bạn
Khám phá sự hỗ trợ CSS trong các thành phần JSF chuẩn
Andrei Cioroianu
Nhà phát triển và Tư vấn Java cao cấp
Devsphere
18 12 2009
Các ứng dụng Web điển hình yêu cầu sử dụng Cascading Style Sheets (CSS-Các bảng định
kiểu nhiều tầng) và JavaScript, cùng với một khung công tác phía-máy chủ, như là JavaServer
Faces (JSF). CSS cho phép bạn thay đổi các đặc tính trực quan của các thành phần Web trong
Ajax và các ứng dụng khác để chúng có thể có một phong cách thân mật và đặc biệt. Trong bài
đầu tiên của loạt bài có hai phần này, hãy khám phá cách sử dụng các thuộc tính có liên quan
đến CSS của các thành phần JSF chuẩn. Ngoài ra, tìm hiểu cách tạo một thành phần JSF tuỳ
chỉnh để thiết lập các phong cách mặc định của các thành phần lồng nhau, làm cho nó dễ dàng
đảm bảo một phong cách phù hợp cho tất cả các trang của ứng dụng Web của bạn. Bạn cũng có
thể sử dụng kỹ thuật này để thiết lập theo chương trình các thuộc tính thành phần khác, như bạn
sẽ thấy trong Phần 2, phần này sẽ chỉ ra cách làm cho các biểu mẫu JSF động hơn khi sử dụng
JavaScript.
Xem thêm bài trong loạt bài này
Sử dụng các thuộc tính phong cách của các thành phần JSF
Hầu như mọi thành phần JSF HTML có hai thuộc tính tùy chọn có tên là style và styleClass, được
hoàn trả như các thuộc tính style (phong cách) và class (lớp) trong kết quả HTML. Một số các
thành phần, như <h:dataTable> và <h:panelGrid>, có các thuộc tính phong cách bổ sung cho các
khía cạnh của chúng. Phần này bàn về các thuộc tính liên quan đến CSS của thư viện JSF HTML.
Liên kết tệp CSS đến các trang JSF của bạn
Nếu một trang Web có phong cách độc đáo, bạn có thể định nghĩa các quy tắc phong cách trong
phần tử <style> của tiêu đề của trang. Bạn cũng có thể xác định thông tin phong cách cho một
thành phần JSF bằng cách sử dụng thuộc tính style. Tuy nhiên, trong hầu hết trường hợp, có lẽ
© Copyright IBM Corporation 2009
Các ứng dụng Craft Ajax sử dụng JSF với CSS và Javascript,
Phần 1: Tăng cường diện mạo của các trang JSF của bạn
Nhẫn hiệu đăng ký
Trang 1 của 20
developerWorks®
ibm.com/developerWorks/vn/
bạn sẽ thích bao gồm các quy tắc phong cách trong các tệp CSS riêng để bạn có thể áp dụng
chúng trên nhiều trang. Bạn có thể liên kết một bảng định kiểu ngoài đến một trang Web bằng cách
sử dụng thẻ <link> như trong Liệt kê 1:
Liệt kê 1. Sử dụng thẻ <link>
<link rel="stylesheet" type="text/css"
href="${pageContext.request.contextPath}/MyStyles.css">
<link rel="stylesheet" type="text/css"
href="<%=request.getContextPath()%>/styles/MoreStyles.css">
Sử dụng MyFaces Tomahawk
Nếu bạn thích sử dụng các thành phần JSF thay cho các thẻ HTML, bạn có thể sử dụng các
thành phần của <t:stylesheet> MyFaces Tomahawk, để trả về thẻ <link> cho bạn.
Trong Liệt kê 1, các thuộc tính href chứa các URL tuyệt đối. Bạn cũng có thể sử dụng các
đường liên kết tương đối cho các tệp CSS, nhưng tốt hơn là chứa đường dẫn ngữ cảnh với
${pageContext.request.contextPath} hoặc <%=request.getContextPath()%> nếu các URL của
các trang JSF chứa tiền tố /faces/ (các bề mặt). Trong trường hợp này, đường liên kết tương
đối bất kỳ đến một tệp, hình ảnh hoặc một số tài nguyên khác của CSS sẽ dẫn đến một yêu cầu
HTTP có chứa tiền tố /faces/ có nghĩa là các tệp không phải JSF sẽ được các Faces servlet sử
dụng. Servet này hoạt động, nhưng không hiệu quả. Bạn có thể sử dụng an toàn các đường liên kết
tương đối trong các ứng dụng dựa trên JSF của bạn nếu bạn yêu cầu các trang JSF sử dụng hậu tố
.faces, để loại bỏ vấn đề được mô tả ở trên.
Định nghĩa và sử dụng các quy tắc phong cách
Các tệp CSS chứa các quy tắc của bảng định kiểu áp dụng cho các phần tử HTML, các phần tử này
có thể được các thành phần JSF hoàn trả, hay có thể đơn giản được bao gồm giữa các thành phần
của trang JSF. Ví dụ, nếu bạn muốn các đường liên kết của bạn được gạch chân khi dùng chuột lướt
trên chúng, thì bạn sẽ sử dụng các quy tắc sau (xem Liệt kê 2):
Liệt kê 2. Các quy tắc phong cách cho các đường liên kết
a { text-decoration: none; }
a:hover { text-decoration: underline; }
Các quy tắc này sẽ được áp dụng cho đường liên kết bất kỳ, cho dù phần tử <a> trực tiếp được tính
đến trong trang JSF, hoặc nó được một thành phần JSF tạo như <h:commandLink> (xem Liệt kê 3):
Liệt kê 3. Các đường liên kết HTML và JSF
<a href="LinkStyles.faces">HTML Link</a>
<h:commandLink value="JSF Link"/>
Liệt kê 4 cho thấy cách bạn có thể chỉ định các phong cách nội tuyến cho một thành phần JSF.
Liệt kê 4. Thành phần JSF với thuộc tính phong cách
<h:commandLink value="Red Link" style="color: red"/>
Các ứng dụng Craft Ajax sử dụng JSF với CSS và Javascript,
Phần 1: Tăng cường diện mạo của các trang JSF của bạn
Trang 2 của 20
ibm.com/developerWorks/vn/
developerWorks®
Tuy nhiên, trong hầu hết trường hợp, bạn sẽ định nghĩa các lớp phong cách (xem Liệt kê 5) trong
các tệp CSS để bạn có thể sử dụng các quy tắc phong cách giống nhau cho nhiều thành phần.
Liệt kê 5. Ví dụ về lớp phong cách
.GreenClass { color: green; }
Tên lớp phong cách sẽ được cung cấp qua thuộc tính styleClass đến các thành phần JSF như
trong Liệt kê 6.
Liệt kê 6. Thành phần JSF với thuộc tính styleClass
<h:commandLink value="Green Link" styleClass="GreenClass"/>
Bạn có thể tìm mã từ các liệt kê 1-6 trong các tệp LinkStyles.jsp và LinkStyles.css từ đường
liên kết mã ví dụ trong bài viết này (xem Tải về).
Các thành phần JSF có nhiều lớp phong cách
Như đã đề cập ở trên, một số thành phần JSF có nhiều hơn một thuộc tính phong cách. Ví dụ,
<h:message> và <h:messages> có mười thuộc tính liên quan đến CSS tiếp theo:
•
•
•
•
•
•
•
•
•
•
style
styleClass
errorClass
errorStyle
fatalClass
fatalStyle
infoClass
infoStyle
warnClass
warnStyle
Chỉ có hai trong số đó được chọn cho mỗi thông báo, tùy thuộc vào mức độ nghiêm trọng của
thông báo đang được hoàn trả. Các thẻ JSF của các thành phần UISelectOne và UISelectMany
chấp nhận các thuộc tính enabledClass và disabledClass cho các mục của các liệt kê được đưa
ra. Các thẻ <h:dataTable> và <h:panelGrid> có các thuộc tính lớp cho bảng chính, tiêu đề (đầu
trang), cuối trang, các hàng và các cột. Các ví dụ sau cho thấy cách sử dụng các thuộc tính liên
quan đến CSS của một bảng dữ liệu được hiển thị trong ảnh chụp màn hình tiếp theo.
Các ứng dụng Craft Ajax sử dụng JSF với CSS và Javascript,
Phần 1: Tăng cường diện mạo của các trang JSF của bạn
Trang 3 của 20
developerWorks®
ibm.com/developerWorks/vn/
Hình 1. Ví dụ TableStyles
Trước tiên, bạn cần một mô hình dữ liệu cho thành phần bảng. Lớp OrderBean (hiển thị trong Liệt kê
7) mở rộng javax.faces.model.ArrayDataModel. Một ứng dụng thực sẽ lấy dữ liệu của mô hình từ
một cơ sở dữ liệu, nhưng để đơn giản, OrderBean được khởi tạo từ một mảng tĩnh.
Liệt kê 7. Ví dụ OrderBean
package jsfcssjs;
import javax.faces.model.ArrayDataModel;
public class OrderBean extends ArrayDataModel {
private static ItemBean items[] = new ItemBean[] {
new ItemBean("Domain Name",
3,
7.99f),
new ItemBean("SSL Certificate",
1, 119.00f),
new ItemBean("Web Hosting",
1, 19.95f),
new ItemBean("Email Box",
20,
0.15f),
new ItemBean("E-Commerce Setup",
1, 25.00f),
new ItemBean("Technical Support", 1, 50.00f)
};
public OrderBean() {
super(items);
}
public float getTotalPrice() {
float total = 0;
for (int i = 0; i < items.length; i++)
total += items[i].getItemPrice();
return total;
}
}
Các ứng dụng Craft Ajax sử dụng JSF với CSS và Javascript,
Phần 1: Tăng cường diện mạo của các trang JSF của bạn
Trang 4 của 20
ibm.com/developerWorks/vn/
developerWorks®
Lớp ItemBean (xem Liệt kê 8) có ba đặc tính đọc/ghi có tên là description (mô tả), quantity, (số
lượng) và unitPrice (đơn giá) và một đặc tính chỉ đọc tên là itemPrice.
Liệt kê 8. Ví dụ ItemBean
package jsfcssjs;
public class ItemBean implements java.io.Serializable {
private String description;
private int quantity;
private float unitPrice;
public ItemBean() {
}
public ItemBean(String description, int quantity, float unitPrice) {
this.description = description;
this.quantity = quantity;
this.unitPrice = unitPrice;
}
...
public float getItemPrice() {
return unitPrice * quantity;
}
}
Tệp TableStyles.css (hiển thị trong Liệt kê 9) chứa các phong cách được sử dụng cho bảng dữ liệu.
Liệt kê 9. Ví dụ TableStyles.css
body
.tablebg
.header
.footer
.text
.number
.graybg
.whitebg
{
{
{
{
{
{
{
{
font-family: Arial; }
background-color: #D0D0A0; }
font-weight: bold; }
font-weight: bold; }
text-align: left; }
text-align: right; }
background-color: #DDDDDD; }
background-color: #FFFFFF; }
Ví dụ TableStyles.jsp jsp (xem Liệt kê 10) có chứa một thành phần bảng JSF có sử dụng các lớp
phong cách được định nghĩa trong TableStyles.css. Sử dụng giá trị của thuộc tính styleClass cho
phần tử <table>. Các thuộc tính headerClass và footerClass xác định các phong cách cho các ô
tiêu đề và cuối trang của bảng. Thuộc tính columnClasses chứa danh sách có phân tách bằng một
dấu phẩy của các lớp được sử dụng cho các phần tử <td> của các ô dữ liệu.
Một danh sách khác của các lớp có thể được xác định thông qua thuộc tính rowClasses. Các lớp
này được sử dụng cho các phần tử <tr> của bảng. Trong ví dụ TableStyles.jsp, chỉ có hai lớp
hàng, nhưng bảng có sáu hàng. Trình hoàn trả (renderer) JSF của thành phần <h:dataTable> sẽ
thay thế hai lớp phong cách, khi sử dụng lớp graybg cho các hàng đầu tiên, thứ ba và thứ năm, và
lớp whitebg cho các hàng thứ hai, thứ tư và thứ sáu. Thuộc tính var định nghĩa một biến có tên là
row (hàng), được dùng để truy cập dữ liệu hàng hiện tại trong khi hoàn trả. Toàn bộ dữ liệu được lấy
ra từ mô hình orderBean, nó được liên kết tới bảng này thông qua thuộc tính value (giá trị).
Các ứng dụng Craft Ajax sử dụng JSF với CSS và Javascript,
Phần 1: Tăng cường diện mạo của các trang JSF của bạn
Trang 5 của 20
developerWorks®
ibm.com/developerWorks/vn/
Liệt kê 10. Ví dụ TableStyles.jsp
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<f:view>
<html>
<head>
<title>Order Table</title>
<link rel="stylesheet" type="text/css"
href="<%=request.getContextPath()%>/styles/TableStyles.css">
</head>
<body>
<h1>Order Table</h1>
<h:dataTable id="table" var="row" value="#{orderBean}"
styleClass="tablebg" headerClass="header" footerClass="footer"
columnClasses="text,number,number,number"
rowClasses="graybg,whitebg" border="0" cellpadding="5">
<h:column>
<f:facet name="header">
<h:outputText value="Description"/>
</f:facet>
<h:outputText value="#{row.description}"/>
<f:facet name="footer">
<h:outputText value="Total Price"/>
</f:facet>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Quantity"/>
</f:facet>
<h:outputText value="#{row.quantity}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Unit Price"/>
</f:facet>
<h:outputText value="#{row.unitPrice}">
<f:convertNumber type="currency" currencyCode="USD"
minFractionDigits="2" maxFractionDigits="2"/>
</h:outputText>
</h:column>
<h:column footerClass="footer number">
<f:facet name="header">
<h:outputText value="Item Price"/>
</f:facet>
<h:outputText value="#{row.itemPrice}">
<f:convertNumber type="currency" currencyCode="USD"
minFractionDigits="2" maxFractionDigits="2"/>
</h:outputText>
<f:facet name="footer">
<h:outputText value="#{orderBean.totalPrice}">
<f:convertNumber type="currency" currencyCode="USD"
minFractionDigits="2" maxFractionDigits="2"/>
</h:outputText>
</f:facet>
</h:column>
</h:dataTable>
</body>
</html>
</f:view>
Liệt kê 11 hiển thị HTML được trang TableStyles.jsp tạo ra.
Các ứng dụng Craft Ajax sử dụng JSF với CSS và Javascript,
Phần 1: Tăng cường diện mạo của các trang JSF của bạn
Trang 6 của 20
ibm.com/developerWorks/vn/
developerWorks®
Liệt kê 11. TableStyles.jsp tạo ra HTML
<html>
<head>
<title>Order Table</title>
<link rel="stylesheet" type="text/css"
href="/jsf12css/styles/TableStyles.css">
</head>
<body>
<h1>Order Table</h1>
<table id="table" class="tablebg" border="0" cellpadding="5">
<thead>
<tr>
<th class="header" scope="col">Description</th>
<th class="header" scope="col">Quantity</th>
<th class="header" scope="col">Unit Price</th>
<th class="header" scope="col">Item Price</th>
</tr>
</thead>
<tfoot>
<tr>
<td class="footer">Total Price</td>
<td class="footer"></td>
<td class="footer"></td>
<td class="footer number">$240.92</td>
</tr>
</tfoot>
<tbody>
<tr class="graybg">
<td class="text">Domain Name</td>
<td class="number">3</td>
<td class="number">$7.99</td>
<td class="number">$23.97</td>
</tr>
<tr class="whitebg">
<td class="text">SSL Certificate</td>
<td class="number">1</td>
<td class="number">$119.00</td>
<td class="number">$119.00</td>
</tr>
<tr class="graybg">
...
</tr>
<tr class="whitebg">
...
</tr>
<tr class="graybg">
...
</tr>
<tr class="whitebg">
...
</tr>
</tbody>
</table>
</body>
</html>
Thành phần <h:column> còn lại của bảng JSF từ ví dụ TableStyles.jsp sử dụng thuộc tính
footerClass để xác định hai lớp cho ô cuối trang hiển thị tổng số đơn đặt hàng. Các lớp footer
(cuối trang) và number (số) sẽ được sử dụng cho phần tử <td> của ô cuối trang. Thuộc tính
footerClass của thành phần <h:column> chỉ có sẵn trong phiên bản JSF 1.2. Nếu bạn sử dụng một
phiên bản JSF có trước, bạn cần bao bọc thành phần <h:outputText> để trả về tổng số này trong
Các ứng dụng Craft Ajax sử dụng JSF với CSS và Javascript,
Phần 1: Tăng cường diện mạo của các trang JSF của bạn
Trang 7 của 20
developerWorks®
ibm.com/developerWorks/vn/
một phần tử <div> để có thể thêm hiệu ứng sắp thẳng hàng của lớp number (xem Liệt kê 12). Tư liệu
mã nguồn có chứa các mẫu mã cho cả hai phiên bản JSF 1.1 và JSF 1.2.
Liệt kê 12. Phiên bản JSF 1.1 của ví dụ TableStyles.jsp
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<f:view>
...
<h:dataTable ...>
...
<h:column>
...
<f:facet name="footer">
<h:panelGroup>
<f:verbatim><div class="number"></f:verbatim>
<h:outputText value="#{orderBean.totalPrice}">
<f:convertNumber type="currency" currencyCode="USD"
minFractionDigits="2" maxFractionDigits="2"/>
</h:outputText>
<f:verbatim></div></f:verbatim>
</h:panelGroup>
</f:facet>
</h:column>
</h:dataTable>
...
</f:view>
Thiết lập các phong cách mặc định cho các thành phần JSF
Khi xây dựng các ứng dụng lớn có nhiều trang JSF, bạn có thể không thích ý tưởng thiết lập thủ
công thuộc tính styleClass cho mọi cá thể thành phần. Các thành phần JSF HTML chuẩn không
có các phong cách mặc định, nhưng khi bạn sẽ thấy trong phần này, có thể đi ngang qua cây thành
phần JSF và thiết lập theo chương trình các lớp phong cách mặc định. Để thực hiện thao tác này,
bạn cần phải biết cách tạo các cây này và cách tạo HTML.
Hiểu cách xây dựng các cây thành phần JSF
Tất cả các yêu cầu bề mặt (faces) bị chặn bởi Faces Servlet, được cấu hình trong bộ mô tả web.xml
của bất kỳ ứng dụng Web dựa trên JSF nào. Đối với mỗi yêu cầu, Faces Servlet khởi tạo một đối
tượng javax.faces.context.FacesContext và gọi các phương thức execute() và render() của
một cá thể javax.faces.lifecycle.Lifecycle. Phương thức execute() xử lý tất cả các giai đoạn
của yêu cầu JSF xử lý vòng đời, trừ một giai đoạn cuối cùng (có tên là Render Response), được
phương thức render() thực hiện.
Các phương thức lưu trữ trạng thái
Tùy thuộc vào giá trị của tham số ngữ cảnh javax.faces.STATE_SAVING_METHOD tham
số này có thể được thiết lập trong tệp web.xml, các cây thành phần được lưu trữ trên máy
chủ hoặc trên máy khách. Việc thực hiện JSF có thể sử dụng quy mô session (phiên làm việc)
để duy trì các cây thành phần ở phía máy chủ. Phương thức này hiệu quả, nhưng khung công
tác JSF có thể bị lẫn lộn nếu người dùng nhấn nút Back (Quay lại) của trình duyệt, trả về một
biểu mẫu đã gửi đi. Thật tốt để lưu trữ mỗi cây thành phần ở phía máy khách ở đó một phần
tử biểu mẫu ẩn giữ bản sao theo thứ tự của cây có liên quan đến thể hiện của trang. Việc lưu
trữ cây thành phần ở phía máy khách làm tăng lưu lượng tuyến và yêu cầu các nguồn tài
Các ứng dụng Craft Ajax sử dụng JSF với CSS và Javascript,
Phần 1: Tăng cường diện mạo của các trang JSF của bạn
Trang 8 của 20
ibm.com/developerWorks/vn/
developerWorks®
nguyên CPU bổ sung thêm để sắp xếp theo thứ tự và sắp xếp không theo thứ tự các cây đối
tượng, nhưng phương thức này tin cậy hơn so với việc sử dụng quy mô session.
Trong giai đoạn đầu (có tên Restore View (Khung nhìn khôi phục lại)), việc thực
hiện JSF nhận được trình xử lý (handler) khung nhìn của ứng dụng, đó là cá thể
javax.faces.application.ViewHandler, và gọi phương thức restoreView() nếu yêu cầu này là gửi
thông báo lại (ví dụ, người dùng nhấn vào một nút Submit-Gửi đi). Trong trường hợp này, cây thành
phần đã được xây dựng và được lưu trong lúc xử lý một yêu cầu Faces trước đó (xem phần bên về
các phương thức lưu trữ trạng thái).
Nếu yêu cầu hiện tại không phải là gửi một thông báo trả lại (ví dụ, người dùng nhấn vào một
đường liên kết Faces), thì việc thực hiện JSF gọi phương thức renderResponse() của phương thức
FacesContext và createView() hiện có của cá thể ViewHandler. Cuộc gọi renderResponse() chỉ dẫn
cho việc thực hiện JSF nhảy từ giai đoạn hiện tại là Restore View, đến giai đoạn Render Response
(Đáp ứng hoàn trả). Phương thức createView() của trình xử lý khung nhìn mặc định chỉ tạo ra
một thành phần javax.faces.component.UIViewRoot. Phần còn lại của cây sẽ được tạo ra trong
giai đoạn Render Response, khi việc thực hiện JSF gọi phương thức renderView() của trình xử lý
khung nhìn.
Cho dù cây thành phần được khôi phục lại hoặc phải được tạo, việc thực hiện JSF chuyển tiếp yêu
cầu HTTP đến một trang JSF có liên quan tại một số điểm trong quá trình thực hiện phương thức
renderView(). Ví dụ, nếu bạn đã yêu cầu /MyApp/MyPage.faces hoặc /MyApp/faces/MyPage.jsp,
URI của trang JSF đã thực hiện là /MyApp/MyPage.jsp.
Trang JSF bất kỳ có chứa thẻ thành phần, như <f:view> và <h:form>, được các trình xử lý
thẻ JSP hỗ trợ. Đây là những lớp Java™ thực hiện các giao diện được định nghĩa trong gói
javax.servlet.jsp.tagext. Khi trang này được thực hiện, thùng chứa (container) JSP tạo
các cá thể của các trình xử lý thẻ và gọi các phương thức của chúng. Trình xử lý thẻ của một
thành phần JSF 1.2 bất kỳ mở rộng javax.faces.webapp.UIComponentELTag. Nếu bạn sử dụng
API của JSF 1.1, lớp của trình xử lý thẻ mở rộng javax.faces.webapp.UIComponentTag hoặc
javax.faces.webapp.UIComponentBodyTag. Bất kể bạn sử dụng phiên bản JSF nào, thì các trình xử
lý thẻ JSF vẫn tạo các cá thể thành phần trong giai đoạn Render Response nếu cây thành phần
chưa được phục hồi trong giai đoạn Restore View.
Bạn có thể bị lôi cuốn vào việc thực hiện javax.faces.event.PhaseListener để thiết lập các phong
cách mặc định, nhưng điều này sẽ không hoạt động khi người dùng yêu cầu một trang bằng cách
nhấn vào một đường liên kết hoặc nhập vào URL trong trình duyệt Web. Trong trường hợp này, việc
thực hiện JSF không thể khôi phục lại cây thành phần, lẽ ra phải được tạo trong giai đoạn Render
Response. Trước giai đoạn cuối này, cây thành phần không tồn tại và sau khi trả về đáp ứng, thật
quá muộn để cập nhật các phong cách thành phần vì đầu ra HTML đã được tạo. Vì vậy, các phong
cách mặc định phải được thiết lập trong quá trình thực hiện giai đoạn Render Response trước khi
hoàn trả các thành phần.
Duyệt các cây thành phần bên phải trước khi hoàn trả các thành phần
JSF có đặc tính chỉ đọc thú vị có tên là rendersChildren. Nếu đặc tính này là false (sai), chỉ
có phương thức encodeBegin() và encodeEnd() sẽ được gọi để hoàn trả thành phần này. Nếu
Các ứng dụng Craft Ajax sử dụng JSF với CSS và Javascript,
Phần 1: Tăng cường diện mạo của các trang JSF của bạn
Trang 9 của 20
developerWorks®
ibm.com/developerWorks/vn/
trả về true (đúng), encodeChildren() cũng được gọi trong giai đoạn Render
Response. Những phương thức này thường ủy quyền hoàn trả cho một lớp, lớp này phải thực hiện
giao diện javax.faces.render.Renderer, nhưng các thành phần JSF cũng có thể tạo HTML của
mình, mà không cần sử dụng các trình hoàn trả (renderers).
getRendersChildren()
Khi sử dụng phiên bản JSF 1.1, các phương thức mã hóa ban đầu được các phương thức của trình
xử lý thẻ gọi. Tuy nhiên, nếu một thành phần hoàn trả thành phần con riêng của nó, tất cả các trình
xử lý thẻ của các thành phần lồng nhau ngừng gọi các phương thức mã hóa vì việc hoàn trả trở
thành trách nhiệm của các thành phần, có phương thức getRendersChildren() của nó trả về true
(đúng). Quá trình hoàn trả này được thực hiện trong phiên bản JSF 1.1 đã có hiệu quả vì nó giảm
tầng đệm, nhưng nó đòi hỏi các nhà phát triển ứng dụng tính đến nội dung HTML trong các thành
phần <f:verbatim>. Trong phiên bản JSF 1.2, bạn không cần phải sử dụng <f:verbatim> nữa vì
việc hoàn trả được thực hiện chỉ sau khi toàn bộ cây thành phần được tạo ra.
Cho dù bạn sử dụng phiên bản JSF 1.1 hoặc 1.2, các thành phần lồng nhau được khởi tạo hoàn
toàn và sẵn sàng được hoàn trả khi encodeChildren() được gọi. Vì vậy, đây là nơi mà bạn có được
cơ hội để thiết lập các phong cách mặc định. Tiếp theo, bạn sẽ thấy cách tạo một phần tùy chỉnh để
thiết lập thuộc tính styleClass cho tất cả các thành phần lồng nhau của nó, duyệt cây thành phần
JSF theo cách đệ quy.
Kỹ thuật được trình bày ở đây có thể được dùng để thiết lập các thuộc tính hoặc các đặc tính bất kì
của các thành phần JSF, không chỉ là các phong cách mặc định. Vì vậy ý tưởng tốt là tạo một lớp
cơ sở chung có thể được tái sử dụng sau này. Lớp SetupComponent mở rộng lớp UIComponentBase
của JSF API và định nghĩa một phương thức trừu tượng có tên là setup(), nó được gọi cho mọi
thành phần lồng nhau có sự hoàn trả của nó được kích hoạt. Phương thức setupTree() (được hiển
thị trong Liệt kê 13) thực hiện duyệt đệ quy của cây thành phần JSF.
Liệt kê 13. Các phương thức setup() và setupTree() của lớp SetupComponent
package jsfcssjs;
import
import
import
...
public
javax.faces.component.UIComponent;
javax.faces.component.UIComponentBase;
javax.faces.context.FacesContext;
abstract class SetupComponent extends UIComponentBase {
protected abstract void setup(FacesContext ctx, UIComponent comp);
protected void setupTree(FacesContext ctx, UIComponent comp) {
if (!comp.isRendered())
return;
setup(ctx, comp);
for (UIComponent child : comp.getChildren())
setupTree(ctx, child);
}
...
}
Phương thức getRendersChildren() (xem Liệt kê 14), được thừa kế từ UIComponentBase, bị ghi đè
để trả về true sao cho thành phần setup (thiết lập) có thể điều khiển việc hoàn trả của thành phần
con của nó.
Các ứng dụng Craft Ajax sử dụng JSF với CSS và Javascript,
Phần 1: Tăng cường diện mạo của các trang JSF của bạn
Trang 10 của 20
ibm.com/developerWorks/vn/
developerWorks®
Liệt kê 14. Phương thức getRendersChildren () của lớp SetupComponent
public abstract class SetupComponent extends UIComponentBase {
...
public boolean getRendersChildren() {
return true;
}
...
}
Liệt kê 15 cho thấy phương thức encodeChildren(), bị ghi đè để gọi setupTree() trước khi gọi
encodeTree() cho mỗi thành phần con.
Liệt kê 15. Phương thức encodeChildren ()của lớp SetupComponent
public abstract class SetupComponent extends UIComponentBase {
...
public void encodeChildren(FacesContext ctx)
throws IOException {
if (!isRendered())
return;
setupTree(ctx, this);
for (UIComponent child : getChildren())
encodeTree(ctx, child);
}
...
}
Phương thức encodeTree() (xem Liệt kê 16) gọi các phương thức mã hóa cho thành phần hiện tại
và được gọi theo cách đệ quy cho các thành phần con nếu getRendersChildren () trả về false.
Liệt kê 16. Phương thức encodeTree () của lớp SetupComponent
public abstract class SetupComponent extends UIComponentBase {
...
protected void encodeTree(FacesContext ctx, UIComponent comp)
throws IOException {
if (!comp.isRendered())
return;
comp.encodeBegin(ctx);
if (comp.getRendersChildren())
comp.encodeChildren(ctx);
else
for (UIComponent child : comp.getChildren())
encodeTree(ctx, child);
comp.encodeEnd(ctx);
}
}
Tạo và cấu hình một thành phần tùy chỉnh
Liệt kê 17 cho thấy lớp DefaultStylesComponent mở rộng SetupComponent và thực hiện phương
thức setup() để thiết lập thuộc tính styleClass , giá trị của thuộc tính này được xây dựng từ tên họ
thành phần và tên của trình hoàn trả.
Liệt kê 17. Lớp DefaultStylesComponent
package jsfcssjs;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
Các ứng dụng Craft Ajax sử dụng JSF với CSS và Javascript,
Phần 1: Tăng cường diện mạo của các trang JSF của bạn
Trang 11 của 20
developerWorks®
ibm.com/developerWorks/vn/
import java.util.Map;
public class DefaultStylesComponent extends SetupComponent {
protected void setup(FacesContext ctx, UIComponent comp) {
Map<String, Object> attrMap = comp.getAttributes();
if (attrMap.get("styleClass") != null)
return;
String familyName = getLastName(comp.getFamily());
String rendererName = getLastName(comp.getRendererType());
if (familyName == null || rendererName == null)
return;
String className = "Default" + familyName;
if (!familyName.equals(rendererName))
className += rendererName;
attrMap.put("styleClass", className);
}
protected String getLastName(String fullName) {
if (fullName == null)
return null;
int dotIndex = fullName.lastIndexOf('.');
if (dotIndex != -1)
return fullName.substring(dotIndex+1);
else
return fullName;
}
public String getFamily() {
return "DefaultStyles";
}
}
Lớp DefaultStylesComponent được cấu hình trong faces-config.xml, như chỉ ra trong Liệt kê 18.
Liệt kê 18. Cấu hình lớp DefaultStylesComponent trong faces-config.xml
<faces-config ...>
...
<component>
<component-type>DefaultStylesComponent</component-type>
<component-class>jsfcssjs.DefaultStylesComponent</component-class>
<component-extension>
<component-family>DefaultStyles</component-family>
</component-extension>
</component>
</faces-config>
Thực hiện thẻ tùy chỉnh
Lớp DefaultStylesTag (xem Liệt kê 19) mở rộng lớp UIComponentELTag được API của JSF 1.2
định nghĩa và thực hiện các phương thức getComponentType() và getRendererType() để trả về
DefaultStylesComponent và null (không), tương ứng. Nếu bạn sử dụng phiên bản JSF 1.1, lớp thẻ
này phải mở rộng UIComponentTag thay cho UIComponentELTag.
Các ứng dụng Craft Ajax sử dụng JSF với CSS và Javascript,
Phần 1: Tăng cường diện mạo của các trang JSF của bạn
Trang 12 của 20
ibm.com/developerWorks/vn/
developerWorks®
Liệt kê 19. Lớp DefaultStylesTag
package jsfcssjs;
import javax.faces.webapp.UIComponentELTag;
public class DefaultStylesTag extends UIComponentELTag {
public String getComponentType() {
return "DefaultStylesComponent";
}
public String getRendererType() {
return null;
}
}
Tệp css.tld (hiển thị trong Liệt kê 20) định nghĩa tên defaultStyles và các thuộc tính của thẻ tùy
chỉnh. Sự hỗ trợ cho các thuộc tính id (mã nhận dạng), binding (liên kết) và rendered (được hoàn
trả) được thừa kế từ UIComponentELTag.
Liệt kê 20. Tệp css.tld cho JSF 1.2 và JSP 2.1
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/javaee" ... version="2.1">
<tlib-version>1.0</tlib-version>
<short-name>css</short-name>
<uri>/css.tld</uri>
<tag>
<name>defaultStyles</name>
<tag-class>jsfcssjs.DefaultStylesTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>id</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>binding</name>
<required>false</required>
<deferred-value>
<type>jsfcssjs.DefaultStylesComponent</type>
</deferred-value>
</attribute>
<attribute>
<name>rendered</name>
<required>false</required>
<deferred-value>
<type>boolean</type>
</deferred-value>
</attribute>
</tag>
</taglib>
Nếu bạn sử dụng JSF 1.1, tệp TLD sẽ tuân theo cú pháp do đặc tả JSP 1.2 định nghĩa (xem Liệt kê
21).
Liệt kê 21. Tệp css.tld cho JSF 1.1 và JSP 1.2
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
Các ứng dụng Craft Ajax sử dụng JSF với CSS và Javascript,
Phần 1: Tăng cường diện mạo của các trang JSF của bạn
Trang 13 của 20
developerWorks®
ibm.com/developerWorks/vn/
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>css</short-name>
<uri>/css.tld</uri>
<tag>
<name>defaultStyles</name>
<tag-class>jsfcssjs.DefaultStylesTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>id</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>binding</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>rendered</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
</taglib>
Sử dụng thành phần tùy chỉnh trong một trang JSF
Trung tâm tài nguyên Ajax của developerWorks
Xem trung tâm tài nguyên Ajax, cửa hàng cung cấp toàn diện của bạn với các công cụ, mã
và thông tin miễn phí về các ứng dụng phát triển Ajax. Diễn đàn cộng đồng Ajax năng động,
được chuyên gia Ajax Jack Herrington đăng lên, sẽ kết nối bạn với những người có thể có các
câu trả lời mà bạn đang tìm kiếm ngay bây giờ.
Ví dụ JSF đã trình bày trong phần này chỉ ra cách bạn có thể tăng cường sự xuất hiện của các
thành phần JSF, bằng cách sử dụng các màu và các đường viền nền.
Các ứng dụng Craft Ajax sử dụng JSF với CSS và Javascript,
Phần 1: Tăng cường diện mạo của các trang JSF của bạn
Trang 14 của 20
ibm.com/developerWorks/vn/
developerWorks®
Hình 2. Ví dụ DefaultStyles
Liệt kê 22 cho thấy tệp DefaultStyles.css , nó xác định một vài lớp phong cách được sử dụng
trong ví dụ DefaultStyles.jsp.
Liệt kê 22. Ví dụ DefaultStyles.css
.DefaultForm {}
.DefaultPanelGrid { background-color: #FFFFFF; }
.DefaultInputText { background-color: #FFDDDD;
border-style: ridge; border-width: thin; }
.DefaultInputTextarea { background-color: #DDFFDD;
border-style: groove; border-width: thick; }
.DefaultSelectOneMenu { background-color: #DDDDFF;
border-style: inset; border-width: medium; }
.DefaultCommandButton { background-color: #DDDDDD;
border-style: outset; border-width: medium; }
.SpecialInputText { background-color: #DDFFFF;
border-style: double; border-width: thick; }
.EnabledOption { color: #FF0000; }
.DisabledOption { color: #0000FF; }
Ví dụ DefaultStyles.jsp (xem Liệt kê 23) sử dụng thành phần <css:defaultStyles> để thiết lập
các phong cách mặc định cho các thành phần JSF không có thuộc tính styleClass. Một trong
những thành phần này sử dụng lớp phong cách SpecialInputText. Các lớp EnabledOption và
DisabledOption được sử dụng cho các mục này của một danh sách thả xuống.
Liệt kê 23. Ví dụ DefaultStyles.jsp
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
Các ứng dụng Craft Ajax sử dụng JSF với CSS và Javascript,
Phần 1: Tăng cường diện mạo của các trang JSF của bạn
Trang 15 của 20
developerWorks®
ibm.com/developerWorks/vn/
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<%@ taglib prefix="css" uri="/css.tld" %>
<f:view>
<html>
<head>
<title>Default Styles</title>
<link rel="stylesheet" type="text/css"
href="<%=request.getContextPath()%>/styles/DefaultStyles.css">
</head>
<body>
<h1>Default Styles</h1>
<css:defaultStyles>
<h:form id="form">
<h:panelGrid columns="1" border="0" cellspacing="5">
<h:inputText id="text" size="30" value="default text style"/>
<h:inputText id="special" size="30" value="special text style"
styleClass="SpecialInputText"/>
<h:selectOneMenu id="menu" enabledClass="EnabledOption"
disabledClass="DisabledOption">
<f:selectItem itemValue="First" itemLabel="First"/>
<f:selectItem itemValue="Second" itemLabel="Second"/>
<f:selectItem itemValue="Third" itemLabel="Third"
itemDisabled="true"/>
</h:selectOneMenu>
<h:inputTextarea id="area" rows="5" cols="30"
value="default text area style"/>
<h:commandButton id="button" value="Submit"/>
</h:panelGrid>
</h:form>
</css:defaultStyles>
</body>
</html>
</f:view>
Liệt kê 24 hiển thị HTML được trang DefaultStyles.jsp tạo ra. Bạn sẽ thấy rằng tất cả các phần
tử biểu mẫu có một thuộc tính class (lớp). Các tên lớp đó bắt đầu bằng Default (mặc định) được
thành phần <css:defaultStyles> thiết lập.
Liệt kê 24. DefaultStyles.jsp tạo HTML
<html>
<head>
<title>Default Styles</title>
<link rel="stylesheet" type="text/css"
href="/jsf12css/styles/DefaultStyles.css">
</head>
<body>
<h1>Default Styles</h1>
<form id="form" ... class="DefaultForm" ...>
<input type="hidden" name="form" value="form" />
<table class="DefaultPanelGrid" border="0" cellspacing="5">
<tbody>
<tr>
<td><input id="form:text" type="text" ...
class="DefaultInputText" .../></td>
</tr>
<tr>
<td><input id="form:special" type="text" ...
class="SpecialInputText" .../></td>
</tr>
<tr>
<td><select id="form:menu" ... class="DefaultSelectOneMenu" ...>
<option value="First" class="EnabledOption">First</option>
Các ứng dụng Craft Ajax sử dụng JSF với CSS và Javascript,
Phần 1: Tăng cường diện mạo của các trang JSF của bạn
Trang 16 của 20
ibm.com/developerWorks/vn/
developerWorks®
<option value="Second" class="EnabledOption">Second</option>
<option value="Third" disabled="disabled"
class="DisabledOption">Third</option>
</select></td>
</tr>
<tr>
<td><textarea id="form:area" ...
class="DefaultInputTextarea" ...> ... </textarea></td>
</tr>
<tr>
<td><input id="form:button" type="submit" ...
class="DefaultCommandButton" /></td>
</tr>
</tbody>
</table>
<input type="hidden" ... id="javax.faces.ViewState" value="..." />
</form>
</body>
</html>
Kết luận
Bài viết này đã giải thích sự hỗ trợ CSS do các thành phần JSF chuẩn cung cấp. Các hỗ trợ đơn
giản chỉ có hai thuộc tính có tên là style và styleClass. Các thành phần phức tạp hơn, chẳng hạn
như các lưới và các bảng dữ liệu, có các thuộc tính liên quan đến CSS bổ sung thêm cho các khía
cạnh và các phần tử của chúng. Phần đầu tiên của loạt bài này cũng giải thích các cây thành phần
JSF được xây dựng như thế nào và cách bạn có thể duyệt bên phải các cây này trước khi hoàn trả
thành phần, vì vậy bạn có thể thêm các tính năng, như là các phong cách mặc định. Hãy chuyển
sang Phần 2, ở đó bạn sẽ tìm thấy các kỹ thuật dựa trên JavaScript để làm cho các biểu mẫu JSF
động hơn.
Các ứng dụng Craft Ajax sử dụng JSF với CSS và Javascript,
Phần 1: Tăng cường diện mạo của các trang JSF của bạn
Trang 17 của 20
developerWorks®
ibm.com/developerWorks/vn/
Các tải về
Mô tả
Tên
Kích thước
Sample application for this article
jsfcssjs_part1_src.zip
25KB
Các ứng dụng Craft Ajax sử dụng JSF với CSS và Javascript,
Phần 1: Tăng cường diện mạo của các trang JSF của bạn
Trang 18 của 20
ibm.com/developerWorks/vn/
developerWorks®
Tài nguyên
• Vùng phát triển Web của developerWorks được đóng gói với các công cụ và thông tin để phát
triển Web 2.0.
• Tìm hiểu thêm về công nghệ JSF và ứng dụng nó trong các ứng dụng của bạn.
• Trung tâm tài nguyên Ajax của developerWorks chứa một thư viện phát triển về nội dung Ajax
cũng như nguồn tài nguyên có ích để giúp bạn bắt đầu phát triển các ứng dụng Ajax ngày
hôm nay.
• Đặc tả JSF 1.2 mô tả đầy đủ công nghệ JavaServer Faces.
• Nhận được mã nguồn JSF RI và các mã nhị phân từ javaserverfaces.dev.java.net
• Dự án Apache MyFaces là một cách thực hiện JSF phổ biến khác.
• W3C cung cấp một giới thiệu hay về Cascading Style Sheets (CSS-Bảng định kiểu nhiều
tầng).
Các ứng dụng Craft Ajax sử dụng JSF với CSS và Javascript,
Phần 1: Tăng cường diện mạo của các trang JSF của bạn
Trang 19 của 20
developerWorks®
ibm.com/developerWorks/vn/
Đôi nét về tác giả
Andrei Cioroianu
Andrei Cioroianu là người sáng lập của Devsphere, một nhà cung cấp các dịch vụ
phát triển Java EE và các dịch vụ tư vấn Ajax / JSF. Ông đã sử dụng các công nghệ
Java và Web từ năm 1997 và có 10 năm kinh nghiệm chuyên môn trong việc giải
quyết những vấn đề kỹ thuật phức tạp và quản lý toàn bộ vòng đời của các sản phẩm
thương mại, các ứng dụng tùy chỉnh và các khung công tác mã nguồn mở
© Copyright IBM Corporation 2009
(www.ibm.com/legal/copytrade.shtml)
Nhẫn hiệu đăng ký
(www.ibm.com/developerworks/vn/ibm/trademarks/)
Các ứng dụng Craft Ajax sử dụng JSF với CSS và Javascript,
Phần 1: Tăng cường diện mạo của các trang JSF của bạn
Trang 20 của 20
Similar pages
PDF: