使用 JSF 树状小部件解耦导航和选择
Decouple navigation and selection with JSF tree-like widget
我正在寻找一种实现具有以下要求的树状 JSF 小部件的好方法:
- 表示展开和折叠树枝
- ajax 通过点击树节点导航
- 通过三态复选框多选节点/分支
- 前三个功能必须相互独立工作
- 解决方案必须与 PrimeFaces 兼容
- 我不想在编写自定义组件方面分叉框架
我遇到了什么:
- PrimeFaces
p:tree
和 p:treeTable
- 内置选择功能通过三态复选框提供了一个很好的实现,但与单击节点紧密相关,这使得它在导航方面无法使用(选择也会改变)
- 或者,即使使用
pe:triStateCheckbox
(PrimeFaces 扩展) ,复选框列的自定义实现也必须重新发明整个三态复选框逻辑
- OmniFaces
o:tree
似乎提供了高水平的定制,但也留下了很多手工制作的余地
欢迎任何提示和经验。
我最终得到了一个基于 p:treeTable
的解决方案,其中 selectionMode="checkbox"
和 p:commandLink
用于导航。
要禁用 'full row' 鼠标单击触发器也会导致选择更改,JavaScript 已按如下方式调整(PrimeFaces 5.3):
<script type="text/javascript">
//<![CDATA[
PrimeFaces.widget.TreeTable.prototype.bindSelectionEvents = function() {
var $this = this,
rowSelector = '> tr.ui-treetable-selectable-node';
this.tbody.off('mouseover.treeTable mouseout.treeTable click.treeTable', rowSelector)
.on('mouseover.treeTable', rowSelector, null, function(e) {
var element = $(this);
if(!element.hasClass('ui-state-highlight')) {
element.addClass('ui-state-hover');
if($this.isCheckboxSelection() && !$this.cfg.nativeElements) {
element.find('> td:first-child > div.ui-chkbox > div.ui-chkbox-box').addClass('ui-state-hover');
}
}
})
.on('mouseout.treeTable', rowSelector, null, function(e) {
var element = $(this);
if(!element.hasClass('ui-state-highlight')) {
element.removeClass('ui-state-hover');
if($this.isCheckboxSelection() && !$this.cfg.nativeElements) {
element.find('> td:first-child > div.ui-chkbox > div.ui-chkbox-box').removeClass('ui-state-hover');
}
}
})
.on('click.treeTable', rowSelector, null, function(e) {
//$this.onRowClick(e, $(this));
e.preventDefault();
});
if(this.isCheckboxSelection()) {
var checkboxSelector = this.cfg.nativeElements ? '> tr.ui-treetable-selectable-node > td:first-child :checkbox':
'> tr.ui-treetable-selectable-node > td:first-child div.ui-chkbox-box';
this.tbody.off('click.treeTable-checkbox', checkboxSelector)
.on('click.treeTable-checkbox', checkboxSelector, null, function(e) {
var node = $(this).closest('tr.ui-treetable-selectable-node');
$this.toggleCheckboxNode(node);
});
//initial partial selected visuals
if(this.cfg.nativeElements) {
this.indeterminateNodes(this.tbody.children('tr.ui-treetable-partialselected'));
}
}
};
//]]>
</script>
我也改了一些CSS,主要是:
.ui-treetable .ui-treetable-data tr.ui-state-highlight,
.ui-treetable .ui-treetable-data tr.ui-state-hover {
cursor: default;
}
我正在寻找一种实现具有以下要求的树状 JSF 小部件的好方法:
- 表示展开和折叠树枝
- ajax 通过点击树节点导航
- 通过三态复选框多选节点/分支
- 前三个功能必须相互独立工作
- 解决方案必须与 PrimeFaces 兼容
- 我不想在编写自定义组件方面分叉框架
我遇到了什么:
- PrimeFaces
p:tree
和p:treeTable
- 内置选择功能通过三态复选框提供了一个很好的实现,但与单击节点紧密相关,这使得它在导航方面无法使用(选择也会改变)
- 或者,即使使用
pe:triStateCheckbox
(PrimeFaces 扩展) ,复选框列的自定义实现也必须重新发明整个三态复选框逻辑
- OmniFaces
o:tree
似乎提供了高水平的定制,但也留下了很多手工制作的余地
欢迎任何提示和经验。
我最终得到了一个基于 p:treeTable
的解决方案,其中 selectionMode="checkbox"
和 p:commandLink
用于导航。
要禁用 'full row' 鼠标单击触发器也会导致选择更改,JavaScript 已按如下方式调整(PrimeFaces 5.3):
<script type="text/javascript">
//<![CDATA[
PrimeFaces.widget.TreeTable.prototype.bindSelectionEvents = function() {
var $this = this,
rowSelector = '> tr.ui-treetable-selectable-node';
this.tbody.off('mouseover.treeTable mouseout.treeTable click.treeTable', rowSelector)
.on('mouseover.treeTable', rowSelector, null, function(e) {
var element = $(this);
if(!element.hasClass('ui-state-highlight')) {
element.addClass('ui-state-hover');
if($this.isCheckboxSelection() && !$this.cfg.nativeElements) {
element.find('> td:first-child > div.ui-chkbox > div.ui-chkbox-box').addClass('ui-state-hover');
}
}
})
.on('mouseout.treeTable', rowSelector, null, function(e) {
var element = $(this);
if(!element.hasClass('ui-state-highlight')) {
element.removeClass('ui-state-hover');
if($this.isCheckboxSelection() && !$this.cfg.nativeElements) {
element.find('> td:first-child > div.ui-chkbox > div.ui-chkbox-box').removeClass('ui-state-hover');
}
}
})
.on('click.treeTable', rowSelector, null, function(e) {
//$this.onRowClick(e, $(this));
e.preventDefault();
});
if(this.isCheckboxSelection()) {
var checkboxSelector = this.cfg.nativeElements ? '> tr.ui-treetable-selectable-node > td:first-child :checkbox':
'> tr.ui-treetable-selectable-node > td:first-child div.ui-chkbox-box';
this.tbody.off('click.treeTable-checkbox', checkboxSelector)
.on('click.treeTable-checkbox', checkboxSelector, null, function(e) {
var node = $(this).closest('tr.ui-treetable-selectable-node');
$this.toggleCheckboxNode(node);
});
//initial partial selected visuals
if(this.cfg.nativeElements) {
this.indeterminateNodes(this.tbody.children('tr.ui-treetable-partialselected'));
}
}
};
//]]>
</script>
我也改了一些CSS,主要是:
.ui-treetable .ui-treetable-data tr.ui-state-highlight,
.ui-treetable .ui-treetable-data tr.ui-state-hover {
cursor: default;
}