【问题标题】:Conditional cell edit in PrimeFaces datatablePrimeFaces 数据表中的条件单元格编辑
【发布时间】:2013-08-22 08:03:27
【问题描述】:

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

最初我尝试<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 类,并且看起来像是用户可编辑的单元格。

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

谢谢!

【问题讨论】:

    标签: jsf-2 primefaces datatable


    【解决方案1】:

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

    回到具体问题:由于editMode="cell"&lt;p:column&gt;&lt;p:cellEditor&gt; 组件的物理存在 的组合,插入了样式类。 PrimeFaces 数据表渲染器根本不考虑 &lt;p:cellEditor&gt; 是否被渲染。它直接插入ui-editable-column 样式类,然后通过JS/jQuery 触发ui-cell-editing 样式。您正在寻找解决方案的正确方向,即 JSTL,它可以有条件地在 JSF 组件树中物理添加/删除 JSF 组件,但不幸的是,它在此构造中不起作用。

    最好的办法是将an issue report 发布给 PrimeFaces 人员,要求您不仅要考虑 &lt;p:cellEditor&gt; 组件的物理存在,还要考虑其 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>
    

    【讨论】:

    • 谢谢@BalusC 我一定会尝试使用自定义渲染器并在此处发布结果。非常感谢您的全面回答!
    • 非常感谢您,我将通过拉取请求来复制此行为。
    • 如果有人好奇,请提交拉取请求:github.com/primefaces/primefaces/pull/908
    猜你喜欢
    • 1970-01-01
    • 2017-07-02
    • 2014-08-03
    • 1970-01-01
    • 2012-02-21
    • 1970-01-01
    • 2013-08-21
    • 2014-01-20
    • 2023-03-25
    相关资源
    最近更新 更多