2012-09-08 18 views
22

Estoy intentando crear un DataTable con la Selección de múltiples filas, pero estoy recibiendo un error aquí está el enlace del tutorial http://www.primefaces.org/showcase/ui/datatableRowSelectionMultiple.jsf:DataModel debe implementar org.primefaces.model.SelectableDataModel cuando la selección esté habilitada.

Aquí está mi XHTML:

<p:dataTable border="1" value="#{projectAdminisrationMB.projectNoUsersList}" 
        var="userObj" 
        selection="# 
     {projectAdminisrationMB.selectedUsers}" 
selectionMode="multiple" rowIndexVar="rowIndex"binding="#{table2}"> 
<p:column id="column3"> 
<f:facet name="header"> 
<h:outputText value=" user "></h:outputText> 
</f:facet> 

     <h:outputText value="#{userObj.name}"/> 

          /
    <h:outputText value="#{userObj.lastName}"></h:outputText> 

    &nbsp; 
    <h:outputText value="#{userObj.firstName}"></h:outputText> 
    </p:column> 

    <f:facet name="footer"> 
    <p:commandButton id="addProjectUser" value=" Add " onclick="dlg1.show()" /> 
     <p:commandButton id="deleteProjectUser" value=" Delete " /> 

    </f:facet> 

</p:dataTable> 

Managed Bean:

@ManagedBean 
@SessionScoped 
public class ProjectAdminisrationMB implements Serializable { 

private static final long serialVersionUID = 1L; 

private String projectName; 
private List <User> projectUsersList; 
private List<User> projectNoUsersList; 
private List<User> selectedUsers; 

private String projectAdmin; 


public ProjectAdminisrationMB() { 
    super(); 
    AdministrationProjectFinal administrationProjectFinal =new  
      AdministrationProjectFinal(); 
    this.projectUsersList=administrationProjectFinal.getUserList(); 
    this.projectNoUsersList=administrationProjectFinal.getNotUserList(); 
} 



public String getProjectName() { 
    return projectName; 
} 

public void setProjectName(String projectName) { 
    this.projectName = projectName; 
} 



public List<User> getProjectUsersList() { 
    return projectUsersList; 
} 



public void setProjectUsersList(List<User> projectUsersList) { 
    this.projectUsersList = projectUsersList; 
} 



public String getProjectAdmin() { 
    return projectAdmin; 
} 

public void setProjectAdmin(String projectAdmin) { 
    this.projectAdmin = projectAdmin; 
} 

public List<User> getProjectNoUsersList() { 
    return projectNoUsersList; 
} 



public void setProjectNoUsersList(List<User> projectNoUsersList) { 
    this.projectNoUsersList = projectNoUsersList; 
} 



public List<User> getSelectedUsers() { 
    return selectedUsers; 
} 



public void setSelectedUsers(List<User> selectedUsers) { 
    this.selectedUsers = selectedUsers; 
} 




} 

estoy recibiendo este error:

javax.faces.FacesException: DataModel must implement  
    org.primefaces.model.SelectableDataModel when selection is enabled..... 
+0

El enlace del tutorial está muerto. El enlace de trabajo es: https://www.primefaces.org/showcase/ui/data/datatable/selection.xhtml – KiriSakow

Respuesta

62

sólo tiene que añadir este rowKey atributo a la etiqueta de tabla de datos:

<p:dataTable border="1" value="#{projectAdminisrationMB.projectNoUsersList}" 
var="userObj" 
rowKey="#{userObj.name}"selection="#{projectAdminisrationMB.selectedUsers}" 
selectionMode="multiple" rowIndexVar="rowIndex" 
binding="#{table2}"> 
+13

El valor del atributo rowKey debe ser exclusivo para cada fila y no puede ser nulo en ninguna fila. Puede ser una mezcla de varios valores, por ejemplo: 'rowKey =" # {userObj.id} - # {userObj.name} "' –

+0

Como tenía algunas columnas con filtrado, encontré una solución que agregaba también un valor para el atributo ' filteredValue' apuntando a una lista del mismo tipo de objetos. – Izerlotti

+1

@Izerlotti Tu comentario resolvió el problema en mi caso. Me gustaría dejarlo en claro para los próximos extraños: cuando se filtra la tabla de datos y en algún momento se reintegra (se cambian las pestañas o smth), se necesita tener una 'Lista' de elementos de tabla de datos en su bean y se necesita configúralo en el atributo 'filteredValue' de tu tabla. En otro lugar obtendrás 'DataModel debe implementar la excepción org.primefaces.model.SelectableDataModel', eso es un poco confuso. – ba3a

3

Como alternativa a rowKey se puede envolver sus datos en un modelo personalizado que en realidad implementa org.primefaces.model.SelectableDataModel. Esto es útil si

  • todas sus clases tienen el mismo tipo de @Id (por ejemplo, un long) y se puede aplicar la misma interfaz (por ejemplo EjbWithId)
  • desea añadir funcionalidades adicionales a los datos que son no es específico del dominio y no pertenece, por ejemplo User.

La interfaz puede ser algo como esto:

public interface EjbWithId 
{ 
    public long getId(); 
    public void setId(long id); 
} 

A continuación, una aplicación genérica de SelectableDataModel para todas sus clases pueden utilizarse:

public class PrimefacesEjbIdDataModel <T extends EjbWithId> 
     extends ListDataModel<T> implements SelectableDataModel<T> 
{  
    public PrimefacesEjbIdDataModel(List<T> data) 
    { 
    super(data); 
    } 

    @Override public T getRowData(String rowKey) 
    { 
    List<T> list = (List<T>) getWrappedData(); 

    for(T ejb : list) 
    { 
     if(ejb.getId()==(new Integer(rowKey))){return ejb;} 
    } 
    return null; 
    } 

    @Override public Object getRowKey(T item) {return item.getId();} 
} 

En su @ManagedBean:

private PrimefacesEjbIdDataModel<User> dmUser; //+getter 
dmUser = new PrimefacesEjbIdDataModel<User>(administrationProjectFinal.getUserList()); 
12

Puede obtener esta e rror si intenta agregar un nuevo elemento a la lista subyacente y olvida asignar un valor a rowKey de ese nuevo elemento.

Cuestiones relacionadas