2012-09-08 11 views
22

Próbuję utworzyć DataTable z wielokrotnego wyboru Row ale dostaję błąd tu jest link do tutoriala http://www.primefaces.org/showcase/ui/datatableRowSelectionMultiple.jsf:DataModel musi implementować org.primefaces.model.SelectableDataModel, gdy zaznaczenie jest włączone.

Oto mój 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; 
} 




} 

dostaję ten błąd:

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

Link do tutoriala nie działa. Łącze robocze to: https://www.primefaces.org/showcase/ui/data/datatable/selection.xhtml – KiriSakow

Odpowiedz

62

prostu dodać ten atrybut rowKey do znacznika elementu datatable:

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

Wartość atrybutu rowKey musi być unikalna dla każdego wiersza i nie może mieć wartości null w żadnym wierszu. Może to być mieszanka kilku wartości, np .: 'rowKey =" # {userObj.id} - # {userObj.name} "' –

+0

Ponieważ miałem kilka kolumn z filtrowaniem, znalazłem rozwiązanie dodające również wartość dla atrybutu ' filteredValue' wskazuje go na listę tego samego typu obiektów. – Izerlotti

+1

@Izerlotti Twój komentarz rozwiązał problem w moim przypadku. Chciałbym wyjaśnić następnym nieznajomym: kiedy filtrujesz datatable i jest on w pewnym momencie ponownie zgłaszany (zmieniasz zakładki lub coś w tym stylu), musisz mieć 'List' elementów podlegających kontroli danych w twoim komponencie i musisz ustaw go w atrybucie "filteredValue" w twojej tabeli. Gdzie indziej dostaniesz 'DataModel musi implementować wyjątek org.primefaces.model.SelectableDataModel', który jest nieco mylący. – ba3a

3

Alternatywnie do rowKey można owinąć swoje dane w niestandardowym modelu, który naprawdę implementuje org.primefaces.model.SelectableDataModel. Jest to przydatne, jeśli

  • wszystkich klasach mają ten sam rodzaj @Id (np long) i może realizować ten sam interfejs (np EjbWithId)
  • chcesz dodać dodatkowe funkcje do danych, które są nie są specyficzne dla domeny i nie należą np User.

Interfejs może być coś takiego:

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

Następnie ogólna realizacja SelectableDataModel dla wszystkich klas można stosować:

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();} 
} 

w twojej @ManagedBean:

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

Możesz dostać to e rror, jeśli spróbujesz dodać nowy element do podstawowej listy i zapomnisz przypisać wartość do rowKey nowego elementu.

Powiązane problemy