2013-08-20 3 views
8

Ich möchte Benutzern erlauben, Zellen in der Datentabelle nur dann zu bearbeiten, wenn eine Bedingung erfüllt ist.Bedingte Zellbearbeitung in PrimeFaces-Datentabelle

Anfangs habe ich <choose> versucht, dies zu erreichen:

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

aber es funktioniert nicht. Ein weiterer Ansatz ist rendered Attribut zu verwenden:

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

, die gut funktioniert - Benutzer können nur erlaubt, Zellen bearbeiten.

Aber auch wenn Zelle nicht editierbar ist, hat es immer noch ui-cell-editing Klasse und sieht aus wie bearbeitbare Zelle für Benutzer.

Was ist eine korrekte Methode, um die Bearbeitung von Zellen zu übernehmen?

Vielen Dank!

Antwort

6

Um richtig die Lektion zu lernen von JSTL scheitern, scheiterte es aus dem Grund in der folgenden Antwort erklärt: JSTL in JSF2 Facelets... makes sense? Auf den Punkt gebracht: #{item} im Moment nicht verfügbar ist JSTL läuft.

auf die konkrete Frage des Rückweg: dass Artklasse in den <p:column>editMode="cell" und die physischen Präsenz von<p:cellEditor> Komponente aufgrund der Kombination eingesetzt worden ist. Der Datendar-Renderer PrimeFaces berücksichtigt überhaupt nicht, ob der <p:cellEditor> gerendert wird oder nicht. Es fügt einfach die ui-editable-column Stilklasse ein, die wiederum den Stil ui-cell-editing über JS/jQuery auslöst. Sie haben in die richtige Richtung für die Lösung gesucht, JSTL, die JSF-Komponenten in der JSF-Komponentenstruktur bedingt physisch hinzufügen/entfernen kann, aber leider wird es in diesem Konstrukt nicht funktionieren.

Ihre beste Wette ist an issue report die PrimeFaces Jungs zu schreiben, wobei Sie fragen sich nicht nur auf die physische Präsenz von <p:cellEditor> Komponente zu berücksichtigen, sondern auch das isRendered() Ergebnis. Unter Berücksichtigung PrimeFaces Version 3.5, die in line 796 of DataTableRenderer class sein würde, die ursprünglich wie folgt aussieht (Zeilenumbrüche zur besseren Lesbarkeit eingeführt):

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

Und sollte geändert werden, wie folgt:

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

Wenn Sie nicht warten können, In der Zwischenzeit könntest du einen benutzerdefinierten Renderer erstellen.

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

} 

Dann bekommen sie es laufen, registrieren, wie in faces-config.xml folgt:

<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> 
+0

danke @BalusC Ich werde auf jeden Fall versuchen, benutzerdefinierte Renderer zu verwenden und das Ergebnis hier posten. Vielen Dank für die umfassende Antwort! – Meta

+0

Gern geschehen. – BalusC

+0

Vielen Dank dafür, ich werde an einer Pull-Anfrage arbeiten, um dieses Verhalten zu replizieren. –