PrimeFaces数据表中的条件单元格编辑

Met*_*eta 8 datatable primefaces jsf-2

我想只有在满足某些条件时才允许用户编辑数据表中的单元格.

最初我试图<choose>实现这个目标:

<p:dataTable var="item" value="${bean.items}" editable="true" editMode="cell">
    <p:column headerText="column A">
        <c:choose>
            <c:when test="${item.isEditable}">
                <p:cellEditor id="title">
                    <f:facet name="output">
                        <h:outputText value="#{item.title}"/>
                    </f:facet>
                    <f:facet name="input">
                        <p:inputText value="#{item.title}"/>
                    </f:facet>
                </p:cellEditor>
            </c:when>
            <c:otherwise>
                <h:outputText value="#{item.title}"/>
            </c:otherwise>
        </c:choose>
    </p:column>
...
Run Code Online (Sandbox Code Playgroud)

但它不起作用.另一种方法是使用rendered属性:

<p:column headerText="column A">
    <p:cellEditor rendered="${item.isEditable}">
         <f:facet name="output">
             <h:outputText value="#{item.title}"/>
         </f:facet>
         <f:facet name="input">
             <p:inputText value="#{item.title}"/>
         </f:facet>
     </p:cellEditor>
    <h:outputText value="#{item.title}" rendered="#{!item.isEditable}"/>
</p:column>
Run Code Online (Sandbox Code Playgroud)

工作正常 - 用户只能编辑允许的单元格.

但即使单元格不可编辑,它仍然具有ui-cell-editing类,并且看起来像用户的可编辑单元格.

将条件应用于单元格编辑的正确方法是什么?

谢谢!

Bal*_*usC 6

为了正确地学习JSTL失败的教训,它失败的原因在下面的答案中解释:JSF2 Facelets中的JSTL有意义吗?简而言之:#{item}JSTL运行时暂不可用.

回到具体问题:由于组合editMode="cell"和组件的物理存在,插入了样式类.PrimeFaces数据表渲染器根本不考虑是否渲染.它只是直接插入样式类,而样式类又通过JS/jQuery 触发样式.您正在寻找解决方案的正确方向,JSTL可以在JSF组件树中有条件地物理添加/删除JSF组件,但遗憾的是它不能在此构造中工作.<p:cellEditor><p:column><p:cellEditor>ui-editable-columnui-cell-editing

您最好的选择是向PrimeFaces 人员发布问题报告,您不仅要考虑<p:cellEditor>组件的实际存在,还要考虑其isRendered()结果.考虑PrimeFaces 3.5版,这将是在796线DataTableRenderer最初看起来像这样(介绍了可读性换行):

String styleClass = selectionEnabled 
    ? DataTable.SELECTION_COLUMN_CLASS 
    : (column.getCellEditor() != null) 
        ? DataTable.EDITABLE_COLUMN_CLASS 
        : null;
Run Code Online (Sandbox Code Playgroud)

并应修改如下:

String styleClass = selectionEnabled 
    ? DataTable.SELECTION_COLUMN_CLASS 
    : (column.getCellEditor() != null && column.getCellEditor().isRendered()) 
        ? DataTable.EDITABLE_COLUMN_CLASS 
        : null;
Run Code Online (Sandbox Code Playgroud)

如果你不能等待,同时你可以自己生成一个自定义渲染器.

package com.example;

import org.primefaces.component.datatable.DataTableRenderer;

public class MyDataTableRenderer extends DataTableRenderer {

    @Override
    protected void encodeCell(FacesContext context, DataTable table, UIColumn column, String clientId, boolean selected) throws IOException {
        // Copypaste here the original encodeCell() source code and make modifications where necessary.
    }

}
Run Code Online (Sandbox Code Playgroud)

然后,要使其运行,请按以下方式注册faces-config.xml:

<render-kit>
    <renderer>
        <description>Overrides the PrimeFaces table renderer with customized cell renderer.</description>
        <component-family>org.primefaces.component</component-family>
        <renderer-type>org.primefaces.component.DataTableRenderer</renderer-type>
        <renderer-class>com.example.MyDataTableRenderer</renderer-class>
    </renderer>
</render-kit>
Run Code Online (Sandbox Code Playgroud)