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

时间:2013-08-20 09:59:16

标签: jsf-2 primefaces datatable

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

最初我尝试<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>
...

但它不起作用。另一种方法是使用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>

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

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

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

谢谢!

1 个答案:

答案 0 :(得分:6)

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

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

您最好的选择是将an issue report发布给PrimeFaces人员,不仅要求您考虑<p:cellEditor>组件的实际存在,还要考虑其isRendered()结果。考虑到PrimeFaces版本3.5,它将在line 796 of DataTableRenderer class中,最初看起来像这样(为了可读性而引入了新行):

String styleClass = selectionEnabled 
    ? DataTable.SELECTION_COLUMN_CLASS 
    : (column.getCellEditor() != null) 
        ? DataTable.EDITABLE_COLUMN_CLASS 
        : null;

应修改如下:

String styleClass = selectionEnabled 
    ? DataTable.SELECTION_COLUMN_CLASS 
    : (column.getCellEditor() != null && column.getCellEditor().isRendered()) 
        ? DataTable.EDITABLE_COLUMN_CLASS 
        : null;

如果你迫不及待,那么你可以在家里制作一个自定义渲染器。

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.
    }

}

然后,要使其运行,请在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>