JSF display database records on datatable - jsf

I've been searching here for hour now and unfortunately I can't how to display database records to datatable, I'm newbie to JSF and I don't know much on JSF right now but I'm building a simple crud application I already know how to create, delete records using JSF but I'm having problem displaying this records to my datatable. I tried creating arraylist, I tried creating another class for this, To make it more clear here is my code:
This is my index.jsf:
<?xml version='1.0' encoding='windows-1252'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<f:view xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html">
<html xmlns="http://www.w3.org/1999/xhtml">
<h:head></h:head>
<h:body>
Username:
<h:outputText value="#{ backing_index.userName }" id="Username">
<p>
</p>
<p>
</p>
<p>
</p>
</h:outputText>
<p>
RoleI.D:
<h:outputText value="#{backing_index.roleId}" id="RoleID"/>
</p>
Role Description:
<h:outputText value="#{backing_index.roleDesc}" id="Description"/>
<h:dataTable value="#{ backing_index.tableRs }" var="user" rules="rows" cellpadding="7">
<f:facet name="header"></f:facet>
<f:facet name="footer"></f:facet>
<h:column>
<f:facet name="header">ID</f:facet>
#{ user.tableId }
</h:column>
<h:column>
<f:facet name="header">First Name</f:facet>
#{ user.tableFirstName }
</h:column>
<h:column>
<f:facet name="header">Middle Name</f:facet>
#{ user.tableMiddleName }
</h:column>
<h:column>
<f:facet name="header">Last Name</f:facet>
#{ user.tableLastName }
</h:column>
<h:column>
<f:facet name="header">Delete</f:facet>
<h:commandButton action="#{ backing_index.deleteAction }" value="Remove this">
<f:param value="Remove" name="delete" />
</h:commandButton>
</h:column>
</h:dataTable>
</h:body>
</html>
<!--oracle-jdev-comment:auto-binding-backing-bean-name:backing_index-->
</f:view>
Here is my code for the bean:
package view.backing;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.bean.*;
import javax.faces.context.*;
import javax.annotation.*;
import javax.faces.*;
import java.sql.*;
import java.util.*;
#RequestScoped
public class Index {
private Connection con;
private ResultSet rs;
private String userName;
private String roleId;
private String roleDesc;
//Variable of Data Table
private TableUser[] tableRs;
//End of Variable
//Start of getter and setter for Data table
public void setTableRs(Index.TableUser[] tableRs) {
this.tableRs = tableRs;
}
public Index.TableUser[] getTableRs() {
return tableRs;
}
//End of getter and setter
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserName() {
return userName;
}
public void setRoleId(String roleId) {
this.roleId = roleId;
}
public String getRoleId() {
return roleId;
}
public void setRoleDesc(String roleDesc) {
this.roleDesc = roleDesc;
}
public String getRoleDesc() {
return roleDesc;
}
#PostConstruct
public void init()throws SQLException, ClassNotFoundException{
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection("jdbc:oracle:thin:#localhost/XE", "JEROME", "perbert101");
displayUserInfo();
displayTableRecords();
}
private void displayUserInfo()throws SQLException{
FacesContext context = FacesContext.getCurrentInstance();
userName = (String)context.getExternalContext().getSessionMap().get("userName");
roleId = (String)context.getExternalContext().getSessionMap().get("roleId");
Statement state = con.createStatement();
state.executeQuery("SELECT * FROM ROLES WHERE ID = 2");
rs = state.getResultSet();
while(rs.next()){
roleDesc = rs.getString(3);
}
}
private void displayTableRecords()throws SQLException{
String query = "SELECT * FROM USERS";
PreparedStatement state = con.prepareStatement(query);
state.execute();
rs = state.getResultSet();
while(rs.next()){
tableRs = new TableUser[]{new TableUser(rs.getLong(1), rs.getString(2), rs.getString(7), rs.getString(5))};
}
}
//Table Records Store
public static class TableUser{
long tableId;
String tableFirstName;
String tableMiddleName;
String tableLastName;
public TableUser(long tableId, String tableFirstName, String tableMiddleName, String tableLastName){
this.tableId = tableId;
this.tableFirstName = tableFirstName;
this.tableMiddleName = tableMiddleName;
this.tableLastName = tableLastName;
}
public void setTableId(long tableId) {
this.tableId = tableId;
}
public long getTableId() {
return tableId;
}
public void setTableFirstName(String tableFirstName) {
this.tableFirstName = tableFirstName;
}
public String getTableFirstName() {
return tableFirstName;
}
public void setTableMiddleName(String tableMiddleName) {
this.tableMiddleName = tableMiddleName;
}
public String getTableMiddleName() {
return tableMiddleName;
}
public void setTableLastName(String tableLastName) {
this.tableLastName = tableLastName;
}
public String getTableLastName() {
return tableLastName;
}
}
}
I don't have any error or something and it display only the last records in the database. Guys if you know the easiest ways can you teach me how to do it, and I always go for a nice clean, short code. your help is really much appreciated :)

There is a bug in your displayTableRecords() method. Within while loop you instantiate new TableUser array for each iteration. Actually what you should do is add TableUser object one by one to existing array.
Use ArrayList inseadof array.
private List<TableUser> tableRs = new ArrayList<TableUser>();
public List<TableUser> getTableRs() {
return tableRs;
}
public void setTableRs(List<TableUser> tableRs) {
this.tableRs = tableRs;
}
private void displayTableRecords() {
String query = "SELECT * FROM USERS";
PreparedStatement state = con.prepareStatement(query);
state.execute();
rs = state.getResultSet();
while (rs.next()) {
tableRs.add(new TableUser(rs.getLong(1),
rs.getString(2), rs.getString(7), rs.getString(5)));
}
}

Related

How to make search result like Google in JSF?

So, I want to display search result as I type the keyword and change the color of the search result text in JSF like when you use Google to search.
Search example (WhatsApp)
I've done the keyup part but still wonder how to apply highlight text using javascript in JSF.
Here is my xhtml code
<h:form>
<h:outputLabel value="Keyword "/>
<h:inputText id="key" value="#{bookList.keyword}" style="height: 22px">
<f:ajax event="keyup" render="search"/>
</h:inputText>
<h:commandButton value="SEARCH" action="index" styleClass="buttonSearch"/>
</h:form>
<br/>
<h:dataTable value="#{bookList.books}" var="book" id="search"
class="book-table"
headerClass="book-table-header">
<h:column>
#{book.title}
</h:column>
<h:column>
#{book.author}
</h:column>
</h:dataTable>
and this is my java code...
Constructor
public class Book {
private String title;
private String author;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Book(String title, String author){
this.title = title;
this.author = author;
}
}
Data
#ManagedBean
#RequestScoped
public class BookList {
private String keyword = "";
public String getKeyword() {
return keyword;
}
public void setKeyword(String keyword) {
this.keyword = keyword;
}
private List<Book> books = new ArrayList<Book>(
Arrays.asList(
new Book("My First Learn to Write Workbook", "Crystal Radke"),
new Book("Where the Crawdads Sing", "Delia Owens"),
new Book("Little Fires Everywhere: A Novel", "Celeste Ng"),
new Book("Fortitude: American Resilience in the Era", "Dan Crenshaw"),
new Book("Arguing the Socialists", "Glenn Beck"),
new Book("Hidden Valley Road: Inside the Mind of an American Family", "Robert Kolker")
)
);
public List<Book> getBooks() {
if (keyword.equals("")) {
return books;
} else {
List<Book> listSearch = new ArrayList<Book>();
for(Book book:books){
if(book.getAuthor().toLowerCase().contains(keyword.toLowerCase())
|| book.getTitle().toLowerCase().contains(keyword.toLowerCase())){
listSearch.add(book);
}
}
return listSearch;
}
}
}
Sorry, if my question isn't nice.

JSF Datatable does not show all List fields(columns)

I want to display a table in JSF:DataTAble. I successfully retrived table from database to List of users type where "users" is my pojo class. Now I am having problem with displaying it on data table some of the columns like FName, LName, Pwd, displayed correctly but when i add other coulmns like "Note" "Email" it gives me this error
javax.servlet.ServletException: /dt.xhtml: Property 'Email' not found on type in.ali.pojo.users
javax.faces.webapp.FacesServlet.service(FacesServlet.java:659)
root cause
javax.el.ELException: /dt.xhtml: Property 'Email' not found on type in.ali.pojo.users
com.sun.faces.facelets.compiler.TextInstruction.write(TextInstruction.java:88)
com.sun.faces.facelets.compiler.UIInstructions.encodeBegin(UIInstructions.java:82)
com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:302)
com.sun.faces.renderkit.html_basic.TableRenderer.renderRow(TableRenderer.java:385)
com.sun.faces.renderkit.html_basic.TableRenderer.encodeChildren(TableRenderer.java:162)
javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:894)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:1856)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:443)
com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)
here is my xhtml page
<?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://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:dataTable value="#{pretechDataTableBean.user}" var="users">
<h:column>
<f:facet name="header">Name</f:facet>
#{users.FName}
</h:column>
<h:column>
<f:facet name="header">Email</f:facet>
#{users.Email}
</h:column>
<h:column>
<f:facet name="header">Password</f:facet>
#{users.pwd}
</h:column>
</h:dataTable>
</h:body>
</html>
here is my PretechDataTableBean which i used for retrieving data from DB
package com.pretech;
import in.ali.pojo.users;
import in.ali.util.HibernateUtil;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.Transaction;
import java.util.ArrayList;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
/**
*
* #author vinod
*/
#ManagedBean
#RequestScoped
public class PretechDataTableBean {
public PretechDataTableBean() {
}
public List<users> getUser() {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
List<users> users =null;
try
{
transaction = session.beginTransaction();
users = session.createQuery("from users").list();
}
catch(Exception e)
{
e.printStackTrace();
}
finally{
session.close();
}
return users;
}
}
This is my users pojo
package in.ali.pojo;
// Generated Sep 28, 2013 3:55:01 PM by Hibernate Tools 4.0.0
/**
* users generated by hbm2java
*/
public class users implements java.io.Serializable {
private long UserId;
private String FName;
private String LName;
private long UserTypeId;
private String UserName;
private String Email;
private String Pwd;
private String Note;
private boolean IsActive;
public users() {
}
public users(long UserId) {
this.UserId = UserId;
}
public users(long UserId, String FName, String LName, long UserTypeId,
String UserName, String Email, String Pwd, String Note,
boolean IsActive) {
this.UserId = UserId;
this.FName = FName;
this.LName = LName;
this.UserTypeId = UserTypeId;
this.UserName = UserName;
this.Email = Email;
this.Pwd = Pwd;
this.Note = Note;
this.IsActive = IsActive;
}
public long getUserId() {
return this.UserId;
}
public void setUserId(long UserId) {
this.UserId = UserId;
}
public String getFName() {
return this.FName;
}
public void setFName(String FName) {
this.FName = FName;
}
public String getLName() {
return this.LName;
}
public void setLName(String LName) {
this.LName = LName;
}
public long getUserTypeId() {
return this.UserTypeId;
}
public void setUserTypeId(long UserTypeId) {
this.UserTypeId = UserTypeId;
}
public String getUserName() {
return this.UserName;
}
public void setUserName(String UserName) {
this.UserName = UserName;
}
public String getEmail() {
return this.Email;
}
public void setEmail(String Email) {
this.Email = Email;
}
public String getPwd() {
return this.Pwd;
}
public void setPwd(String Pwd) {
this.Pwd = Pwd;
}
public String getNote() {
return this.Note;
}
public void setNote(String Note) {
this.Note = Note;
}
public boolean isIsActive() {
return this.IsActive;
}
public void setIsActive(boolean IsActive) {
this.IsActive = IsActive;
}
}
The fields must be likeThis instead of LikeThis. Just change your JSF code to
<h:dataTable value="#{pretechDataTableBean.user}" var="user">
<h:column>
<f:facet name="header">Name</f:facet>
#{user.fName}
</h:column>
<h:column>
<f:facet name="header">Email</f:facet>
#{user.email}
</h:column>
<h:column>
<f:facet name="header">Password</f:facet>
#{user.pwd}
</h:column>
</h:dataTable>
And update the field names in your User class to follow the proper Java Bean naming convention.
public class users implements java.io.Serializable {
private long userId;
private String fName;
private String lName;
private long userTypeId;
private String userName;
private String email;
private String pwd;
private String note;
private boolean isActive;
//constructor, getters and setters
}
Apart from this, there are other bugs in your current design:
You must not have business logic in the getters of your managed bean, instead take advantage of the #PostConstruct method to initialize the necessary data to be used.
Since this bean looks that should stay alive while the user stays in the same view, it will be better to decorate it as #ViewScoped instead of #RequestScoped.
Use proper names for your classes and fields. For example, if you have a List<Something> field, name your variable somethingList or similar in order that the code is self-explanatory.
From these, you can change your managed bean to:
#ManagedBean
#ViewScoped
public class PretechDataTableBean {
private List<users> userList;
public PretechDataTableBean() {
}
#PostConstruct
public void init() {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
List<users> users =null;
try
{
transaction = session.beginTransaction();
users = session.createQuery("from users").list();
}
catch(Exception e)
{
e.printStackTrace();
}
finally{
session.close();
}
return users;
}
public List<users> getUserList() {
return this.user;
}
}
Since the field changed its name in the managed bean, you should edit it accordingly in the respective view:
<h:dataTable value="#{pretechDataTableBean.userList}" var="user">
Related info:
Why JSF calls getters multiple times
Communication in JSF 2: Managed bean scopes
JavaBeans API Specification , more specifically, Section 7: Properties.

Unable to find matching navigation case with from-view-id '/index.xhtml' for action : JSF

I am getting the following error :
Unable to find matching navigation case with from-view-id '/index.xhtml' for action '#{medcontroller.getMedGeneric}' with outcome 'javax.faces.model.ListDataModel#7a652236'
I am new to jsf and I'm really clueless about solving this error. I have a ManagedBean with the following code:
MedController.java
#ManagedBean(name = "medcontroller")
#SessionScoped
public class MedController implements Serializable {
int startId;
String gName;
int endId;
DataModel medNames;
//DataModel medGeneric;
MedicineHelper helper;
private int recordCount = 1000;
private int pageSize = 10;
private Medicine current;
private int selectedItemIndex;
public MedController() {
helper = new MedicineHelper();
startId = 1;
endId = 10;
}
public MedController(int startId, int endId) {
helper = new MedicineHelper();
this.startId = startId;
this.endId = endId;
}
public Medicine getSelected() {
if (current == null) {
current = new Medicine();
selectedItemIndex = -1;
}
return current;
}
public DataModel getMedNames() {
if (medNames == null) {
medNames = new ListDataModel(helper.getMedNames(startId, endId));
}
return medNames;
}
public String getgName()
{
return gName;
}
public void setgName(String gName)
{
this.gName = gName;
}
public DataModel getMedGeneric() {
if (medNames == null) {
medNames= new ListDataModel(helper.getMedGeneric(gName));
}
return medNames;
}
void recreateModel() {
medNames = null;
}
public boolean isHasNextPage() {
if (endId + pageSize <= recordCount) {
return true;
}
return false;
}
public boolean isHasPreviousPage() {
if (startId-pageSize > 0) {
return true;
}
return false;
}
public String next() {
startId = endId+1;
endId = endId + pageSize;
recreateModel();
return "index";
}
public String previous() {
startId = startId - pageSize;
endId = endId - pageSize;
recreateModel();
return "index";
}
public int getPageSize() {
return pageSize;
}
public String prepareView(){
current = (Medicine) getMedNames().getRowData();
return "browse";
}
public String prepareList(){
recreateModel();
return "index";
}
}
And here is my JSF file
index.xhtml
<ui:define name="body">
<h:form styleClass="jsfcrud_list_form">
<h:commandLink action="#{medcontroller.previous}" value="Previous #{medcontroller.pageSize}" rendered="#{medcontroller.hasPreviousPage}"/>
<h:commandLink action="#{medcontroller.next}" value="Next #{medcontroller.pageSize}" rendered="#{medcontroller.hasNextPage}"/>
<h:dataTable value="#{medcontroller.medNames}" var="item" border="1" cellpadding="15" cellspacing="10" rowClasses="jsfcrud_odd_row,jsfcrud_even_row" rules="all" style="border:solid 1px">
<h:column>
<f:facet name="header">
<h:outputText value="BrandName"/>
</f:facet>
<h:outputText value="#{item.brandName}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Generic"/>
</f:facet>
<h:outputText value="#{item.generic}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value=" "/>
</f:facet>
<h:commandLink action="#{medcontroller.prepareView}" value="View"/>
</h:column>
</h:dataTable>
<h:inputText value="#{medcontroller.gName}" />
<h:commandButton value="Submit" action="#{medcontroller.getMedGeneric}" />
</h:form>
</ui:define>
Please help me solve the error.
Also, I do not have a faces-config.xml file. I am using netbeans ide 7.1.2 web application with jsf and hibernate framework.
Thank you in advance.
The <h:commandButton action> must point to a method which invokes some business logic and returns either void or a String representing the target page you'd like to (re)display. However you returned a whole ListDataModel which isn't making any sense to JSF navigation handler and hence this error.
Something like this should do:
public String getMedGeneric(){
// Do your business logic here.
return "someViewId";
}
This will navigate to someViewId.xhtml. However, if you intend to stick on the same view, just let it return void (or null) and it will redisplay the same view.
public void getMedGeneric(){
// Do your business logic here.
}
By the way, it's really a poor naming convention to prefix action method names with get. This is confusing and makes your code not self-documenting. Rather name it loadMedGeneric() or so. I'm merely guessing as you didn't tell anywhere about the concrete functional requirement, what exactly that button should be doing.
getMedGeneric should return java.lang.String which represent navigation to another page described in faces-config.xml. In your case it return some model so it will not work unfortunatell. Let try to put getMedGeneric() action to actionListener and then in action put navigation String. i.e:
action="navString" actionListener="#{medcontroller.getMedGeneric}"
you should try just
actionListener="#{medcontroller.getMedGeneric}"

DataModel must implement org.primefaces.model.SelectableDataModel when selection is enabled.

I'm trying to create a DataTable with Multiple Row Selection but i'm getting an error here's the link of the tutorial http://www.primefaces.org/showcase/ui/datatableRowSelectionMultiple.jsf :
Here's my 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>
<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;
}
}
i'm getting this error:
javax.faces.FacesException: DataModel must implement
org.primefaces.model.SelectableDataModel when selection is enabled.....
just add this attribute rowKey to the datatable tag :
<p:dataTable border="1" value="#{projectAdminisrationMB.projectNoUsersList}"
var="userObj"
rowKey="#{userObj.name}"selection="#{projectAdminisrationMB.selectedUsers}"
selectionMode="multiple" rowIndexVar="rowIndex"
binding="#{table2}">
You can get this error if you try to add a new item to the underlying list and forget to assign a value to that new item's rowKey.
Alternatively to rowKey you can wrap your data in a custom model which really implements org.primefaces.model.SelectableDataModel. This is helpful if
all of your your classes have the same kind of #Id (e.g. a long) and can implement the same interface (e.g. EjbWithId)
you want to add additional functionalities to your data which are not domain specific and don't belong e.g. User.
The interface may be something like this:
public interface EjbWithId
{
public long getId();
public void setId(long id);
}
Then a generic implementation of SelectableDataModel for all your classes can be used:
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();}
}
In your #ManagedBean:
private PrimefacesEjbIdDataModel<User> dmUser; //+getter
dmUser = new PrimefacesEjbIdDataModel<User>(administrationProjectFinal.getUserList());
first check whether you've added
rowKey="#{userObj.id}"
then you need to have the data table List set in filteredValue attribute of your data table in xhtml, instead of value.

JSF UIRepeat and PostBack

I have a simple page where a I use <ui:repeat> and it gets the value from a backing bean.
The initial request will give it an empty list. The postback then will invoke an action that will change the model behind the <ui:repeat> but it is not rendered?!
I debugged through it and I saw that the <ui:repeat> evaluates the value at restore view phase but thats it. When it reaches render response it does not use the latest value from my bean. Is that the expected behavior?
How can I make that work? Do I have to write my own repeat tag?
I can't really tell what could be the problem without some of your code, but these are the basics:
Backing bean:
public class ObjectService{
private DataModel objectDataModel;
private List<Object> objectList;
private Pagination paginationHelper;
private ObjectDao objectDao = new ObjectDao();
private String queryOption;
public void setQueryOption(String queryOption){
this.queryOption = queryOption;
}
public String getQueryOption(){
return this.queryOption;
}
public <E> PaginationHelper getPagination(final List<E> list) {
pagination = new PaginationHelper(10) {
#Override
public int getItemsCount() {
return list.size();
}
#Override
public DataModel createPageDataModel() {
return new ListDataModel(list);
}
};
return pagination;
}
public void setPagination(PaginationHelper pagination) {
this.pagination = pagination;
}
public List<Object> getObjectList(){
this.objectList = objectDao.readObjectsWhere(queryOption);
return this.objectList;
}
public void setObjectList(List<Object> objectList){
this.objectList = objectList;
}
public DataModel getObjectDataModel(){
if (objectDataModel == null) {
objectDataModel = getPagination(getObjectList()).createPageDataModel();
}
return objectDataModel;
}
public void setObjectDataModel(DataModel objectDataModel){
this.objectDataModel = objectDataModel
}
public String changeModel(){
objectDataModel = null;
return null;
}
}
XHTML page:
...
<h:form>
<fieldset>
<label>
<span>Option:</span>
<h:inputText value="#{objectService.queryOption}" />
</label>
<h:commandButton action="#{objectService.changeModel}" value="request data" />
</fieldset>
<ui:repeat value="#{objectService.objectDataModel}" var="objectVar">
<h:outputLabel value="#{objectVar.property1}" />
<h:outputLabel value="#{objectVar.property2}" />
<h:outputLabel value="#{objectVar.property3}" />
</ui:repeat>
</h:form>
...

Resources