Để hiển thị dữ liệu phân cấp và xây dựng điều hướng cho trang web, PrimeFaces cung cấp sẵn các component Tree và TreeTable để bạn dễ dàng triển khai những tính năng này.
Tuy nhiên, việc khai thác triệt để sức mạnh của các component này không hề đơn giản. Nó đòi hỏi bạn phải nắm vững nhiều chi tiết kỹ thuật, mà đôi khi, những thông tin đó lại rải rác trên nhiều tài liệu khác nhau hoặc thậm chí không được đề cập rõ ràng. Bài viết này ra đời với mục đích cung cấp cho bạn cái nhìn toàn diện và những giải thích chi tiết nhất về cách bạn có thể tận dụng tối đa các thành phần Tree và TreeTable của PrimeFaces.
Thông tin cơ bản về PrimeFaces Tree
Thuộc tính | Giá trị |
---|---|
Tên | Tree |
Lớp thành phần | org.primefaces.component.tree.Tree |
Loại thành phần | org.primefaces.component.Tree |
Nhóm thành phần | org.primefaces.component |
Loại bộ kết xuất | org.primefaces.component.TreeRenderer |
Lớp bộ kết xuất | org.primefaces.component.tree.TreeRenderer |
Các thuộc tính của Primefaces Tree
Tên thuộc tính | Mặc định | Kiểu dữ liệu | Mô tả |
---|---|---|---|
id |
null |
String | Định danh duy nhất của thành phần |
rendered |
true |
Boolean | Giá trị boolean xác định việc hiển thị thành phần. Nếu đặt là false , thành phần sẽ không được render |
binding |
null |
Object | Biểu thức EL ánh xạ đến một đối tượng UIComponent phía server trong backing bean |
widgetVar |
null |
String | Tên của widget phía client |
value |
null |
Object | Một đối tượng TreeNode làm mô hình dữ liệu phía sau |
var |
null |
String | Tên biến trong phạm vi request dùng để truy cập dữ liệu từng node |
dynamic |
false |
Boolean | Xác định chế độ bật/tắt node là qua Ajax hay client |
cache |
true |
Boolean | Bật/tắt cache cho các node tải động. Nếu true , các node đã mở rộng sẽ được giữ lại trong bộ nhớ |
onNodeClick |
null |
String | Sự kiện Javascript xử lý khi một node được nhấn |
selection |
null |
Object | Mảng TreeNode dùng để tham chiếu các node được chọn |
style |
null |
String | Kiểu (CSS inline) của phần tử chứa chính của tree |
styleClass |
null |
String | Lớp CSS của phần tử chứa chính của tree |
selectionMode |
null |
String | Xác định chế độ chọn node (single , multiple , checkbox ) |
highlight |
true |
Boolean | Tô sáng các node khi di chuột khi chức năng chọn được bật |
datakey |
null |
Object | Khóa duy nhất của dữ liệu được thể hiện qua các node |
animate |
false |
Boolean | Bật hiệu ứng trượt khi mở/đóng node |
orientation |
vertical |
String | Hướng của bố cục: vertical hoặc horizontal |
propagateSelectionUp |
true |
Boolean | Bật lan truyền chọn từ con lên cha (chế độ checkbox) |
propagateSelectionDown |
true |
Boolean | Bật lan truyền chọn từ cha xuống con (chế độ checkbox) |
dir |
ltr |
String | Hướng văn bản, giá trị hợp lệ là ltr và rtl |
draggable |
false |
Boolean | Cho phép các node có thể kéo |
droppable |
false |
Boolean | Cho phép tree có thể nhận các node kéo vào |
dragdropScope |
null |
String | Khóa phạm vi dùng để nhóm các tree cho thao tác kéo thả |
dragMode |
self |
String | Xác định mối quan hệ cha-con khi node được kéo. Giá trị hợp lệ: self , parent , ancestor |
dropRestrict |
none |
String | Hạn chế quan hệ khi node được thả. Giá trị: none , sibling |
required |
false |
Boolean | Ràng buộc kiểm tra xem có chọn node hay không |
requiredMessage |
null |
String | Thông báo khi ràng buộc lựa chọn bắt buộc không được đáp ứng |
Bắt đầu với Primefaces Tree
Thành phần p:tree
trong PrimeFaces cho phép bạn hiển thị dữ liệu dạng cây.
Bạn cấp dữ liệu cho Tree thông qua một instance của org.primefaces.model.TreeNode
, đại diện cho nút gốc (root). Hãy xem xét ví dụ đơn giản dưới đây, nơi chúng ta sử dụng thành phần Tree để hiển thị cấu trúc dữ liệu cơ bản.
Mã nguồn index.xhtml
:
<html xmlns="<https://www.w3.org/1999/xhtml>"
xmlns:ui="<https://java.sun.com/jsf/facelets>"
xmlns:h="<https://java.sun.com/jsf/html>"
xmlns:f="<https://java.sun.com/jsf/core>"
xmlns:p="<https://primefaces.org/ui>">
<h:head>
<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>
<p:tree value="#{treeManagedBean.root}" var="node">
<p:treeNode>
<h:outputText value="#{node}"/>
</p:treeNode>
</p:tree>
</h:form>
</html>
Mã nguồn TreeManagedBean.java
:
package com.journaldev.prime.faces.beans;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
@ManagedBean
@SessionScoped
public class TreeManagedBean {
// TreeNode instance
private TreeNode root;
public TreeManagedBean(){
// Đây là nút gốc, dữ liệu của nó là "Root Node" và parent là null
this.root = new DefaultTreeNode("Root Node", null);
// Tạo nút con
TreeNode child = new DefaultTreeNode("Child Node", this.root);
// Tham chiếu parent của nút con (có thể bỏ qua nếu đã truyền vào constructor)
child.setParent(this.root);
// Tạo nút cháu
TreeNode descendent = new DefaultTreeNode("Descendent Node", child);
// Tham chiếu parent của nút cháu (có thể bỏ qua nếu đã truyền vào constructor)
descendent.setParent(child);
}
public TreeNode getRoot() {
return root;
}
public void setRoot(TreeNode root) {
this.root = root;
}
}
Từ ví dụ trên, chúng ta nhận thấy những điều sau:
- Thành phần
p:tree
liên kết với một instance củaTreeNode
được gọi làroot
. - Instance
root
chứa một nút con, đây cũng là một instance củaTreeNode
và nó cũng tham chiếu đến một nút con khác (nút cháu). Điều này hình thành cấu trúc phân cấp. - Bạn hiển thị cây phân cấp này bằng cách tham chiếu trực tiếp đến nút gốc thông qua thuộc tính
value
. - Thuộc tính
var
của thành phầnTree
dùng để tham chiếu biến Request-Scoped, mà bạn sẽ sử dụng để trích xuất dữ liệu của từng nút cây. - Mỗi
TreeNode
được tạo bằng cách truyền hai đối số: đối tượng dữ liệu được đóng gói và tham chiếu đến nút cha của nó. - Mỗi
TreeNode
có các thuộc tính quan trọng nhưtype
,data
,children
,parent
và cờ booleanexpanded
. Chúng ta sẽ khám phá kỹ hơn các thuộc tính này trong các phần tiếp theo.
PrimeFaces Dynamic Tree
Mặc định, thành phần Tree không hoạt động ở chế độ động. Chế độ động sử dụng Ajax để tải các nút cây từ phía máy chủ theo yêu cầu. Khi bạn mở rộng một nút, Tree chỉ tải các nút con của nút đó và gửi về client để hiển thị. Khác với hành vi mặc định (khi dynamic
là false
), nơi tất cả các nút cây trong model đều được render về client ngay từ đầu, chế độ động sẽ phù hợp hơn cho các tập dữ liệu lớn. Bạn có thể kích hoạt chế độ động bằng cách thiết lập thuộc tính dynamic
thành true
.
Mã nguồn index.xhtml
:
<html xmlns="<https://www.w3.org/1999/xhtml>"
xmlns:ui="<https://java.sun.com/jsf/facelets>"
xmlns:h="<https://java.sun.com/jsf/html>"
xmlns:f="<https://java.sun.com/jsf/core>"
xmlns:p="<https://primefaces.org/ui>">
<h:head>
<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>
<p:tree value="#{treeManagedBean.root}" var="node" dynamic="true">
<p:treeNode>
<h:outputText value="#{node}"/>
</p:treeNode>
</p:tree>
</h:form>
</html>
Các kiểu TreeNode khác nhau trong PrimeFaces
Một yêu cầu phổ biến là bạn muốn hiển thị các loại TreeNode
và biểu tượng khác nhau trong cấu trúc phân cấp của mình. Để triển khai điều này, bạn hãy làm theo các bước đơn giản sau:
- Bạn định nghĩa/đặt nhiều thành phần
<p:treeNode/>
, mỗi thành phần có một thuộc tínhtype
khác nhau. - Bạn sử dụng kiểu đã định nghĩa đó để liên kết các
TreeNode
trong model của mình.
Ví dụ dưới đây minh họa cách sử dụng các kiểu TreeNode
khác nhau để hiển thị sự đa dạng về loại. Các tệp bị ảnh hưởng là cả index.xhtml
và TreeManagedBean.java
.
Mã nguồn index.xhtml
:
<html xmlns="<https://www.w3.org/1999/xhtml>"
xmlns:ui="<https://java.sun.com/jsf/facelets>"
xmlns:h="<https://java.sun.com/jsf/html>"
xmlns:f="<https://java.sun.com/jsf/core>"
xmlns:p="<https://primefaces.org/ui>">
<h:head>
<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>
<p:tree value="#{treeManagedBean.root}" var="node" dynamic="true">
<p:treeNode expandedIcon="ui-icon ui-icon-folder-open"
collapsedIcon="ui-icon ui-icon-folder-collapsed">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="document" icon="ui-icon ui-icon-document">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="image" icon="ui-icon ui-icon-image">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="video" icon="ui-icon ui-icon-video">
<h:outputText value="#{node}"/>
</p:treeNode>
</p:tree>
</h:form>
</html>
Mã nguồn TreeManagedBean.java
:
package com.journaldev.prime.faces.beans;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
@ManagedBean
@SessionScoped
public class TreeManagedBean {
// TreeNode instance
private TreeNode root;
public TreeManagedBean(){
// Đây là nút gốc
this.root = new DefaultTreeNode("Root Node", null);
// Tạo nút "Documents"
TreeNode documents = new DefaultTreeNode("Documents", this.root);
// Tạo nút tài liệu
TreeNode document01 = new DefaultTreeNode("document","Expenses.doc", documents);
// Tạo nút "Images"
TreeNode images = new DefaultTreeNode("Images", this.root);
// Tạo nút hình ảnh
TreeNode image01 = new DefaultTreeNode("image","Travel.gif", images);
// Tạo nút "Videos"
TreeNode videos = new DefaultTreeNode("Videos", this.root);
// Tạo nút video
TreeNode video01 = new DefaultTreeNode("video","Play.avi", videos);
}
public TreeNode getRoot() {
return root;
}
public void setRoot(TreeNode root) {
this.root = root;
}
}
Như đã thấy từ ví dụ, sự tích hợp giữa TreeNode
instance và thành phần p:treeNode
chính là qua thuộc tính type
. Bạn cũng có thể sử dụng các thuộc tính expandedIcon
, collapsedIcon
và icon
trên p:treeNode
để tùy chỉnh biểu tượng cho từng loại nút.
Sự kiện hành vi Ajax của PrimeFaces Tree
Thành phần Tree cung cấp nhiều sự kiện hành vi Ajax khác nhau, cho phép bạn tương tác với các hành động của người dùng trên cây.
Sự kiện (Event) | Tham số Listener | Kích hoạt khi |
---|---|---|
expand |
org.primefaces.event.NodeExpandEvent |
Khi một node được mở rộng |
collapse |
org.primefaces.event.NodeCollapseEvent |
Khi một node bị thu gọn |
select |
org.primefaces.event.NodeSelectEvent |
Khi một node được chọn |
unselect |
org.primefaces.event.NodeUnselectEvent |
Khi một node bị bỏ chọn |
Ví dụ sau cho thấy một cây với bốn listener sự kiện:
Mã nguồn index2.xhtml
:
<html xmlns="<https://www.w3.org/1999/xhtml>"
xmlns:ui="<https://java.sun.com/jsf/facelets>"
xmlns:h="<https://java.sun.com/jsf/html>"
xmlns:f="<https://java.sun.com/jsf/core>"
xmlns:p="<https://primefaces.org/ui>">
<h:head>
<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>
<p:tree value="#{treeManagedBean.root}" var="node" dynamic="true">
<p:treeNode expandedIcon="ui-icon ui-icon-folder-open"
collapsedIcon="ui-icon ui-icon-folder-collapsed">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="document" icon="ui-icon ui-icon-document">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="image" icon="ui-icon ui-icon-image">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="video" icon="ui-icon ui-icon-video">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:ajax event="select" listener="#{treeManagedBean.onNodeSelect}"></p:ajax>
<p:ajax event="unselect" listener="#{treeManagedBean.onNodeUnSelect}"></p:ajax>
<p:ajax event="expand" listener="#{treeManagedBean.onNodeExpand}"></p:ajax>
<p:ajax event="collapse" listener="#{treeManagedBean.onNodeCollapse}"></p:ajax>
</p:tree>
</h:form>
</html>
Mã nguồn TreeManagedBean.java
:
package com.journaldev.prime.faces.beans;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.primefaces.event.NodeCollapseEvent;
import org.primefaces.event.NodeExpandEvent;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.event.NodeUnselectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
@ManagedBean
@SessionScoped
public class TreeManagedBean {
// TreeNode instance
private TreeNode root;
public TreeManagedBean(){
// This is the root node, so it's data is root and its parent is null
this.root = new DefaultTreeNode("Root Node", null);
// Create documents node
TreeNode documents = new DefaultTreeNode("Documents", this.root);
// Create document node
TreeNode document01 = new DefaultTreeNode("document","Expenses.doc", documents);
// Create images node
TreeNode images = new DefaultTreeNode("Images", this.root);
// Create image node
TreeNode image01 = new DefaultTreeNode("image","Travel.gif", images);
// Create videos node
TreeNode videos = new DefaultTreeNode("Videos", this.root);
// Create video node
TreeNode video01 = new DefaultTreeNode("video","Play.avi", videos);
}
public TreeNode getRoot() {
return root;
}
public void setRoot(TreeNode root) {
this.root = root;
}
public void onNodeSelect(NodeSelectEvent event){
System.out.println("Node Data ::"+event.getTreeNode().getData()+" :: Selected");
}
public void onNodeUnSelect(NodeUnselectEvent event){
System.out.println("Node Data ::"+event.getTreeNode().getData()+" :: UnSelected");
}
public void onNodeExpand(NodeExpandEvent event){
System.out.println("Node Data ::"+event.getTreeNode().getData()+" :: Expanded");
}
public void onNodeCollapse(NodeCollapseEvent event){
System.out.println("Node Data ::"+event.getTreeNode().getData()+" :: Collapsed");
}
}
Từ đoạn mã trên, bạn thấy:
- Khi bạn mở rộng một
TreeNode
, một sự kiện Ajax được kích hoạt. - Với mỗi sự kiện được kích hoạt, một phương thức listener Ajax đã được định nghĩa để xử lý.
- Các event listener cũng rất hữu ích khi làm việc với lượng lớn dữ liệu. Bạn có thể cung cấp nút gốc và các nút con cho cây, sau đó sử dụng các event listener để lấy nút được chọn và thêm các nút mới vào cây đó trong thời gian chạy.
- Lưu ý, các sự kiện
Select
vàUnSelect
chưa được kích hoạt ở ví dụ này. Để kích hoạt chúng, bạn cần thiết lập thuộc tínhselectionMode
cho Tree.
Selection và SelectionMode trong PrimeFaces Tree
Thành phần Tree cung cấp chức năng tích hợp giúp bạn xác định các nút đã chọn. Cơ chế chọn nút hỗ trợ ba chế độ, và với mỗi chế độ, một hoặc nhiều instance TreeNode
được gán làm tham chiếu lựa chọn.
- Single Mode: Bạn chỉ có thể chọn một
TreeNode
tại một thời điểm. Thuộc tínhselection
nên tham chiếu đến mộtTreeNode
đơn lẻ. - Multiple Mode: Bạn có thể chọn nhiều nút. Thuộc tính
selection
nên tham chiếu đến một mảngTreeNode
. - Checkbox Mode: Bạn có thể chọn nhiều nút bằng giao diện checkbox. Thuộc tính
selection
cũng nên tham chiếu đến một mảngTreeNode
.
Mã nguồn index1.xhtml
:
<html xmlns="<https://www.w3.org/1999/xhtml>"
xmlns:ui="<https://java.sun.com/jsf/facelets>"
xmlns:h="<https://java.sun.com/jsf/html>"
xmlns:f="<https://java.sun.com/jsf/core>"
xmlns:p="<https://primefaces.org/ui>">
<h:head>
<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>
<p:tree value="#{treeManagedBean.root}" var="node" dynamic="true"
selectionMode="single" selection="#{treeManagedBean.singleSelectedTreeNode}">
<p:treeNode expandedIcon="ui-icon ui-icon-folder-open"
collapsedIcon="ui-icon ui-icon-folder-collapsed">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="document" icon="ui-icon ui-icon-document">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="image" icon="ui-icon ui-icon-image">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="video" icon="ui-icon ui-icon-video">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:ajax event="select" listener="#{treeManagedBean.onNodeSelect}"></p:ajax>
<p:ajax event="unselect" listener="#{treeManagedBean.onNodeUnSelect}"></p:ajax>
<p:ajax event="expand" listener="#{treeManagedBean.onNodeExpand}"></p:ajax>
<p:ajax event="collapse" listener="#{treeManagedBean.onNodeCollapse}"></p:ajax>
</p:tree>
<p:tree value="#{treeManagedBean.root}" var="node" dynamic="true"
selectionMode="multiple" selection="#{treeManagedBean.multipleSelectedTreeNodes}">
<p:treeNode expandedIcon="ui-icon ui-icon-folder-open"
collapsedIcon="ui-icon ui-icon-folder-collapsed">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="document" icon="ui-icon ui-icon-document">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="image" icon="ui-icon ui-icon-image">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="video" icon="ui-icon ui-icon-video">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:ajax event="select" listener="#{treeManagedBean.onNodeSelect}"></p:ajax>
<p:ajax event="unselect" listener="#{treeManagedBean.onNodeUnSelect}"></p:ajax>
<p:ajax event="expand" listener="#{treeManagedBean.onNodeExpand}"></p:ajax>
<p:ajax event="collapse" listener="#{treeManagedBean.onNodeCollapse}"></p:ajax>
</p:tree>
<p:tree value="#{treeManagedBean.root}" var="node" dynamic="true"
selectionMode="checkbox" selection="#{treeManagedBean.checkboxSelectedTreeNodes}">
<p:treeNode expandedIcon="ui-icon ui-icon-folder-open"
collapsedIcon="ui-icon ui-icon-folder-collapsed">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="document" icon="ui-icon ui-icon-document">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="image" icon="ui-icon ui-icon-image">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="video" icon="ui-icon ui-icon-video">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:ajax event="select" listener="#{treeManagedBean.onNodeSelect}"></p:ajax>
<p:ajax event="unselect" listener="#{treeManagedBean.onNodeUnSelect}"></p:ajax>
<p:ajax event="expand" listener="#{treeManagedBean.onNodeExpand}"></p:ajax>
<p:ajax event="collapse" listener="#{treeManagedBean.onNodeCollapse}"></p:ajax>
</p:tree>
<h:commandButton value="Print Selected Nodes" action="#{treeManagedBean.printSelectedNodes}"></h:commandButton>
</h:form>
</html>
Mã nguồn TreeManagedBean.java
:
package com.journaldev.prime.faces.beans;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.primefaces.event.NodeCollapseEvent;
import org.primefaces.event.NodeExpandEvent;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.event.NodeUnselectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
@ManagedBean
@SessionScoped
public class TreeManagedBean {
// TreeNode instance
private TreeNode root;
private TreeNode singleSelectedTreeNode;
private TreeNode [] multipleSelectedTreeNodes;
private TreeNode [] checkboxSelectedTreeNodes;
public TreeManagedBean(){
// This is the root node, so it's data is root and its parent is null
this.root = new DefaultTreeNode("Root Node", null);
// Create documents node
TreeNode documents = new DefaultTreeNode("Documents", this.root);
// Create document node
TreeNode document01 = new DefaultTreeNode("document","Expenses.doc", documents);
// Create images node
TreeNode images = new DefaultTreeNode("Images", this.root);
// Create image node
TreeNode image01 = new DefaultTreeNode("image","Travel.gif", images);
// Create videos node
TreeNode videos = new DefaultTreeNode("Videos", this.root);
// Create video node
TreeNode video01 = new DefaultTreeNode("video","Play.avi", videos);
}
public TreeNode getRoot() {
return root;
}
public void setRoot(TreeNode root) {
this.root = root;
}
public TreeNode getSingleSelectedTreeNode() {
return singleSelectedTreeNode;
}
public void setSingleSelectedTreeNode(TreeNode singleSelectedTreeNode) {
this.singleSelectedTreeNode = singleSelectedTreeNode;
}
public TreeNode[] getMultipleSelectedTreeNodes() {
return multipleSelectedTreeNodes;
}
public void setMultipleSelectedTreeNodes(TreeNode[] multipleSelectedTreeNodes) {
this.multipleSelectedTreeNodes = multipleSelectedTreeNodes;
}
public TreeNode[] getCheckboxSelectedTreeNodes() {
return checkboxSelectedTreeNodes;
}
public void setCheckboxSelectedTreeNodes(TreeNode[] checkboxSelectedTreeNodes) {
this.checkboxSelectedTreeNodes = checkboxSelectedTreeNodes;
}
public void onNodeSelect(NodeSelectEvent event){
System.out.println("Node Data ::"+event.getTreeNode().getData()+" :: Selected");
}
public void onNodeUnSelect(NodeUnselectEvent event){
System.out.println("Node Data ::"+event.getTreeNode().getData()+" :: UnSelected");
}
public void onNodeExpand(NodeExpandEvent event){
System.out.println("Node Data ::"+event.getTreeNode().getData()+" :: Expanded");
}
public void onNodeCollapse(NodeCollapseEvent event){
System.out.println("Node Data ::"+event.getTreeNode().getData()+" :: Collapsed");
}
public String printSelectedNodes(){
System.out.println("Single Selection Is :: "+this.singleSelectedTreeNode.getData());
if (this.multipleSelectedTreeNodes != null) { // Thêm kiểm tra null an toàn
for(TreeNode n : this.multipleSelectedTreeNodes){
System.out.println("Multiple Selection Are :: "+n.getData());
}
}
if (this.checkboxSelectedTreeNodes != null) { // Thêm kiểm tra null an toàn
for(TreeNode n : this.checkboxSelectedTreeNodes){
System.out.println("CheckBox Selection Are :: "+n.getData());
}
}
return "";
}
}
Một số điểm cần lưu ý thêm để giải thích chi tiết:
- Thành phần
p:treeNode
có các thuộc tính nhưexpandedIcon
vàcollapsedIcon
để bạn chỉ định các biểu tượng cho hành vi mở rộng và thu gọn của nút. - Thành phần
p:treeNode
cũng có thuộc tínhicon
được sử dụng để chỉ định biểu tượng của chính nút đó.
Node cache và sự kiện OnNodeClick trong PrimeFaces
Mặc định, thuộc tính cache
được bật (true
). Các nút được tải động sẽ được giữ trong bộ nhớ, vì vậy việc mở rộng lại một nút sẽ không kích hoạt yêu cầu phía máy chủ. Trong trường hợp bạn đặt cache
thành false
, việc thu gọn nút sẽ loại bỏ các nút con, và việc mở rộng lại sau đó sẽ khiến các nút con được tải lại từ máy chủ.
Bạn cũng có thể thực thi một đoạn mã JavaScript tùy chỉnh khi một nút cụ thể được nhấp. Thuộc tính onNodeClick
được sử dụng cho mục đích này. Phương thức JavaScript được gọi với các phần tử html clickedNode
và event
được truyền vào. Ví dụ sau hiển thị các thông báo log trong console trình duyệt khi onNodeClick
được gọi.
Mã nguồn index3.xhtml
:
<html xmlns="<https://www.w3.org/1999/xhtml>"
xmlns:ui="<https://java.sun.com/jsf/facelets>"
xmlns:h="<https://java.sun.com/jsf/html>"
xmlns:f="<https://java.sun.com/jsf/core>"
xmlns:p="<https://primefaces.org/ui>">
<h:head>
<script name="jquery/jquery.js" library="primefaces"></script>
<script>
function onNodeClick(node,event){
console.log("nodeArg :: "+node);
console.log("eventArg ::"+event);
}
</script>
</h:head>
<h:form>
<p:tree value="#{treeManagedBean.root}" var="node" dynamic="true"
onNodeClick="onNodeClick(node,event)"
selectionMode="single" selection="#{treeManagedBean.singleSelectedTreeNode}">
<p:treeNode expandedIcon="ui-icon ui-icon-folder-open"
collapsedIcon="ui-icon ui-icon-folder-collapsed">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="document" icon="ui-icon ui-icon-document">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="image" icon="ui-icon ui-icon-image">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="video" icon="ui-icon ui-icon-video">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:ajax event="select" listener="#{treeManagedBean.onNodeSelect}"></p:ajax>
<p:ajax event="unselect" listener="#{treeManagedBean.onNodeUnSelect}"></p:ajax>
<p:ajax event="expand" listener="#{treeManagedBean.onNodeExpand}"></p:ajax>
<p:ajax event="collapse" listener="#{treeManagedBean.onNodeCollapse}"></p:ajax>
</p:tree>
</h:form>
</html>
Kéo thả trong PrimeFaces
Các nút cây có thể được sắp xếp lại trong một cây duy nhất và thậm chí có thể được chuyển giữa nhiều cây bằng cách sử dụng chức năng kéo thả (drag & drop). Ví dụ sau cho bạn thấy cách bạn có thể làm cho một cây duy nhất có thể kéo và thả.
Mã nguồn index4.xhtml
:
<html xmlns="<https://www.w3.org/1999/xhtml>"
xmlns:ui="<https://java.sun.com/jsf/facelets>"
xmlns:h="<https://java.sun.com/jsf/html>"
xmlns:f="<https://java.sun.com/jsf/core>"
xmlns:p="<https://primefaces.org/ui>">
<h:head>
<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>
<p:tree value="#{treeManagedBean.root}" var="node" dynamic="true" droppable="true" draggable="true"
selectionMode="single" selection="#{treeManagedBean.singleSelectedTreeNode}">
<p:treeNode expandedIcon="ui-icon ui-icon-folder-open"
collapsedIcon="ui-icon ui-icon-folder-collapsed">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="document" icon="ui-icon ui-icon-document">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="image" icon="ui-icon ui-icon-image">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="video" icon="ui-icon ui-icon-video">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:ajax event="select" listener="#{treeManagedBean.onNodeSelect}"></p:ajax>
<p:ajax event="unselect" listener="#{treeManagedBean.onNodeUnSelect}"></p:ajax>
<p:ajax event="expand" listener="#{treeManagedBean.onNodeExpand}"></p:ajax>
<p:ajax event="collapse" listener="#{treeManagedBean.onNodeCollapse}"></p:ajax>
</p:tree>
</h:form>
</html>
Việc áp dụng khái niệm kéo thả trên một cây đơn lẻ khá dễ dàng. Một ví dụ phức tạp hơn có thể thấy khi bạn muốn kéo thả giữa nhiều thành phần cây. Ví dụ sau cho bạn thấy một ví dụ đơn giản cho điều đó. Lần này, bạn cần sử dụng thuộc tính dragdropScope
mới để làm cho các nút của cây có thể kéo và thả giữa các cây với nhau.
Mã nguồn index5.xhtml
:
<html xmlns="<https://www.w3.org/1999/xhtml>"
xmlns:ui="<https://java.sun.com/jsf/facelets>"
xmlns:h="<https://java.sun.com/jsf/html>"
xmlns:f="<https://java.sun.com/jsf/core>"
xmlns:p="<https://primefaces.org/ui>">
<h:head>
<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>
<p:tree value="#{treeManagedBean.root}" var="node" dynamic="true" droppable="true" draggable="true"
selectionMode="single" selection="#{treeManagedBean.singleSelectedTreeNode}"
dragdropScope="myScope">
<p:treeNode expandedIcon="ui-icon ui-icon-folder-open"
collapsedIcon="ui-icon ui-icon-folder-collapsed">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="document" icon="ui-icon ui-icon-document">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="image" icon="ui-icon ui-icon-image">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="video" icon="ui-icon ui-icon-video">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:ajax event="select" listener="#{treeManagedBean.onNodeSelect}"></p:ajax>
<p:ajax event="unselect" listener="#{treeManagedBean.onNodeUnSelect}"></p:ajax>
<p:ajax event="expand" listener="#{treeManagedBean.onNodeExpand}"></p:ajax>
<p:ajax event="collapse" listener="#{treeManagedBean.onNodeCollapse}"></p:ajax>
</p:tree>
<p:tree value="#{treeManagedBean.root}" var="node" dynamic="true" droppable="true" draggable="true"
selectionMode="single" selection="#{treeManagedBean.singleSelectedTreeNode}"
dragdropScope="myScope">
<p:treeNode expandedIcon="ui-icon ui-icon-folder-open"
collapsedIcon="ui-icon ui-icon-folder-collapsed">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="document" icon="ui-icon ui-icon-document">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="image" icon="ui-icon ui-icon-image">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="video" icon="ui-icon ui-icon-video">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:ajax event="select" listener="#{treeManagedBean.onNodeSelect}"></p:ajax>
<p:ajax event="unselect" listener="#{treeManagedBean.onNodeUnSelect}"></p:ajax>
<p:ajax event="expand" listener="#{treeManagedBean.onNodeExpand}"></p:ajax>
<p:ajax event="collapse" listener="#{treeManagedBean.onNodeCollapse}"></p:ajax>
</p:tree>
</h:form>
</html>
Horizontal Tree trong PrimeFaces
Mặc định, hướng của cây là dọc. Việc đặt thuộc tính orientation
thành horizontal
sẽ hiển thị các nút theo bố cục ngang. Tất cả các tính năng của cây dọc ngoại trừ kéo thả đều có sẵn cho cây ngang.
Mã nguồn index6.xhtml
:
<html xmlns="<https://www.w3.org/1999/xhtml>"
xmlns:ui="<https://java.sun.com/jsf/facelets>"
xmlns:h="<https://java.sun.com/jsf/html>"
xmlns:f="<https://java.sun.com/jsf/core>"
xmlns:p="<https://primefaces.org/ui>">
<h:head>
<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>
<p:tree value="#{treeManagedBean.root}" var="node" dynamic="true" orientation="horizontal"
selectionMode="single" selection="#{treeManagedBean.singleSelectedTreeNode}">
<p:treeNode expandedIcon="ui-icon ui-icon-folder-open"
collapsedIcon="ui-icon ui-icon-folder-collapsed">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="document" icon="ui-icon ui-icon-document">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="image" icon="ui-icon ui-icon-image">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="video" icon="ui-icon ui-icon-video">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:ajax event="select" listener="#{treeManagedBean.onNodeSelect}"></p:ajax>
<p:ajax event="unselect" listener="#{treeManagedBean.onNodeUnSelect}"></p:ajax>
<p:ajax event="expand" listener="#{treeManagedBean.onNodeExpand}"></p:ajax>
<p:ajax event="collapse" listener="#{treeManagedBean.onNodeCollapse}"></p:ajax>
</p:tree>
</h:form>
</html>
PrimeFaces ContextMenu
PrimeFaces cung cấp một thành phần đặc biệt giúp bạn thực hiện các thao tác theo ngữ cảnh: p:contextMenu
. Thành phần Tree thậm chí đã tích hợp với context menu để bạn có thể áp dụng các thao tác đã sắp xếp chống lại nút đã chọn và các nút trong trường hợp bạn đã phát triển nhiều lựa chọn.
Bạn sử dụng thuộc tính for
của ContextMenu
để tham chiếu đến thuộc tính id
của thành phần Tree, sao cho menu đã định nghĩa được hiển thị mỗi khi một nút cụ thể trong thành phần Tree được chọn. Hãy sử dụng chuột phải để hiển thị thành phần context menu.
Mã nguồn index6.xhtml
:
<html xmlns="<https://www.w3.org/1999/xhtml>"
xmlns:ui="<https://java.sun.com/jsf/facelets>"
xmlns:h="<https://java.sun.com/jsf/html>"
xmlns:f="<https://java.sun.com/jsf/core>"
xmlns:p="<https://primefaces.org/ui>">
<h:head>
<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>
<p:contextMenu for="tree">
<p:menuitem value="View" actionListener="#{treeManagedBean.view}" icon="ui-icon-search"></p:menuitem>
</p:contextMenu>
<p:tree id="tree" value="#{treeManagedBean.root}" var="node" dynamic="true" orientation="horizontal"
selectionMode="single" selection="#{treeManagedBean.singleSelectedTreeNode}">
<p:treeNode expandedIcon="ui-icon ui-icon-folder-open"
collapsedIcon="ui-icon ui-icon-folder-collapsed">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="document" icon="ui-icon ui-icon-document">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="image" icon="ui-icon ui-icon-image">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:treeNode type="video" icon="ui-icon ui-icon-video">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:ajax event="select" listener="#{treeManagedBean.onNodeSelect}"></p:ajax>
<p:ajax event="unselect" listener="#{treeManagedBean.onNodeUnSelect}"></p:ajax>
<p:ajax event="expand" listener="#{treeManagedBean.onNodeExpand}"></p:ajax>
<p:ajax event="collapse" listener="#{treeManagedBean.onNodeCollapse}"></p:ajax>
</p:tree>
</h:form>
</html>
Mã nguồn TreeManagedBean.java
:
package com.journaldev.prime.faces.beans;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ActionEvent;
import org.primefaces.event.NodeCollapseEvent;
import org.primefaces.event.NodeExpandEvent;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.event.NodeUnselectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
@ManagedBean
@SessionScoped
public class TreeManagedBean {
// TreeNode instance
private TreeNode root;
private TreeNode singleSelectedTreeNode;
private TreeNode [] multipleSelectedTreeNodes;
private TreeNode [] checkboxSelectedTreeNodes;
public TreeManagedBean(){
// This is the root node, so it's data is root and its parent is null
this.root = new DefaultTreeNode("Root Node", null);
// Create documents node
TreeNode documents = new DefaultTreeNode("Documents", this.root);
// Create document node
TreeNode document01 = new DefaultTreeNode("document","Expenses.doc", documents);
// Create images node
TreeNode images = new DefaultTreeNode("Images", this.root);
// Create image node
TreeNode image01 = new DefaultTreeNode("image","Travel.gif", images);
// Create videos node
TreeNode videos = new DefaultTreeNode("Videos", this.root);
// Create video node
TreeNode video01 = new DefaultTreeNode("video","Play.avi", videos);
}
public TreeNode getRoot() {
return root;
}
public void setRoot(TreeNode root) {
this.root = root;
}
public TreeNode getSingleSelectedTreeNode() {
return singleSelectedTreeNode;
}
public void setSingleSelectedTreeNode(TreeNode singleSelectedTreeNode) {
this.singleSelectedTreeNode = singleSelectedTreeNode;
}
public TreeNode[] getMultipleSelectedTreeNodes() {
return multipleSelectedTreeNodes;
}
public void setMultipleSelectedTreeNodes(TreeNode[] multipleSelectedTreeNodes) {
this.multipleSelectedTreeNodes = multipleSelectedTreeNodes;
}
public TreeNode[] getCheckboxSelectedTreeNodes() {
return checkboxSelectedTreeNodes;
}
public void setCheckboxSelectedTreeNodes(TreeNode[] checkboxSelectedTreeNodes) {
this.checkboxSelectedTreeNodes = checkboxSelectedTreeNodes;
}
public void onNodeSelect(NodeSelectEvent event){
System.out.println("Node Data ::"+event.getTreeNode().getData()+" :: Selected");
}
public void onNodeUnSelect(NodeUnselectEvent event){
System.out.println("Node Data ::"+event.getTreeNode().getData()+" :: UnSelected");
}
public void onNodeExpand(NodeExpandEvent event){
System.out.println("Node Data ::"+event.getTreeNode().getData()+" :: Expanded");
}
public void onNodeCollapse(NodeCollapseEvent event){
System.out.println("Node Data ::"+event.getTreeNode().getData()+" :: Collapsed");
}
public String printSelectedNodes(){
System.out.println("Single Selection Is :: "+this.singleSelectedTreeNode.getData());
if (this.multipleSelectedTreeNodes != null) {
for(TreeNode n : this.multipleSelectedTreeNodes){
System.out.println("Multiple Selection Are :: "+n.getData());
}
}
if (this.checkboxSelectedTreeNodes != null) {
for(TreeNode n : this.checkboxSelectedTreeNodes){
System.out.println("CheckBox Selection Are :: "+n.getData());
}
}
return "";
}
public void view(ActionEvent e){
System.out.println("View action has invoked against node :: "+this.singleSelectedTreeNode.getData());
}
}
PrimeFaces TreeTable
TreeTable
là một thành phần cực kỳ hữu ích để bạn hiển thị dữ liệu phân cấp dưới dạng bảng. Nó kết hợp sức mạnh của Tree
và DataTable
, cho phép bạn quản lý và tương tác với cấu trúc dữ liệu phức tạp một cách trực quan hơn.
Bắt đầu với PrimeFaces TreeTable
Thuộc tính | Giá trị |
---|---|
Tên | TreeTable |
Lớp thành phần | org.primefaces.component.treetable.TreeTable |
Loại thành phần | org.primefaces.component.TreeTable |
Nhóm thành phần | org.primefaces.component |
Loại bộ kết xuất | org.primefaces.component.TreeTableRenderer |
Lớp bộ kết xuất | org.primefaces.component.treetable.TreeTableRenderer |
Tên thuộc tính | Mặc định | Kiểu | Mô tả |
---|---|---|---|
id |
null |
String | Định danh duy nhất của thành phần |
rendered |
true |
Boolean | Xác định có render thành phần hay không |
binding |
null |
Object | Biểu thức EL ánh xạ đến UIComponent trong backing bean |
value |
null |
Object | Mô hình dữ liệu dạng TreeNode |
var |
null |
String | Tên biến trong request để truy cập dữ liệu từng node |
widgetVar |
null |
String | Tên widget phía client |
style |
null |
String | CSS inline của phần tử chứa |
styleClass |
null |
String | Lớp CSS của phần tử chứa |
selection |
null |
Object | Tham chiếu dữ liệu được chọn |
selectionMode |
null |
String | Kiểu chọn (single, multiple, checkbox) |
scrollable |
false |
Boolean | Có cuộn dữ liệu hay không |
scrollHeight |
null |
Integer | Chiều cao vùng cuộn |
scrollWidth |
null |
Integer | Chiều rộng vùng cuộn |
tableStyle |
null |
String | CSS inline của bảng |
tableStyleClass |
null |
String | Lớp CSS của bảng |
emptyMessage |
"No records found" |
String | Thông báo khi không có dữ liệu |
resizableColumns |
false |
Boolean | Có thể thay đổi kích thước cột không |
rowStyleClass |
null |
String | Lớp CSS cho mỗi hàng |
liveResize |
false |
Boolean | Thay đổi kích thước cột trực tiếp |
required |
false |
Boolean | Ràng buộc lựa chọn bắt buộc |
requiredMessage |
null |
String | Thông báo nếu không chọn mà có ràng buộc |
sortBy |
null |
ValueExpr | Biểu thức sắp xếp mặc định |
sortOrder |
ascending |
String | Thứ tự sắp xếp mặc định |
sortFunction |
null |
MethodExpr | Hàm sắp xếp tùy chỉnh |
nativeElements |
false |
Boolean | Sử dụng checkbox gốc trong native mode |
dataLocale |
null |
Object | Locale dùng cho tính năng như sắp xếp |
caseSensitiveSort |
false |
Boolean | Sắp xếp có phân biệt hoa thường hay không |
Tương tự như Tree
, TreeTable
được điền dữ liệu bằng một instance TreeNode
tương ứng với nút gốc. API TreeNode
cung cấp cấu trúc dữ liệu phân cấp và đại diện cho dữ liệu sẽ được điền vào bảng cây. Ví dụ sau cho bạn thấy các instance tài liệu Plain Old Java Object (POJO) được hiển thị bằng thành phần TreeTable
.
Mã nguồn index7.xhtml
:
<html xmlns="<https://www.w3.org/1999/xhtml>"
xmlns:ui="<https://java.sun.com/jsf/facelets>"
xmlns:h="<https://java.sun.com/jsf/html>"
xmlns:f="<https://java.sun.com/jsf/core>"
xmlns:p="<https://primefaces.org/ui>">
<h:head>
<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>
<p:treeTable value="#{treeTableManagedBean.root}" var="node">
<p:column>
<f:facet name="header">
Name
</f:facet>
<h:outputText value="#{node.name}"></h:outputText>
</p:column>
<p:column>
<f:facet name="header">
Author
</f:facet>
<h:outputText value="#{node.author}"></h:outputText>
</p:column>
<p:column>
<f:facet name="header">
ID
</f:facet>
<h:outputText value="#{node.id}"></h:outputText>
</p:column>
</p:treeTable>
</h:form>
</html>
Mã nguồn Document.java
(POJO):
package com.journaldev.prime.faces.data;
public class Document {
private String name;
private String id;
private String author;
public Document(String name, String id,String author){
this.name = name;
this.id = id;
this.author = author;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
Mã nguồn TreeTableManagedBean.java
:
package com.journaldev.prime.faces.beans;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
import com.journaldev.prime.faces.data.Document;
@ManagedBean
@SessionScoped
public class TreeTableManagedBean {
private TreeNode root = new DefaultTreeNode("Root Node", null);
public TreeTableManagedBean(){
// Populate Document Instances
Document doc01 = new Document("Primefaces Tutorial","1","Primefaces Company");
Document doc02 = new Document("Hibernate Tutorial","2","JournalDev");
// Create Documents TreeNode
TreeNode documents = new DefaultTreeNode(new Document("Documents","0","Documents"), this.root);
// Create Document TreeNode
TreeNode document01 = new DefaultTreeNode(doc01, documents);
TreeNode document02 = new DefaultTreeNode(doc02, documents);
}
public TreeNode getRoot() {
return root;
}
public void setRoot(TreeNode root) {
this.root = root;
}
}
PrimeFaces TreeTable – Selection
Tương tự như thành phần Tree, chức năng chọn nút là một tính năng tích hợp, cho phép bạn xác định kiểu lựa chọn: Single
, multiple
và checkbox
là các giá trị bạn có thể sử dụng. Lựa chọn đơn sẽ liên kết nút đã chọn của bạn với một instance TreeNode
duy nhất, trong khi các lựa chọn khác sử dụng một mảng TreeNode
.
Ví dụ sau cho bạn thấy cách bạn có thể hiển thị lựa chọn của người dùng bằng cách sử dụng Growl Message
. Ví dụ này sử dụng p:commandButton
do PrimeFaces cung cấp, mà chúng ta sẽ thảo luận sau.
Mã nguồn index8.xhtml
:
<html xmlns="<https://www.w3.org/1999/xhtml>"
xmlns:ui="<https://java.sun.com/jsf/facelets>"
xmlns:h="<https://java.sun.com/jsf/html>"
xmlns:f="<https://java.sun.com/jsf/core>"
xmlns:p="<https://primefaces.org/ui>">
<h:head>
<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>
<p:growl id="message">
</p:growl>
<p:treeTable value="#{treeTableManagedBean.root}" var="node" selectionMode="single"
selection="#{treeTableManagedBean.singleSelectedNode}">
<p:column>
<f:facet name="header">
Name
</f:facet>
<h:outputText value="#{node.name}"></h:outputText>
</p:column>
<p:column>
<f:facet name="header">
Author
</f:facet>
<h:outputText value="#{node.author}"></h:outputText>
</p:column>
<p:column>
<f:facet name="header">
ID
</f:facet>
<h:outputText value="#{node.id}"></h:outputText>
</p:column>
</p:treeTable>
<p:treeTable value="#{treeTableManagedBean.root}" var="node" selectionMode="multiple"
selection="#{treeTableManagedBean.multipleSelectedNodes}">
<p:column>
<f:facet name="header">
Name
</f:facet>
<h:outputText value="#{node.name}"></h:outputText>
</p:column>
<p:column>
<f:facet name="header">
Author
</f:facet>
<h:outputText value="#{node.author}"></h:outputText>
</p:column>
<p:column>
<f:facet name="header">
ID
</f:facet>
<h:outputText value="#{node.id}"></h:outputText>
</p:column>
</p:treeTable>
<p:treeTable value="#{treeTableManagedBean.root}" var="node" selectionMode="checkbox"
selection="#{treeTableManagedBean.checkboxSelectedNodes}">
<p:column>
<f:facet name="header">
Name
</f:facet>
<h:outputText value="#{node.name}"></h:outputText>
</p:column>
<p:column>
<f:facet name="header">
Author
</f:facet>
<h:outputText value="#{node.author}"></h:outputText>
</p:column>
<p:column>
<f:facet name="header">
ID
</f:facet>
<h:outputText value="#{node.id}"></h:outputText>
</p:column>
</p:treeTable>
<p:commandButton value="Show Selected Documents" action="#{treeTableManagedBean.viewSelectedNodes}" process="@form" update="message">
</p:commandButton>
</h:form>
</html>
Mã nguồn TreeTableManagedBean.java
:
package com.journaldev.prime.faces.beans;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
import com.journaldev.prime.faces.data.Document;
@ManagedBean
@SessionScoped
public class TreeTableManagedBean {
private TreeNode root = new DefaultTreeNode("Root Node", null);
private TreeNode singleSelectedNode;
private TreeNode [] multipleSelectedNodes;
private TreeNode [] checkboxSelectedNodes;
public TreeTableManagedBean(){
// Populate Document Instances
Document doc01 = new Document("Primefaces Tutorial","1","Primefaces Company");
Document doc02 = new Document("Hibernate Tutorial","2","JournalDev");
// Create Documents TreeNode
TreeNode documents = new DefaultTreeNode(new Document("Documents","0","Documents"), this.root);
// Create Document TreeNode
TreeNode document01 = new DefaultTreeNode(doc01, documents);
TreeNode document02 = new DefaultTreeNode(doc02, documents);
}
public TreeNode getRoot() {
return root;
}
public void setRoot(TreeNode root) {
this.root = root;
}
public TreeNode getSingleSelectedNode() {
return singleSelectedNode;
}
public void setSingleSelectedNode(TreeNode singleSelectedNode) {
this.singleSelectedNode = singleSelectedNode;
}
public TreeNode[] getMultipleSelectedNodes() {
return multipleSelectedNodes;
}
public void setMultipleSelectedNodes(TreeNode[] multipleSelectedNodes) {
this.multipleSelectedNodes = multipleSelectedNodes;
}
public TreeNode[] getCheckboxSelectedNodes() {
return checkboxSelectedNodes;
}
public void setCheckboxSelectedNodes(TreeNode[] checkboxSelectedNodes) {
this.checkboxSelectedNodes = checkboxSelectedNodes;
}
public String viewSelectedNodes(){
String message = "You've selected documents :: \\\\n";
if (this.singleSelectedNode != null) {
message+="- "+((Document)this.singleSelectedNode.getData()).getName()+"\\\\n";
}
if (this.multipleSelectedNodes != null) {
for(TreeNode node : this.multipleSelectedNodes){
message+="- "+((Document)node.getData()).getName()+"\\\\n";
}
}
if (this.checkboxSelectedNodes != null) {
for(TreeNode node : this.checkboxSelectedNodes){
message+="- "+((Document)node.getData()).getName()+"\\\\n";
}
}
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(message));
return "";
}
}
PrimeFaces TreeTable – Sự kiện Ajax & ContextMenu
TreeTable
cũng hỗ trợ các sự kiện hành vi Ajax tương tự như thành phần Tree. Một sự kiện ngoại lệ là colResize
, sẽ được kích hoạt khi một cột được thay đổi kích thước. Ngoài ra, việc sử dụng ContextMenu
cũng không khác gì so với thành phần Tree.
Đáng tiếc, phiên bản PrimeFaces 5.0 miễn phí mà chúng ta đang sử dụng có một vấn đề quan trọng ngăn cản việc làm rõ sự kiện lắng nghe thay đổi kích thước cột. Tuy nhiên, để bạn biết cách lắng nghe sự kiện đó, một ví dụ đơn giản được cung cấp dưới đây:
Mã nguồn index9.xhtml
:
<html xmlns="<https://www.w3.org/1999/xhtml>"
xmlns:ui="<https://java.sun.com/jsf/facelets>"
xmlns:h="<https://java.sun.com/jsf/html>"
xmlns:f="<https://java.sun.com/jsf/core>"
xmlns:p="<https://primefaces.org/ui>">
<h:head>
<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>
<p:treeTable value="#{treeTableManagedBean.root}" var="node" resizableColumns="true">
<p:column>
<f:facet name="header">
Name
</f:facet>
<h:outputText value="#{node.name}"></h:outputText>
</p:column>
<p:column>
<f:facet name="header">
Author
</f:facet>
<h:outputText value="#{node.author}"></h:outputText>
</p:column>
<p:column>
<f:facet name="header">
ID
</f:facet>
<h:outputText value="#{node.id}"></h:outputText>
</p:column>
<p:ajax event="colResize" listener="#{treeTableManagedBean.colResizeListener}"></p:ajax>
</p:treeTable>
</h:form>
</html>
Mã nguồn Java (trong TreeTableManagedBean.java
):
// .. Some Required Code
import org.primefaces.event.ColumnResizeEvent; // Import cần thiết
public void colResizeListener(ColumnResizeEvent e){
String message ="Column resize event is thrown";
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(message));
}
PrimeFaces TreeTable – Sorting
Tính năng sắp xếp được kích hoạt bằng cách đặt biểu thức sortBy
ở cấp độ cột.
Mã nguồn index10.xhtml
:
<html xmlns="<https://www.w3.org/1999/xhtml>"
xmlns:ui="<https://java.sun.com/jsf/facelets>"
xmlns:h="<https://java.sun.com/jsf/html>"
xmlns:f="<https://java.sun.com/jsf/core>"
xmlns:p="<https://primefaces.org/ui>">
<h:head>
<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<h:form>
<p:treeTable value="#{treeTableManagedBean.root}" var="node">
<p:column sortBy="#{node.name}">
<f:facet name="header">
Name
</f:facet>
<h:outputText value="#{node.name}"></h:outputText>
</p:column>
<p:column sortBy="#{node.author}">
<f:facet name="header">
Author
</f:facet>
<h:outputText value="#{node.author}"></h:outputText>
</p:column>
<p:column sortBy="#{node.id}">
<f:facet name="header">
ID
</f:facet>
<h:outputText value="#{node.id}"></h:outputText>
</p:column>
</p:treeTable>
</h:form>
</html>
Trong trường hợp bạn muốn hiển thị TreeTable
đã được sắp xếp ngay khi tải trang, bạn có thể sử dụng thuộc tính sortBy
của TreeTable
. Các thuộc tính tùy chọn sortOrder
và sortFunction
được cung cấp để bạn định nghĩa thứ tự sắp xếp mặc định (tăng dần hoặc giảm dần) và một phương thức Java để thực hiện việc sắp xếp thực tế tương ứng.
Kết luận
Chúng ta đã cùng nhau khám phá sâu rộng về các thành phần Tree và TreeTable của PrimeFaces. Bạn đã hiểu thấu đáo cách khởi tạo và cấp dữ liệu cho chúng bằng TreeNode
, cách sử dụng chế độ dynamic
để tối ưu hiệu suất với lượng dữ liệu lớn, và cách tùy chỉnh giao diện với nhiều loại nút và biểu tượng khác nhau. Những kiến thức này sẽ giúp bạn khai thác tối đa sức mạnh của PrimeFaces để xây dựng các giao diện người dùng phức tạp, trực quan và hiệu quả. Bạn hoàn toàn có thể áp dụng chúng để phát triển các ứng dụng quản lý file, biểu đồ tổ chức, cây danh mục sản phẩm trong các hệ thống.