【问题标题】:PrimeFaces TreeTable - Stop Checkbox selection propagationPrimeFaces TreeTable - 停止复选框选择传播
【发布时间】:2017-09-28 13:42:24
【问题描述】:

环境:
PrimeFaces 6.1
JSF 2.2
Tomcat 7.0.23
Java 1.7.0_79

实现了一个带有复选框选择的TreeTable,并且需要防止父节点和子节点分别向上和向下传播以进行客户端和服务器端处理。

示例树:
父节点
--子节点1
----子子节点1.1
--子节点2
----子子节点2.1

期望的行为:
选择节点时,只应选中该节点的复选框。

实际行为(开箱即用):
选择一个节点,选择子节点和父节点。例如,在上面的示例树中选择子节点 2,父节点和子子节点 2.1 也被选中。

TreeTable 组件:

<p:treeTable id="treeTable" value="#{Bean.rootNode}" var="item" selectionMode="checkbox" nodeVar="node"
    styleClass="widthFull" showUnselectableCheckbox="true" selection="#{Bean.selectedNodes}" stickyHeader="true">
    <p:ajax event="select" listener="#{Bean.processSelect(item)}" ignoreAutoUpdate="true"/>
    <p:ajax event="unselect" listener="#{Bean.processUnselect(item)}" ignoreAutoUpdate="true"/>
    ....
</p:treeTable>

覆盖 PrimeFaces JS 函数:
能够通过覆盖 PrimeFaces.widget.TreeTable.prototype.propagateUp 和 PrimeFaces.widget.TreeTable.prototype.getDescendants javascript 函数来防止在客户端处理中传播。

PrimeFaces.widget.TreeTable.prototype.propagateUp = function(node) {
    //do nothing, overriding the TreeTable propagate selection up functionality

}

PrimeFaces.widget.TreeTable.prototype.getDescendants = function(node) {
    //do nothing other than return empty array, overriding the TreeTable propagate selection down functionality by overriding getDescendants...hopefully this doesn't cause other issues
    f = [];
    return f;
}

树表更新:
TreeTable 更新是作为 ajax 选择和取消选择事件处理的一部分执行的。

RequestContext.getCurrentInstance().update("inventoryForm:treeTable");

问题:
当触发 ajax 选择和取消选择事件以禁用特定节点上的可选择性并更新 TreeTable 时,将选择子节点。处理 ajax 事件监听器时,子节点不在 Bean 上的 selectedNodes 数组中。如何防止在 TreeTable 组件更新时选择子节点?

【问题讨论】:

  • 检查 TreeTable(Renderer) java 代码的作用...也许它在那里直观地选择了它们
  • @Kukeltje 谢谢你的建议,我去那里看看。
  • @Kukeltje 再次感谢您的建议,它帮助找到了解决方案。我能够通过扩展 CheckboxTreeNode 类并覆盖propagateSelectionDown 和propagateSelectionUp 方法来完成复选框传播预防。

标签: primefaces jsf-2.2


【解决方案1】:

可以通过扩展 CheckboxTreeNode 类并覆盖propagateSelectionDown(boolean) 和propagateSelectionUp() 方法来防止从服务器端传播复选框选择。当然,您需要使用新类而不是 CheckboxTreeNode 来构建树内容。

public class MyCheckboxTreeNode extends CheckboxTreeNode {

    public MyCheckboxTreeNode() {
        super();
    }

    public MyCheckboxTreeNode(Object data, TreeNode parent) {
        super(data, parent);
    }

    public MyCheckboxTreeNode(Object data) {
        super(data);
    }

    public MyCheckboxTreeNode(String type, Object data, TreeNode parent) {
        super(type, data, parent);
    }

    @Override
    protected void propagateSelectionDown(boolean value) {
        //Do nothing, overriding CheckboxTreeNode method to prevent propagation down of tree node selections when ajax update is performed.
    }

    @Override
    protected void propagateSelectionUp() {
        //Do nothing, overriding CheckboxTreeNode method to prevent propagation up of tree node selections when ajax update is performed.
    }
}

需要覆盖额外的 PrimeFaces javascript 函数,以防止在后代节点折叠时向下传播。

//--------Override Primefaces JS
PrimeFaces.widget.TreeTable.prototype.fireSelectNodeEvent = function(b) {
    //Overriding this function in order to prevent selection of descendant nodes when parent is selected. See a.oncomplete function below.
    if (this.isCheckboxSelection()) {
           var e = this
             , a = {
               source: this.id,
               process: this.id
           };
           a.params = [{
               name: this.id + "_instantSelection",
               value: b
           }];
           a.oncomplete = function(k, f, g) {
            //commented out the logic to prevent selection of descendant nodes when parent node is selected
            //if (g.descendantRowKeys && g.descendantRowKeys !== "") {
                   //var j = g.descendantRowKeys.split(",");
                   //for (var h = 0; h < j.length; h++) {
                       //e.addToSelection(j[h])
                   //}
                   //e.writeSelections()
               //}
           }
           ;
           if (this.hasBehavior("select")) {
               var d = this.cfg.behaviors.select;
               d.call(this, a)
           } else {
               PrimeFaces.ajax.AjaxRequest(a)
           }
       } else {
           if (this.hasBehavior("select")) {
               var d = this.cfg.behaviors.select
                 , c = {
                   params: [{
                       name: this.id + "_instantSelection",
                       value: b
                   }]
               };
               d.call(this, c)
           }
       }
}

【讨论】:

    猜你喜欢
    • 2012-07-19
    • 2013-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-16
    • 2014-11-15
    • 2012-08-30
    • 2014-10-14
    相关资源
    最近更新 更多