I have a question for the Primefaces Datatable object, especially the Selection object.
In my next code, I always get Null for the "Selected Question" variable associated with Datatable with Selection.
Jsf sequence:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:p="http://primefaces.org/ui" xmlns:ui="http://java.sun.com/jsf/facelets"> <ui:composition template="mainTemplate.xhtml"> <ui:define name="contentTitle">Your Questions</ui:define> <ui:define name="content"> <h:form id="formAllQuestion"> <p:growl id="allQuestionGrowl" showDetail="true"/> <p:dataTable id="allQuestionsTable" var="question" value="#{allQuestionBean.allQuestionDataHelper}" paginator="true" rows="10" selection="#{allQuestionBean.selectedQuestion}" selectionMode="single"> <p:ajax event="rowSelect" listener="#{allQuestionBean.onRowSelect}" update=":formAllQuestion:AnswerToQuestionDialogTable :formAllQuestion:allQuestionGrowl" oncomplete="questDialog.show()"/> <p:ajax event="rowUnselect" listener="#{allQuestionBean.onRowUnselect}" update=":formAllQuestion:allQuestionGrowl"/> <f:facet name="header">Select a Row to display your Question Details</f:facet> <p:column headerText="QuestionID"> #{question.questionId} </p:column> <p:column headerText="Question Name"> #{question.questionName} </p:column> <p:column headerText="Question Description"> #{question.questionText} </p:column> <p:column headerText="Question Short Description"> #{question.questionShortText} </p:column> <p:column headerText="Author"> #{question.professor.profSurename} #{question.professor.profName} </p:column> </p:dataTable> <p:dialog header="Question Details" widgetVar="questionDialog" resizable="true" id="questDialog" showEffect="fade" hideEffect="fade" modal="true"> <p:dataTable id="AnswerToQuestionDialogTable" var="answer" value="#{allQuestionBean.answers}"> <f:facet name="header"> Hier kommt der QR_Code rein! #{allQuestionBean.selectedQuestion.questionId} - #{allQuestionBean.selectedQuestion.questionName} </f:facet> <p:column headerText="Answer"> <h:outputText value="#{answer.answerText}"/> </p:column> <p:column headerText="Counts For this Answer"> <h:outputText value="Bis jetz noch nix!"/> </p:column> </p:dataTable> </p:dialog> </h:form> </ui:define> </ui:composition> </html>
And the associated Bean class (AllQuestionBean.class):
@ManagedBean(name = "allQuestionBean") @ViewScoped public class AllQuestionBean implements Serializable { private static final long serialVersionUID = 7038894302985973905L; @ManagedProperty(value = "#{questionDAO}") private QuestionDAO questionDAO; @ManagedProperty(value = "#{profSession.professor}") private Professor professor; @ManagedProperty(value = "#{answerDAO}") private AnswerDAO answerDAO; @ManagedProperty(value = "#{answeredDAO}") private AnsweredDAO answeredDAO; private List<Question> questions; private Question selectedQuestion; private List<Answer> answers; private AllQuestionDataHelper allQuestionDataHelper; public AllQuestionBean(){ System.out.println("Starting Bean: "+this.getClass().getName()); } @PostConstruct public void initVariables(){ questions = questionDAO.readByProfessor(professor); } public void onRowSelect(SelectEvent event) { FacesMessage msg = new FacesMessage("Question Selected", selectedQuestion.getQuestionId()+" -- "+selectedQuestion.getQuestionName()); FacesContext.getCurrentInstance().addMessage(null, msg); } public void onRowUnselect(UnselectEvent event) { FacesMessage msg = new FacesMessage("Question Selected", selectedQuestion.getQuestionId()+" -- "+selectedQuestion.getQuestionName()); FacesContext.getCurrentInstance().addMessage(null, msg); }
Data module:
public class AllQuestionDataHelper extends ListDataModel<Question> implements SelectableDataModel<Question> { public AllQuestionDataHelper() { } public AllQuestionDataHelper(List<Question> list) { super(list); } @Override public Object getRowKey(Question question) { if(!(question == null)){ System.out.println("Your Questions --> Getting RowKey"); System.out.println("RowKey: "+question); System.out.println("RowKey: "+question.getQuestionId()); }else{ System.out.println("Warning Row Key is null"); } return question.getQuestionId(); } @Override public Question getRowData(String rowKey) { System.out.println("Your Questions --> Getting RowData"); System.out.println("RowData: "+rowKey); List<Question> questionList = (List<Question>) getWrappedData(); for(Question q : questionList){ if(rowKey.equals(q.getQuestionId())){ System.out.println("Returning "+q.getQuestionId()); return q; } } return null; } }
I debugged several runs and mentioned that the "selectedQuestion" variable in AllQuestionBean.class is never set. Say the Variable event in "onRowSelect" contains a NULL-Object. As you can see, * .xhtml has two Datatables. The first will load normally, no problem. The onClick Bean method should start a dialog with the second Datatable, but will be completed using Nullpointer.
For Datatable, I followed the tutorial on Primefaces (http://www.primefaces.org/showcase-labs/ui/datatableRowSelectionInstant.jsf)
Chris source share