I have a question to the Primefaces Datatable, especially to the Selection Object.
In my following Code I get always Null for the Variable "Selected Question" which is bound to the Datatable with Selection.
The jsf as followed:
<?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);
}
//---GETTER and SETTER
public AllQuestionDataHelper getAllQuestionDataHelper() {
allQuestionDataHelper = new AllQuestionDataHelper(questions);
return allQuestionDataHelper;
}
public void setAllQuestionDataHelper(AllQuestionDataHelper allQuestionDataHelper) {
this.allQuestionDataHelper = allQuestionDataHelper;
}
public QuestionDAO getQuestionDAO() {
return questionDAO;
}
public void setQuestionDAO(QuestionDAO questionDAO) {
this.questionDAO = questionDAO;
}
public Professor getProfessor() {
return professor;
}
public void setProfessor(Professor professor) {
this.professor = professor;
}
public AnswerDAO getAnswerDAO() {
return answerDAO;
}
public void setAnswerDAO(AnswerDAO answerDAO) {
this.answerDAO = answerDAO;
}
public AnsweredDAO getAnsweredDAO() {
return answeredDAO;
}
public void setAnsweredDAO(AnsweredDAO answeredDAO) {
this.answeredDAO = answeredDAO;
}
public List<Question> getQuestions() {
return questions;
}
public void setQuestions(List<Question> questions) {
this.questions = questions;
}
public Question getSelectedQuestion() {
System.out.println("getSelectedQuestion");
return selectedQuestion;
}
public void setSelectedQuestion(Question selectedQuestion) {
System.out.println("Set selected Question: "+selectedQuestion);
this.selectedQuestion = selectedQuestion;
}
public List<Answer> getAnswers() {
answers = answerDAO.getAllAnswersForQuestion(selectedQuestion);
return answers;
}
public void setAnswers(List<Answer> answers) {
this.answers = answers;
}
}
The Data Modell:
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 a few runs and mentioned that the Variable "selectedQuestion" in AllQuestionBean.class is never set. Will say, the event Variable in "onRowSelect" holds a NULL-Object.
As you can see there are two Datatables in the *.xhtml. The first one will load normally, no problems. The onClick-Method of the Bean should launch a Dialog with the Second Datatable, but will quit with a Nullpointer.
For the Datatable I followed the Tutorial at Primefaces (http://www.primefaces.org/showcase-labs/ui/datatableRowSelectionInstant.jsf)
Use rowKey attribute on p:dataTable.
rowKey is a unique Identifier that helps Primefaces engine to return the selected Object based on selection.
Usually the value you supply to the rowKey attribute is the unique property of the POJO that you are populating in to p:dataTable.
If you don't have any such unique fields in your POJO. Then its always useful to make one, for example: int rowId;, which you might increment and put in to POJO while you adding them to the List.
Related
This question already has answers here:
Creating master-detail pages for entities, how to link them and which bean scope to choose
(2 answers)
Closed 6 years ago.
I've got a datatable with values in which I get from my DB.
In my class myBean, I've got an Variable of type User to store the selected row. It just can be selected one row. Now I want to call this Variable from an other bean which is called printUser to get the selected User.
But it always prints null.
View
<p:dataTable id="userDT" var="user" value="#{myBean.getUserList()}" selection="#{myBean.selectedUser}"
rowKey="#{user.id}" >
<p:column selectionMode="single" style="width:16px;text-align:center"/>
<p:column width="200" headerText="ID">
<h:outputText value="#{user.id}" />
</p:column>
<p:column width="200" headerText="Firstname">
<h:outputText value="#{user.firstname}" />
</p:column>
<p:column width="250" headerText="Lastname">
<h:outputText value="#{user.lastname}" />
</p:column>
</p:dataTable>
myBean
#Named(value = "myBean")
#ManagedBean
#SessionScoped
public class myBean implements Serializable {
private static final long serialVersionUID = 1L;
private User selectedUser = new User();
public myBean() {
}
public List<User> getUserList() {
...
}
public Patient getSelectedUser() {
return selectedUser;
}
public void setSelectedUser(User selectedUser) {
this.selectedUser= selectedUser;
}
}
User.java
public class User {
private Integer id;
private String firstname;
private String lastname;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
}
printUser
#Named(value = "printUser")
#ManagedBean
#RequestScoped
public class printUser {
public printUser() {
}
public void getSelectedUserData(){
myBean bean = new myBean();
User user = new User();
user = bean.getSelectedUser();
System.err.println("UserID: " + user.getID());
}
}
Hope you undertand my Problem.
Thanks alot
Excuse my English
This is an example to use the entity of the selected row in the same page and in another page. The example use Lombok Getter,Setter and Data annotations for shortness:
The entity for the DataTable:
#Entity
#Data
#TableGenerator( name = "GEN_TestEntity1", table = "ID_Generator", pkColumnName = "GEN_KEY", pkColumnValue = "GEN_TestEntity1", valueColumnName = "GEN_VALUE" )
#NamedQuery( name = TestEntity1.QUERY_ALL_TESTENTITY1, query = "SELECT te1 FROM TestEntity1 te1" )
public class TestEntity1 implements Serializable
{
public static final String QUERY_ALL_TESTENTITY1 = "query_All_TestEntity1";
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue( strategy = GenerationType.TABLE, generator = "GEN_TestEntity1" )
private int id;
#Column
private String name;
}
The ManagedBean as a controller:
#ManagedBean
#SessionScoped
public class EntityBean
{
#EJB
private EntitySER entitySER;
#Getter
#Setter
private TestEntity1 selectedEntity;
public List<TestEntity1> getAllTestEntity1()
{
return entitySER.getAllTestEntity1();
}
public void onRowSelect( SelectEvent event_ )
{
}
}
Another ManagedBean which uses the first one (if you really want it):
#ManagedBean
#RequestScoped
public class AnotherBean
{
#ManagedProperty( value="#{entityBean}" )
private EntityBean entityBean;
...
}
The stateless session bean:
#Stateless
#LocalBean
public class EntitySER
{
#PersistenceContext
private EntityManager em;
public List<TestEntity1> getAllTestEntity1()
{
Query q = em.createNamedQuery( TestEntity1.QUERY_ALL_TESTENTITY1 );
return q.getResultList();
}
}
The index page (index.xhtml):
<?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"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>Page 1</title>
</h:head>
<h:body>
<h:form id="form">
<p:dataTable id="table_TestEntity1" value="#{entityBean.allTestEntity1}" var="entity" selection="#{entityBean.selectedEntity}"
rowKey="#{entity.id}" selectionMode="single">
<p:ajax event="rowSelect" listener="#{entityBean.onRowSelect}" update=":form:entID :form:entName"/>
<p:column>
#{entity.id}
</p:column>
<p:column>
#{entity.name}
</p:column>
</p:dataTable>
<p>
<h:outputLabel id="entID" value="#{entityBean.selectedEntity.id}"/>:
<h:outputLabel id="entName" value="#{entityBean.selectedEntity.name}"/>
</p>
<p>
<h:commandButton value="Page 2" action="/faces/another.xhtml"/>
</p>
</h:form>
</h:body>
</html>
The another Page (another.xhtml):
<?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"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>Another Page</title>
</h:head>
<h:body>
<p>
The selected entity: #{entityBean.selectedEntity.id}:#{entityBean.selectedEntity.name}
</p>
<h:form>
<h:commandButton value="Back" action="/faces/index.xhtml"/>
</h:form>
</h:body>
</html>
I'm new in JSF and PrimeFaces and I can't understand why my setter for selected value doesn't set:
I've got main XHTML in which after click on <p:commandButton> I want to change selected row. But after changing selection of the row on data setter setSelectedBook() get null value on entrance.
I already set selection and rowKey for <p:dataTable>.
It looks like :
main XTML:
<?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"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://xmlns.jcp.org/jsf/html"
>
<body>
<ui:composition template="./../../WEB-INF/pagesTemplate.xhtml">
<form>
<ui:define name="content">
<p:dataTable id="eventsDT" var="book" value="#{bookHolder.books}"
selectionMode= "single" selection="#{bookController.selectedBook}"
rowKey="#{book.id}">
<p:ajax event="rowSelect"/>
<p:ajax event="rowDblselect" listener="#{bookController.onDoubleRowSelect}" />
<p:column headerText="ID">
<h:outputText value="#{book.id}" />
</p:column>
<p:column headerText="Title">
<h:outputText value="#{book.longName}" />
</p:column>
</p:dataTable>
</ui:define>
<ui:define name="right">
<h:panelGrid columns="1" cellpadding="5">
<p:commandButton id="btnEdit" value="Edit"
action="#{navigationController.moveToBookEditPageSimple}"
style="width: 100px;height: 28px; margin-left: 10%"/>
</h:panelGrid>
</ui:define>
</form>
</ui:composition>
</body>
</html>
BookController that can't get value:
#Named("bookController")
#SessionScoped
#Local(BookView.class)
public class BookController implements Serializable {
public BookController() {
navigator = new NavigationController();
}
NavigationController navigator;
#Inject
BookHolder bookHolder;
private Book selectedBook;
public Book getSelectedBook() {
return selectedBook;
}
public void setSelectedBook(Book selectedBookValue) {
this.selectedBook = selectedBookValue;
}
public void onDoubleRowSelect(SelectEvent event) throws IOException {
String str = navigator.showPage("BookEdit");
FacesContext.getCurrentInstance().getExternalContext().redirect(str + ".xhtml");
}
}
BookHolderBean that contains data:
#Named("bookHolder")
#ApplicationScoped
public class BookHolder {
public BookHolder() {
}
#PostConstruct
void setValues() {
this.books = new ArrayList<>();
for (int i = 0; i < 10; i++) {
this.books.add(new Book(new ParkType(i, i,
"Book #: " + i + " (long name)",
"Book #: " + i + " (short name)",
"Book #: " + i + " (note)")));
}
}
private List<Book> books;
public List<Book> getBooks() {
return books;
}
public void setBooks(List<Book> parkTypes) {
this.books = parkTypes;
}
}
Class Book:
public class Book extends MainEntitie<Book> implements Serializable, SelectableDataModel<Book> {
#Inject
BookHolder bookHolder;
private final String longName;
private final String shortName;
public Book(BookBase sd) {
super(sd.getId(), false, false, sd.getNote());
this.longName = sd.getLongName();
this.shortName = sd.getShortName();
}
public String getLongName() {
return longName;
}
public String getShortName() {
return shortName;
}
#Override
public int getId() {
return super.getId();
}
#Override
public Object getRowKey(Book t) {
return t.getId();
}
#Override
public Book getRowData(String string) {
for (Book app : bookHolder.getBooks()) {
if (app.getId() == Integer.parseInt(string)) {
return app;
}
}
return null;
}
}
Since you use ui:define, I assume there is a ui:include in your template file (pagesTemplate.xhtml).
If so, that is great, but your included page has some unnecessary stuff, e.g. html and body tag (by the way: use h:body). No need for that.
See second part of this posting to learn how to include an xhtml file into another one.
You will notice that the content of ui:define is kind of "cut&pasted" into the your template file.
So, what about your form tag? It's being ignored (at least, I guess it won't be a parent of your datatable).
Make the h:form (again, use JSF's h:form instead of HTML form) a child of ui:define,
like:
<ui:composition template="/WEB-INF/template.xhtml"
xmlns=.....>
<ui:define name="content">
<h:form>
<p:dataTable ...>
...
</p:dataTable>
</h:form>
</ui:define>
</ui:composition>
I'm still learning how to use Facelets and I am trying to send inputted values from a JSF page to a list in a ManagedBean and then display that information in a dataTable. I have JSF page to enter in the data, a backing bean to manage the list, and a regular application for the normal objects. I can't figure out how to send the input value from the JSF to the backing bean, however.
Here is my view:
<?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"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Guestbook Form</title>
</h:head>
<h:body>
<h:form>
<h1>Guestbook Application Form</h1>
<p>Please fill out all entries and click the Submit button</p>
<h:panelGrid columns="3">
<h:outputText value = "Name: "></h:outputText>
<h:inputText id="nameInputText" required ="true"
requiredMessage="Please enter your name"
value = "#{guestbookBean.name}"
validatorMessage="Name must be fewer than 20
characters">
<f:validateLength maximum="20"/>
</h:inputText>
<h:message for="nameInputText" styleClass="error"/>
<h:outputText value = "Email: "></h:outputText>
<h:inputText id="emailInputText" required ="true"
requiredMessage="Please enter your email address"
value="#{guestbookBean.email}"
validatorMessage="Invalid email address format">
<f:validateRegex pattern ="\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*"/>
</h:inputText>
<h:message for="emailInputText" styleClass="error"/>
<h:outputText value = "Enter a message: "></h:outputText>
<h:inputTextarea id="messageInputText" required ="true"
requiredMessage="Please enter a message"
value="#{guestbookBean.message}"
validatorMessage="Message must be fewer than 140 characters">
<f:validateLength maximum="140"/>
</h:inputTextarea>
<h:message for="messageInputText" styleClass="error"/>
</h:panelGrid>
<h:commandButton value="Submit" type ="Submit" action ="#{guestbookBean.setList()}"/>
<h:commandButton value ="Reset Form" type ="reset"/>
<h:outputText escape="false" value ="#{guestbookBean.result}"/>
<h:dataTable value="#{guestbookBean.list}" var="guests"
styleClass="table" cellpadding="5" cellspacing="1" border="2">
<h:column>
<f:facet name ="header">Name</f:facet>
#{guests.name}
</h:column>
<h:column>
<f:facet name ="header">Email</f:facet>
#{guests.email}
</h:column>
<h:column>
<f:facet name ="header">Message</f:facet>
#{guests.message}
</h:column>
</h:dataTable>
</h:form>
</h:body>
</html>
Here is my backing bean:
package guestbook;
import java.util.List;
import java.util.ArrayList;
import java.io.Serializable;
import javax.enterprise.context.Dependent;
import javax.faces.bean.*;
#ManagedBean(name = "guestbookBean")
public class GuestbookBean implements Serializable{
private String na;
private String em;
private String m;
private List<GuestbookEntry> bookList = new ArrayList<>();
//Set name
public void setName(String first)
{
this.na = first;
}
//Set email
public void setEmail(String mail)
{
this.em = mail;
}
//Set message
public void setMessage(String msg)
{
this.m = msg;
}
//Return the name
public String getName()
{
return na;
}
//Return the email
public String getEmail()
{
return em;
}
//Return the message
public String getMessage()
{
return m;
}
public void setList()
{
GuestbookEntry bk = new GuestbookEntry();
bk.setName(na);
bk.setEmail(em);
bk.setMessage(m);
bookList.add(0, bk);
}
public List<GuestbookEntry> getList()
{
return bookList;
}
// returns result for rendering on the client
public String getResult()
{
if ( !bookList.isEmpty())
{
return "<p style=\"background-color:yellow;width:200px;" +
"padding:5px\">Data submitted successfully"+ "</p>";
}
else
{
return ""; // request has not yet been made
}
} // end method getResult
}
Here is my model:
package guestbook;
public class GuestbookEntry {
private String firstName;
private String lastName;
private String email;
private String message;
public void setFirstName(String fn)
{
firstName = fn;
}
public void setLastName(String ln)
{
lastName = ln;
}
public void setEmail(String em)
{
email = em;
}
public void setMessage(String m)
{
message = m;
}
public String getFirstName()
{
return firstName;
}
public String getLastName()
{
return lastName;
}
public String getEmail()
{
return email;
}
public String getMessage()
{
return message;
}
}
The data is not being reset because you are not clearing the fields after the submit
You can set to null na, em and m to reset the fields
Regarding the table, try adding #ViewScoped to your bean, the default scope is RequestScope, which is not keeping your table
Mojara 2.1.21
I'm using primefaces editor component p:editor. The value attribute in editor is a complex EL-Statement.
<h:form>
<p:datatable value="#{bean.getItems}" var="item">
<p:column>
<p:editor value="bean.A(item).value" />
</p:column>
</p:datatable>
</h:form>
class Bean {
public Entity A (Item i) { return ...}
}
class Entity {
public String getValue();
public void setValue(String);
}
The getter Entity.getValue() is called, but the setter Entity.serValue(String) is not called, if form is submitted.
I suppose it has nothing to do with editor but a common feature of EL. How can I instruct the editor to call a setter if some changes will be made in editor by a user ?
UPDATE
The variant <p:editor value="#{multiEditorBacking.eval(editor).text}" id="textArea" /> has trouble if setter will be called. But <p:editor value="#{editor.text}" id="textArea" /> is ok. The following examples can be used for testing.
<!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" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:o="http://omnifaces.org/ui" xmlns:pe="http://primefaces.org/ui/extensions">
<ui:composition>
<h:head></h:head>
<h:body>
<h:form id="formId">
<p:dataTable value="#{multiEditorBacking.editors}" var="editor" rowIndexVar="index" >
<p:column>
<p:commandButton value="Refresh" actionListener="#{multiEditorBacking.onRefresh(index)}" update="textArea"
process="#this" />
<p:editor value="#{multiEditorBacking.eval(editor).text}" id="textArea" />
<!-- <p:editor value="#{editor.text}" id="textArea" /> -->
</p:column>
</p:dataTable>
<p:commandButton value="Save" />
</h:form>
</h:body>
</ui:composition>
</html>
MultiEditorBean.java
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
#SessionScoped
#Named
public class MultiEditorBacking implements Serializable{
private List<MultiPojo> editors;
private HashMap <Integer, MultiPojo> hash = new HashMap<Integer, MultiPojo>();
#PostConstruct
public void init(){
editors = new ArrayList<MultiPojo>();
MultiPojo m = new MultiPojo();
m.setText("hey1");
editors.add(m);
hash.put(1, m);
m=new MultiPojo();
m.setText("adf2");
editors.add(m);
hash.put(2, m);
m=new MultiPojo();
m.setText("cjd3");
editors.add(m);
hash.put(3, m);
}
public MultiPojo eval (MultiPojo m){
return m;
}
public void onRefresh (int index){
}
public List<MultiPojo> getEditors() {
return editors;
}
public void setEditors(List<MultiPojo> editors) {
this.editors = editors;
}
public HashMap <Integer, MultiPojo> getHash() {
return hash;
}
public void setHash(HashMap <Integer, MultiPojo> hash) {
this.hash = hash;
}
}
MultiPojo.java
public class MultiPojo {
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
This works for me, in Mojarra 2.2.5, using EL 2.2. Are you sure you've got that EL version enabled which allows method parameter passing? You need a Servlet 3.x container available (such as Tomcat 7) or you'll need to add the library yourself. However, it seems you've got it as #{multiEditorBacking.eval(editor).text} value for your editors is being properly evaluated.
By the way, your <ui:composition> surrounding <h:head /> and <h:body /> is unecessary. Another thing I don't like from your code is the use of #SessionScoped for pure view matters. Go with #ViewScoped unless you're explicitly dealing with session related stuff.
#SessionScoped
#Named
public class MultiEditorBacking implements Serializable {
private List<MultiPojo> editors;
private HashMap<Integer, MultiPojo> hash = new HashMap<Integer, MultiPojo>();
public MultiEditorBacking() {
editors = new ArrayList<MultiPojo>();
MultiPojo m = new MultiPojo();
m.setText("hey1");
editors.add(m);
hash.put(1, m);
m = new MultiPojo();
m.setText("adf2");
editors.add(m);
hash.put(2, m);
m = new MultiPojo();
m.setText("cjd3");
editors.add(m);
hash.put(3, m);
}
public MultiPojo eval(MultiPojo m) {
return m;
}
public void onRefresh(int index) {
System.out.println("Editor " + index + " refreshed");
}
public List<MultiPojo> getEditors() {
return editors;
}
public void setEditors(List<MultiPojo> editors) {
this.editors = editors;
}
public HashMap<Integer, MultiPojo> getHash() {
return hash;
}
public void save() {
System.out.println("Editors: " + editors);
}
public void setHash(HashMap<Integer, MultiPojo> hash) {
this.hash = hash;
}
public class MultiPojo {
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
#Override
public String toString() {
return "MultiPojo [text=" + text + "]";
}
}
}
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head />
<h:body>
<h:form id="formId">
<p:dataTable value="#{multiEditorBacking.editors}" var="editor"
rowIndexVar="index">
<p:column>
<p:commandButton value="Refresh"
actionListener="#{multiEditorBacking.onRefresh(index)}"
update="textArea" process="#this" />
<p:editor value="#{multiEditorBacking.eval(editor).text}"
id="textArea" />
</p:column>
</p:dataTable>
<p:commandButton value="Save" action="#{multiEditorBacking.save}" />
</h:form>
</h:body>
</html>
See also:
Using EL 2.2 with Tomcat 6.0.24
The solution was to use brackets in EL to get setter called.
<p:editor value="#{(multiEditorBacking.eval(editor)).text}"
id="textArea" />
I need a DataTable with RadioCheckbox then found the link
FacesException: DataModel must implement org.primefaces.model.SelectableDataModel when selection is enabled
all I needed, but when running the page is blank and doesn't give exception.
Anyway I will post my code as well.
My xhtml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Primefaces 3.1</title>
</h:head>
<h:body>
<h:form id="form">
<p:dataTable value="#{tableBean.cars}" var="var" paginator="true" rows="10"
selection="#{tableBean.car}"
selectionMode="single">
<p:column>
<f:facet name="header">
<h:outputText styleClass="outputText" value="Model"></h:outputText>
</f:facet>
<h:outputText styleClass="outputText" value="#{var.model}"></h:outputText>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText styleClass="outputText" value="Color"></h:outputText>
</f:facet>
<h:outputText styleClass="outputText" value="#{var.randomColor}"></h:outputText>
</p:column>
</p:dataTable>
</h:form>
</h:body>
</html>
Bean:
#ManagedBean
#SessionScoped
public class TableBean implements Serializable{
private static final long serialVersionUID = 1L;
private List<Car> cars;
private Car car;
private CarDataModel carsModel;
public TableBean() {
cars = new ArrayList<Car>();
Car car1 = new Car();
car1.setModel("BMW");
car1.setRandomColor("Black");
cars.add(car1);
Car car2 = new Car();
car2.setModel("Audi");
car2.setRandomColor("White");
cars.add(car2);
carsModel = new CarDataModel(cars);
}
public List<Car> getCars() {
return cars;
}
public String onRowSelect(){
System.out.println("Row Click!!!");
return "otherpage";//Does this nav works???if not how???
}
public Car getCar() {
return car;
}
public CarDataModel getCarsModel() {
return carsModel;
}
public void setCarsModel(CarDataModel carsModel) {
this.carsModel = carsModel;
}
CarDataModel:
public class CarDataModel extends ListDataModel<Car> implements SelectableDataModel<Car>, Serializable {
private static final long serialVersionUID = 1L;
public CarDataModel(List<Car> data) {
super(data);
}
#Override
public Car getRowData(String rowKey) {
#SuppressWarnings("unchecked")
List<Car> cars = (List<Car>) getWrappedData();
for(Car car : cars) {
if(car.getModel().equals(rowKey))
return car;
}
return null;
}
#Override
public Object getRowKey(Car car) {
return car.getModel();
}
I do not know what can be.
Thanks!
I think the problem is here:
public TableBean() {
cars = new ArrayList<Car>();
Car car1 = new Car();
car1.setModel("BMW");
car1.setRandomColor("Black");
cars.add(car1);
Car car2 = new Car();
car2.setModel("Audi");
car2.setRandomColor("White");
cars.add(car2);
carsModel = new CarDataModel(cars);
}
You cannot put values to your list in the constructor.
If you move that code to the getCars() method, it should work
public TableBean() {}
public List<Car> getCars() {
if(cars != null && !cars.isEmpty()) return cars;
else {
cars = new ArrayList<Car>();
Car car1 = new Car();
car1.setModel("BMW");
car1.setRandomColor("Black");
cars.add(car1);
Car car2 = new Car();
car2.setModel("Audi");
car2.setRandomColor("White");
cars.add(car2);
carsModel = new CarDataModel(cars);
}
return cars;
}