I have 2 classes Games and Fouls, there are lot of fouls in a game. The user sends a parameter with the game id to find the game he want and after that the currentGame variable is created.Its type is Game. I have a datatable which prints the fouls in the current game
The setCurentGame setter is called form the body of the page onload.
so far everything works okay, but when I add a new foul, is not added to the datatable, my assumption is that the game was already retrieved (because current game was created before) so the new foul is in the database and not in the Game currentGame.
Is there any way that i can update the currentGame every time a foul i added?
I have tried refreshing the page and even to call the seeter again after creating the foul but nothing worked
The datatable looks like this:
<p:dataTable id="datalist" value="#{gameController.currentGame.foulCollection}" var="item">
<f:facet name="{exporters}">
</f:facet>
<p:ajax event="rowSelect" update="createButton viewButton editButton deleteButton"/>
<p:ajax event="rowUnselect" update="createButton viewButton editButton deleteButton"/>
<p:column width="32" sortBy="#{item.id}" filterBy="#{item.id}">
<f:facet name="header">
<h:outputText value="#{bundle.ListFoulTitle_id}"/>
</f:facet>
<h:outputText value="#{item.id}"/>
</p:column>
<p:column sortBy="#{item.quarter}" filterBy="#{item.quarter}">
<f:facet name="header">
<h:outputText value="#{bundle.ListFoulTitle_quarter}"/>
</f:facet>
<h:outputText value="#{item.quarter}"/>
</p:column>
<p:column sortBy="#{item.foultime}" filterBy="#{item.foultime}">
<f:facet name="header">
<h:outputText value="#{bundle.ListFoulTitle_foultime}"/>
</f:facet>
<h:outputText value="#{item.foultime}"/>
</p:column>
<f:facet name="footer">
<p:commandButton id="createButton" icon="ui-icon-plus" value="#{bundle.Create}" actionListener="#{foulController.prepareCreate}" update=":FoulCreateForm" oncomplete="PF('FoulCreateDialog').show()"/>
</f:facet>
</p:dataTable>
GameController bean:
package onisiforos.fouls.classes;
import onisiforos.fouls.db.Game;
import onisiforos.fouls.classes.util.JsfUtil;
import onisiforos.fouls.classes.util.JsfUtil.PersistAction;
import onisiforos.fouls.bean.GameFacade;
import java.io.Serializable;
import java.util.List;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import javax.faces.bean.ManagedProperty;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
#Named("gameController")
#SessionScoped
public class GameController implements Serializable {
#EJB
private onisiforos.fouls.bean.GameFacade ejbFacade;
private List<Game> items = null;
private Game selected;
private Game currentGame;
public Game getCurrentGame() {
return currentGame;
}
public void setCurrentGame() {
int gid =
Integer.parseInt(FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("gameid"));
Game cg = getGame(gid);
this.currentGame = cg;
}
public GameController() {
}
public Game getSelected() {
return selected;
}
public void setSelected(Game selected) {
this.selected = selected;
}
protected void setEmbeddableKeys() {
}
protected void initializeEmbeddableKey() {
}
private GameFacade getFacade() {
return ejbFacade;
}
public Game prepareCreate() {
selected = new Game();
initializeEmbeddableKey();
return selected;
}
public void create() {
setCurrentGame()
persist(PersistAction.CREATE, ResourceBundle.getBundle("/Bundle").getString("GameCreated"));
updateCurrentGame();
if (!JsfUtil.isValidationFailed()) {
items = null;
}
}
public void update() {
persist(PersistAction.UPDATE, ResourceBundle.getBundle("/Bundle").getString("GameUpdated"));
}
public void destroy() {
persist(PersistAction.DELETE, ResourceBundle.getBundle("/Bundle").getString("GameDeleted"));
if (!JsfUtil.isValidationFailed()) {
selected = null; // Remove selection
items = null;
}
}
public List<Game> getGames() {
if (items == null) {
items = getFacade().findAll();
}
return items;
}
private void persist(PersistAction persistAction, String successMessage) {
if (selected != null) {
setEmbeddableKeys();
try {
if (persistAction != PersistAction.DELETE) {
getFacade().edit(selected);
} else {
getFacade().remove(selected);
}
JsfUtil.addSuccessMessage(successMessage);
} catch (EJBException ex) {
String msg = "";
Throwable cause = ex.getCause();
if (cause != null) {
msg = cause.getLocalizedMessage();
}
if (msg.length() > 0) {
JsfUtil.addErrorMessage(msg);
} else {
JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
}
} catch (Exception ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
}
}
}
public Game getGame(java.lang.Integer id) {
return getFacade().find(id);
}
public List<Game> getItemsAvailableSelectMany() {
return getFacade().findAll();
}
public List<Game> getItemsAvailableSelectOne() {
return getFacade().findAll();
}
#FacesConverter(forClass = Game.class)
public static class GameControllerConverter implements Converter {
#Override
public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
if (value == null || value.length() == 0) {
return null;
}
GameController controller = (GameController) facesContext.getApplication().getELResolver().
getValue(facesContext.getELContext(), null, "gameController");
return controller.getGame(getKey(value));
}
java.lang.Integer getKey(String value) {
java.lang.Integer key;
key = Integer.valueOf(value);
return key;
}
String getStringKey(java.lang.Integer value) {
StringBuilder sb = new StringBuilder();
sb.append(value);
return sb.toString();
}
#Override
public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
if (object == null) {
return null;
}
if (object instanceof Game) {
Game o = (Game) object;
return getStringKey(o.getId());
} else {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "object {0} is of type {1}; expected type: {2}", new Object[]{object, object.getClass().getName(), Game.class.getName()});
return null;
}
}
}
}
It seems your setCurrentGame method will not be called, you can manually call it in your create() method to update the current game object from the database after the foul is created.
Related
I'm using Primefaces and spinner component. My problem is that the spinner value is not set in the bean, if it's inside an iteration structure. My spinner is inside ui:repeat.
In the end, the problem is how to deal with different form controls mapping to the same property in bean.
<h:form>
<ui:repeat var="item" value="#{myBean.items}">
<p:spinner size="2" min="1" max="50" style="width:75px" value="#{cartBean.quantityToOrder}"/>
<p:commandButton value="Add to cart" action="#{cartBean.saveItemToCart(item)}" ajax="false"/>
</ui:repeat>
</h:form>
and my bean
#ManagedBean
#SessionScoped
public class CartBean extends BaseBean {
private int quantityToOrder;
//setter, getter...
//When called quantityToOrder = 0 always
public void saveItemToOrder(Item item) {
quantityToOrder IS 0.
}
}
I suspect it has to do with form submission, I have tried a form enclosing all elements in the collection and also a form enclosing any of the spinners + button. The generated client IDs are distinct for all spinners.
Any help would be appreciated.
Put a System.out.println("quantity: " + quantityToOrder) on your setQuantityToOrder(int quantityToOrder) method and will will see the problem. The value of the last spinner will prevail over the others because all the spinners are pointed to the same property (cartBean.quantityToOrder).
Try moving the quantityToOrder to the Item as follows:
<h:form id="mainForm">
<ui:repeat value="#{cartBean.items}" var="item">
<p:outputLabel value="#{item.name}: " for="sp" />
<p:spinner id="sp" size="2" min="1" max="50" style="width:75px" value="#{item.quantityToOrder}" />
<p:commandButton value="Add to cart" action="#{cartBean.saveItemToOrder(item)}" process="#this, sp" update=":mainForm:total" />
<br />
</ui:repeat>
Total: <h:outputText id="total" value="#{cartBean.quantityToOrder}" />
</h:form>
The cartBean:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class CartBean implements Serializable {
private List<CartItem> items;
private int quantityToOrder;
#PostConstruct
public void setup() {
items = new ArrayList<CartItem>();
items.add(new CartItem(1, "A"));
items.add(new CartItem(2, "B"));
items.add(new CartItem(3, "C"));
}
public void saveItemToOrder(CartItem item) {
//do whatever you want to do with the item quantity.
System.out.println("Qtd of " + item.getName() + ": " + item.getQuantityToOrder());
//to calculte the qtd of items on the cart.
quantityToOrder = 0;
for (CartItem cartItem : items) {
quantityToOrder += cartItem.getQuantityToOrder();
}
}
public List<CartItem> getItems() {
return items;
}
public void setItems(List<CartItem> items) {
this.items = items;
}
public int getQuantityToOrder() {
return quantityToOrder;
}
public void setQuantityToOrder(int quantityToOrder) {
this.quantityToOrder = quantityToOrder;
}
}
The CartItem:
import java.io.Serializable;
public class CartItem implements Serializable {
private Integer id;
private Integer quantityToOrder;
private String name;
public CartItem(Integer id, String name) {
this.id = id;
this.name = name;
quantityToOrder = 0;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getQuantityToOrder() {
return quantityToOrder;
}
public void setQuantityToOrder(Integer quantityToOrder) {
this.quantityToOrder = quantityToOrder;
}
#Override
public int hashCode() {
int hash = 7;
hash = 67 * hash + (this.id != null ? this.id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final CartItem other = (CartItem) obj;
if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) {
return false;
}
return true;
}
}
Hi guys i have a datatable from the primefaces library, which i am trying to include the feature of editing each cell and when the user presses a "save" button at the row it will update the edited values to a database, however currently when a user edits a cell what ever they change the cell to the second they click off the cell the value goes the same as what it was before, it does not save the new values, and also another issues is when the user presses save at the end of the row the values passwed to the database is always Null, how can i solve these two issues ?
here is the xhtml
<p:dataTable id="dataTable" var="u" value="#{userBean.getUserList()}"
paginator="true" rows="10"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15,25"
editable="true" editMode="cell"
>
<p:column>
<!--
<p:ajax event="rowEdit" listener="{u.onEdit}" update=":form:messages" />
<p:ajax event="rowEditCancel" listener="{u.onCancel}" update=":form:messages" />
-->
<f:facet name="header">
User ID
</f:facet>
#{u.userID}
</p:column>
<p:column headerText="Name" >
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{u.name}" />
</f:facet>
<f:facet name="input">
<p:inputText id="NameInput" value="#{u.name}"
style="width:96%" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Email">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{u.email}" />
</f:facet>
<f:facet name="input">
<p:inputText id="EmailInput" value="#{u.email}"
/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Address">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{u.address}" />
</f:facet>
<f:facet name="input">
<p:inputText id="AddressInput" value="#{u.address}"
/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column>
<f:facet name="header">
Created Date
</f:facet>
#{u.created_date}
</p:column>
<p:column>
<f:facet name="header">
Delete
</f:facet>
<h:commandButton value="Delete" action="#{user.delete(u.userID)}" />
</p:column>
<p:column>
<f:facet name="header">
Save Edit
</f:facet>
<h:commandButton value="Save" action="#{user.editData(u.userID)}" />
</p:column>
</p:dataTable>
and here is the backing bean although currently this is only updating the database with the values from the databale
public void editData(long userID) {
System.out.println(name);
PreparedStatement ps = null;
Connection con = null;
if (userID != 0) {
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
System.out.println(name);
String sql = "UPDATE user1 set name = '" + name + "', email = '" + email + "', address = '" + address + "' WHERE userId=" + userID;
ps = con.prepareStatement(sql);
int i = ps.executeUpdate();
if (i > 0) {
System.out.println("Row updated successfully");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
con.close();
ps.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
the datable originally gets its values from the database
Thanks
Here is how i populate the datatable with values from the database,/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package richard.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import richard.test.User;
#ManagedBean(name = "userBean")
#SessionScoped
public class UserBean {
List<User> list;
PreparedStatement ps = null;
Connection con = null;
ResultSet rs = null;
public List<User> getList() {
return list;
}
public List<User> getUserList() {
list = new ArrayList<User>();
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
String sql = "select * from user1";
ps = con.prepareStatement(sql);
rs = ps.executeQuery();
while (rs.next()) {
User usr = new User();
usr.setUserID(rs.getLong("userId"));
usr.setName(rs.getString("name"));
usr.setEmail(rs.getString("email"));
usr.setAddress(rs.getString("address"));
usr.setCreated_date(rs.getDate("created_date"));
list.add(usr);
Map<Long, Boolean> checked = new HashMap<Long, Boolean>();
List<User> checkedItems = new ArrayList<User>();
for (User item : list) {
if (checked.get(item.getUserID()) != null) {
checkedItems.add(item);
usr.delete(usr.getUserID());
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
con.close();
ps.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return list;
}
}
HERE is the full user bean code
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package richard.test;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.component.UIColumn;
import javax.faces.event.ActionEvent;
import org.primefaces.component.datatable.DataTable;
import org.primefaces.event.CellEditEvent;
import org.primefaces.event.RowEditEvent;
#ManagedBean
#RequestScoped
public class User {
List<User> list;
PreparedStatement ps = null;
Connection con = null;
ResultSet rs = null;
private long userID = 1;
private String name;
private String address;
private Date created_date;
private String email;
boolean editable;
public boolean isEditable() {
return editable;
}
public void setEditable(boolean editable) {
this.editable = editable;
}
public String editAction(User order) {
order.setEditable(true);
return null;
}
public long getUserID() {
return userID;
}
public void setUserID(long userID) {
this.userID = userID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Date getCreated_date() {
return created_date;
}
public void setCreated_date(Date created_date) {
this.created_date = created_date;
}
public String add() {
System.out.println("In add");
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
int i = 0;
if (userID != 0) {
PreparedStatement ps = null;
Connection con = null;
try {
System.out.println("about to add to db");
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
String sql = "INSERT INTO user1( name, email, address, created_date) VALUES(?,?,?,?)";
ps = con.prepareStatement(sql);
ps.setString(1, name);
ps.setString(2, email);
ps.setString(3, address);
if (created_date != null) {
String date = fmt.format(created_date);
Object obj = date;
if (obj == null) {
ps.setDate(4, null);
} else {
java.sql.Date dt = java.sql.Date.valueOf(new String(date));
ps.setDate(4, dt);
}
}
i = ps.executeUpdate();
System.out.println("Data Added Successfully");
} catch (Exception e) {
System.out.println(e);
} finally {
try {
con.close();
ps.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (i > 0) {
return "output";
} else {
return "invalid";
}
} else {
return "invalid";
}
}
public void delete(long userID) {
PreparedStatement ps = null;
Connection con = null;
if (userID != 0) {
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
String sql = "DELETE FROM user1 WHERE userId=" + userID;
ps = con.prepareStatement(sql);
int i = ps.executeUpdate();
if (i > 0) {
System.out.println("Row deleted successfully");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
con.close();
ps.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public void editData(long userID) {
PreparedStatement ps = null;
Connection con = null;
if (userID != 0) {
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
System.out.println(name);
String sql = "UPDATE user1 set name = '" + name + "', email = '" + email + "', address = '" + address + "' WHERE userId=" + userID;
ps = con.prepareStatement(sql);
int i = ps.executeUpdate();
if (i > 0) {
System.out.println("Row updated successfully");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
con.close();
ps.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
The main problem is that you have two User objects:
User u - currently selected user.
User user - just a ManagedBean, most probably with no state (no id, no name, no address).
When performing the edit operation you try to use u.id and user.name, user.address, etc.
What you need to do, is to take all the values from the u object.
There are many different approaches (I've never used the third one, but it should work and it's the closest to what you've already have):
A1. You can keep currently selected object in your UserBean and set it with setPropertyActionListener:
<f:setPropertyActionListener target="#{userBean.selectedUser}" value="#{u}" />
Then you can call the edit method implemented in the same bean (it has full access to selectedUser object and it can implement the edit itself of just delegate the action to object with edit method implementation).
A2. You can place your edit method in the UserBean and pass entire User object as a parameter:
<h:commandButton value="Save" action="#{userBean.editData(u)}" />
A3. Or you can just call:
<h:commandButton value="Save" action="#{u.editData()}" />
instead of:
<h:commandButton value="Save" action="#{user.editData(u.userID)}" />
How to implement a simple add/remove dynamic <rich:tabPanel>?
(I've seen people asking this around so I thought postin a Q&A of a simple implementation)
The implementation has 3 custom classes:
Content: contains the values to be displayed in a tab;
ItemTab: contais an UITab object and a Content object;
MyTabs: EJB managed bean that provides access to the tabs and adding/removal methods.
The code is:
Content:
public class Content {
String name;
String job;
String dept;
public Content() {
name = "John Doe";
job = "None";
dept = "None";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public String getDept() {
return dept;
}
public void setDept(String dept) {
this.dept = dept;
}
}
TabItem:
public class TabItem {
UITab component;
Content content;
public TabItem() {
component = new UITab();
content = new Content();
}
public UITab getComponent() {
return component;
}
public void setComponent(UITab tab) {
this.component = tab;
}
public Content getContent() {
return content;
}
public void setContent(Content content) {
this.content = content;
}
}
MyTabs:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
#Named
#SessionScoped
public class MyTabs implements Serializable {
private List<TabItem> tabs;
public MyTabs() {
tabs = new ArrayList<TabItem>();
}
#PostConstruct
private void init() {
createTab();
createTab();
createTab();
}
public void createTab() {
TabItem tab = new TabItem();
tab.getComponent().setId("Tab" + (tabs.size()+1));
tab.getComponent().setHeader("Tab " + (tabs.size()+1));
tab.getContent().setName("John Doe " + (tabs.size()+1));
tab.getContent().setJob("Salesman " + (tabs.size()+1));
tab.getContent().setDept("Sales " + (tabs.size()+1));
tabs.add(tab);
}
public void removeTab(TabItem tab) {
tabs.remove(tab);
}
public List<TabItem> getTabs() {
return tabs;
}
public void setTabs(List<TabItem> tabs) {
this.tabs = tabs;
}
}
tabview.xhtml:
<h:commandLink value="Add Tab"
actionListener="#{myTabs.createTab()}"/>
<rich:tabPanel switchType="client">
<c:forEach items="#{myTabs.tabs}" var="tab">
<rich:tab value="#{tab.component}">
<f:facet name="header">
<h:outputLabel value="#{tab.component.header}"/>
<h:commandLink value=" X" actionListener="#{myTabs.removeTab(tab)}"/>
</f:facet>
<h:panelGrid columns="2">
<h:outputLabel value="Name: "/>
<h:outputLabel value="#{tab.content.name}"/>
<h:outputLabel value="Dept: "/>
<h:outputLabel value="#{tab.content.dept}"/>
<h:outputLabel value="Job: "/>
<h:outputLabel value="#{tab.content.job}"/>
</h:panelGrid>
</rich:tab>
</c:forEach>
</rich:tabPanel>
I have this problem.
I wanted to create selectOneMenu for custom select some data. But it's not working and i really don't know why. I spent cca 5 hours with this problem. I'm so desperate.
So some my code:
But when i will pick some item from selectonemenu, selected_id is still 0. Still, still. I tried to do almost everything but without result.
I tried this:
<p:selectOneMenu value="#{medicinesBean.selectedBranch}" required="true" effect="fade" id="listComboBox">
<f:selectItems value="#{medicinesBean.branchesForComboBox}" var="itm" itemLabel="#{itm.name}" itemValue="#{itm.id}" />
</p:selectOneMenu>
Backing Bean class:
/* private members */
private ArrayList<BranchDTO> branchesForComboBox = new ArrayList<BranchDTO>();
private BranchDTO selectedBranch;
/* getter and setters ... */
also i tried this with SelectItem[] model but result was same. NOT WORK.
Then i tried it like:
<p:selectOneMenu value="#{medicinesBean.selected_id}" required="true" effect="fade" id="listComboBox">
<f:selectItem itemLabel="First" itemValue="1"/>
<f:selectItem itemLabel="Second" itemValue="2"/>
<f:selectItem itemLabel="Third" itemValue="3"/>
<f:selectItem itemLabel="Fouth" itemValue="4"/>
</p:selectOneMenu>
/* private members */
private int selected_id;
But still 0. When i used object like value for selectonemenu, always null exception was always returned. So i will be glad for any advice for this.
Thanks
brw. backing bean is ViewScoped and data from DAO are correctly returned so some bug will be in component selectonemenu.
Thanks BalusC, so here is my implementation
Backing Bean
/**
* #author Sajmon
*/
package OraclBeans;
import DTOs.PobockaDTO;
import DTOs.ZoznamLiekovDTO;
import EJBs.ZoznamLiekovEJB;
import java.io.Serializable;
import java.util.ArrayList;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean(name="zoznamLiekovBean")
#ViewScoped
public class ZoznamLiekovBean implements Serializable {
#EJB
private ZoznamLiekovEJB listOfMedicineEJB;
/* private members */
private ArrayList<ZoznamLiekovDTO> listOfMedicines;
private ArrayList<PobockaDTO> branchesForCombobox = new ArrayList<PobockaDTO>();
private ZoznamLiekovDTO selectedItem;
private PobockaDTO selectedBranch;
//private SelectItem[] branchesOptions;
//private SelectItem selectedOption;
private int selected_id;
public ZoznamLiekovBean() {
}
#PostConstruct
private void init() {
branchesForCombobox = listOfMedicineEJB.getBranches();
listOfMedicines = listOfMedicineEJB.getLists();
}
public void test() {
System.out.println("ID: " + selected_id);
}
/*
private SelectItem[] addItemsToOptions() {
SelectItem[] data = new SelectItem[branchesForCombobox.size()];
for (int i = 0; i < branchesForCombobox.size(); i++) {
data[i] = new SelectItem(branchesForCombobox.get(i).getId(), branchesForCombobox.get(i).getNazov());
}
return data;
}
*/
/* getters and setters */
/*
public SelectItem[] getBranchesOptions() {
return branchesOptions;
}
public void setBranchesOptions(SelectItem[] branchesOptions) {
this.branchesOptions = branchesOptions;
}
public void setSelectedOption(SelectItem selectedOption) {
this.selectedOption = selectedOption;
}
public SelectItem getSelectedOption() {
return selectedOption;
}
*/
public ArrayList<PobockaDTO> getBranchesForCombobox() {
return branchesForCombobox;
}
public void setBranchesForCombobox(ArrayList<PobockaDTO> branchesForCombobox) {
this.branchesForCombobox = branchesForCombobox;
}
public ArrayList<ZoznamLiekovDTO> getListOfMedicines() {
return listOfMedicines;
}
public void setListOfMedicines(ArrayList<ZoznamLiekovDTO> listOfMedicines) {
this.listOfMedicines = listOfMedicines;
}
public PobockaDTO getSelectedBranch() {
return selectedBranch;
}
public void setSelectedBranch(PobockaDTO selectedBranch) {
this.selectedBranch = selectedBranch;
}
public ZoznamLiekovDTO getSelectedItem() {
return selectedItem;
}
public void setSelectedItem(ZoznamLiekovDTO selectedItem) {
this.selectedItem = selectedItem;
}
public int getSelected_id() {
return selected_id;
}
public void setSelected_id(int selected_id) {
this.selected_id = selected_id;
}
}
EJB:
/**
* #author Sajmon
*/
package EJBs;
import DTOs.PobockaDTO;
import DTOs.ZoznamLiekovDTO;
import OraclDAO.OracleZoznamLiekovDAO;
import java.io.Serializable;
import java.util.ArrayList;
import javax.ejb.Stateless;
#Stateless
public class ZoznamLiekovEJB implements Serializable {
private OracleZoznamLiekovDAO dao = new OracleZoznamLiekovDAO();
public ArrayList<ZoznamLiekovDTO> getLists() {
return dao.getListOfMedicines();
}
public ArrayList<PobockaDTO> getBranches() {
return dao.getBranchesForCombobox();
}
}
DAO:
/**
* #author Sajmon
*/
package OraclDAO;
import DTOs.PobockaDTO;
import DTOs.ZoznamLiekovDTO;
import OraclDAOFactory.OracleDAOFactory;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
public class OracleZoznamLiekovDAO implements Serializable {
private String SELECT_ALL = "SELECT Z.id_zoznamu, P.nazov_pobocky, L.nazov_lieku FROM Zoznam_liekov Z "
+ "JOIN Pobocka P ON (Z.id_pobocky = P.id_pobocky)"
+ "JOIN Liek L ON (Z.id_lieku = L.id_lieku)";
private String SELECT_BRANCHES = "SELECT DISTINCT P.id_pobocky, P.nazov_pobocky FROM Zoznam_liekov Z JOIN Pobocka P ON (Z.id_pobocky = P.id_pobocky)";
public OracleZoznamLiekovDAO() {
}
public ArrayList<PobockaDTO> getBranchesForCombobox() {
ArrayList<PobockaDTO> data = new ArrayList<PobockaDTO>();
PobockaDTO item;
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = OracleDAOFactory.getOracleDatabaseConnection();
ps = con.prepareStatement(SELECT_BRANCHES);
rs = ps.executeQuery();
while (rs.next()) {
item = new PobockaDTO();
item.setId(rs.getInt(1));
item.setNazov(rs.getString(2));
data.add(item);
}
System.out.println("Data imported to list successfully.");
}
catch (SQLException ex) {
Logger.getLogger(OracleZoznamLiekovDAO.class.getName()).log(Level.SEVERE, null, ex);
}
finally {
if (con != null) {
try {
con.close();
}
catch (SQLException ex) {
Logger.getLogger(OracleZoznamLiekovDAO.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
return data;
}
public ArrayList<ZoznamLiekovDTO> getListOfMedicines() {
ArrayList<ZoznamLiekovDTO> data = new ArrayList<ZoznamLiekovDTO>();
ZoznamLiekovDTO item;
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = OracleDAOFactory.getOracleDatabaseConnection();
ps = con.prepareStatement(SELECT_ALL);
rs = ps.executeQuery();
while (rs.next()) {
item = new ZoznamLiekovDTO();
item.setId(rs.getInt(1));
item.getPobocka().setNazov(rs.getString(2));
item.getLiek().setNazov(rs.getString(3));
data.add(item);
}
System.out.println("List of Medicines imported successfully.");
}
catch (SQLException ex) {
Logger.getLogger(OracleZoznamLiekovDAO.class.getName()).log(Level.SEVERE, null, ex);
}
finally {
if (con != null) {
try {
con.close();
}
catch (SQLException ex) {
Logger.getLogger(OracleZoznamLiekovDAO.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
return data;
}
}
And XHTML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Zoznam liekov - prehľad</title>
<link rel="stylesheet" type="text/css" href="../style.css" />
</h:head>
<h:body>
<div id="out">
<h:form id="mainForm">
<p:selectOneMenu value="#{zoznamLiekovBean.selected_id}" required="true" effect="fade" id="zoznamComboBox">
<f:selectItems value="#{zoznamLiekovBean.branchesForCombobox}" var="itm" itemLabel="#{itm.nazov}" itemValue="#{itm.id}"/>
</p:selectOneMenu>
<p:commandButton immediate="true" styleClass="submitClass" value="Generuj zoznam" update="dialogText" actionListener="#{zoznamLiekovBean.test()}"/>
<p:dataTable style="width: 1100px" widgetVar="zoznamLiekovTable" selection="#{zoznamLiekovBean.selectedItem}" selectionMode="single" rowKey="#{item.id}" var="item" value="#{zoznamLiekovBean.listOfMedicines}" rows="5" rowsPerPageTemplate="5,10,15,20"
paginator="true" paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink}">
<p:column>
<f:facet name="header">ID:</f:facet>
<h:outputText value="#{item.id}"/>
</p:column>
<p:column>
<f:facet name="header">Pobočka:</f:facet>
<h:outputText value="#{item.pobocka.nazov}"/>
</p:column>
<p:column>
<f:facet name="header">Liek:</f:facet>
<h:outputText value="#{item.liek.nazov}"/>
</p:column>
</p:dataTable>
<p:dialog widgetVar="test" showEffect="explode" hideEffect="explode">
<h:outputText id="dialogText" value="#{zoznamLiekovBean.selected_id}"/>
</p:dialog>
</h:form>
</div>
</h:body>
</html>
Remove immediate="true" from the commandButton. You are skipping the whole Apply Request Value phase - Update Model value phase with that. That's why your value is always null or 0.
Check this out
I am working with Eclipse and Glassfish 3.0. Pretty new to this technology although I have done similar things before. Very simple really got a datatable bound to a backing bean. Add methods and remove methods i have covered - the problem lies with the update method I am calling. I cannot seem to see the changes being picked up in the component (HtmlInputText) never mind passing the data back to the table.
My code for the data table is below (and the jsf page)
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<f:loadBundle basename="resources.application" var="msg"/>
<head>
<title><h:outputText value="#{msg.welcomeTitle}" /></title>
</head>
<body>
<h:form id="mainform">
<h:dataTable var="row" border="0" value="#{beanCategory.collection}" binding="#{beanCategory.datatable}">
<f:facet name="header">
<h:outputText value="Categories"/>
</f:facet>
<h:column>
<f:facet name="header">
<h:outputText value="Description"/>
</f:facet>
<h:inputText id="input1" value="#{row.description}" valueChangeListener="#{row.inputChanged}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Id"/>
</f:facet>
<h:outputText id="id" value="#{row.id}"/>
</h:column>
<h:column>
<h:commandButton value="Delete" type="submit" action="#{beanCategory.remove}">
<f:setPropertyActionListener target="#{beanCategory.selectedcategory}" value="#{row}"/>
</h:commandButton>
<h:commandButton value="Save" action="#{beanCategory.update}"
>
<f:setPropertyActionListener
target="#{beanCategory.selectedcategory}" value="#{row}" />
</h:commandButton>
</h:column>
</h:dataTable>
<h:inputText id="text1"></h:inputText> <h:commandButton action="#{beanCategory.addCategory}" value="Add" type="submit" id="submitbutton">
</h:commandButton>
<br/><br/>
Messages
<h:messages></h:messages><br /><br />
</h:form>
</body>
</html>
Backing Bean is here
package net.bssuk.timesheets.controller;
import java.io.Serializable;
import java.util.List;
import javax.faces.component.UIInput;
import javax.faces.component.html.HtmlDataTable;
import javax.faces.context.FacesContext;
import javax.persistence.*;
import net.bssuk.timesheets.model.Category;
#javax.inject.Named("beanCategory")
#javax.enterprise.context.SessionScoped
public class BeanCategory implements Serializable {
private List<Category> collection;
private EntityManagerFactory emf;
private EntityManager em;
private int selectedid;
private Category selectedcategory;
private HtmlDataTable datatable;
private static final long serialVersionUID = 1L;
public BeanCategory() {
// TODO Auto-generated constructor stub
System.out.println("Bean Constructor");
}
public String addCategory() {
try {
this.emf = Persistence.createEntityManagerFactory("timesheets1");
System.out.println("Changed - Now attempting to add");
System.out.println("Ready to do cateogory");
Category category = new Category();
FacesContext context = FacesContext.getCurrentInstance();
UIInput input = (UIInput) context.getViewRoot().findComponent(
"mainform:text1");
String value = input.getValue().toString();
if (value != null) {
category.setDescription(input.getValue().toString());
} else {
category.setDescription("Was null");
}
this.em = this.emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
em.persist(category);
tx.commit();
em.close();
emf.close();
// return "index.xhtml";
} catch (Exception e) {
e.printStackTrace();
}
return "return.html";
}
public String remove() {
try {
this.emf = Persistence.createEntityManagerFactory("timesheets1");
System.out.println("Getting Collection");
this.em = this.emf.createEntityManager();
FacesContext context = FacesContext.getCurrentInstance();
System.out.println("Number found is " + this.selectedid);
if (selectedcategory != null) {
System.out.println("removing "+selectedcategory.getId()+" - " +selectedcategory.getDescription());
EntityTransaction tx = em.getTransaction();
tx.begin();
System.out.println("Merging..");
this.em.merge(selectedcategory);
System.out.println("removing...");
this.em.remove(selectedcategory);
tx.commit();
em.close();
emf.close();
}else{
System.out.println("Not found");
}
return "index.xhtml";
} catch (Exception e) {
e.printStackTrace();
return "index.xhtml";
}
}
public String update() {
try {
this.emf = Persistence.createEntityManagerFactory("timesheets1");
System.out.println("Update Getting Collection");
Category category = (Category) getDatatable().getRowData();
FacesContext context = FacesContext.getCurrentInstance();
System.out.println("PHASE ID="+context.getCurrentPhaseId().toString());
if (category != null) {
// DESCRIPTION VALUE BELOW IS ALWAYS OLD VALUE (IE DATA IN DATABASE)
System.out.println("updating "+category.getId()+" - " +category.getDescription());
this.em = this.emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
em.merge(category);
tx.commit();
em.close();
emf.close();
}else{
System.out.println("Not found");
}
return "index.xhtml";
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
public void setCollection(List<Category> collection) {
this.collection = collection;
}
public List<Category> getCollection() {
// this.emf=Persistence.createEntityManagerFactory("timesheets1");
// System.out.println("Getting Collection");
try {
this.emf = Persistence.createEntityManagerFactory("timesheets1");
this.em = this.emf.createEntityManager();
Query query = this.em.createNamedQuery("findAll");
this.collection = query.getResultList();
return this.collection;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public void setSelectedid(int id) {
this.selectedid=id;
}
public void setSelectedcategory(Category selectedcategory) {
this.selectedcategory = selectedcategory;
}
public HtmlDataTable getDatatable() {
return datatable;
}
public void setDatatable(HtmlDataTable datatable) {
this.datatable = datatable;
}
public Category getSelectedcategory() {
return selectedcategory;
}
}
My Mapped entity for JPA is here
package net.bssuk.timesheets.model;
import java.io.Serializable;
import javax.persistence.*;
/**
* The persistent class for the CATEGORIES database table.
*
*/
#Entity
#Table(name="CATEGORIES")
#NamedQuery(name="findAll", query = "SELECT c from Category c")
public class Category implements Serializable {
private static final long serialVersionUID = 1L;
private String description;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
public Category() {
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
}
OK - Updated my code to follow example. I have tried to incorporate an EJB into the scenario as follows
package net.bssuk.timesheets.ejb;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import net.bssuk.timesheets.model.Category;
#Stateless
public class CategoryEJB implements CategoryEJBRemote {
#PersistenceContext(unitName="timesheets1")
private EntityManager em;
#Override
public List<Category> findCategories() {
// TODO Auto-generated method stub
System.out.println("find categories");
Query query = em.createNamedQuery("findAll");
return query.getResultList();
}
#Override
public Category createCategory(Category category) {
// TODO Auto-generated method stub
em.persist(category);
return category;
}
#Override
public Category udpateCategory(Category category) {
// TODO Auto-generated method stub
return em.merge(category);
}
#Override
public void deleteCategory(Category category) {
// TODO Auto-generated method stub
em.remove(em.merge(category));
}
}
My EJB is below
package net.bssuk.timesheets.ejb;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import net.bssuk.timesheets.model.Category;
#Stateless
public class CategoryEJB implements CategoryEJBRemote {
#PersistenceContext(unitName="timesheets1")
private EntityManager em;
#Override
public List<Category> findCategories() {
// TODO Auto-generated method stub
System.out.println("find categories");
Query query = em.createNamedQuery("findAll");
return query.getResultList();
}
#Override
public Category createCategory(Category category) {
// TODO Auto-generated method stub
em.persist(category);
return category;
}
#Override
public Category udpateCategory(Category category) {
// TODO Auto-generated method stub
return em.merge(category);
}
#Override
public void deleteCategory(Category category) {
// TODO Auto-generated method stub
em.remove(em.merge(category));
}
}
Can anyone suggest if this sort of looks ok? Or have I completely lost the plot with it!
Look,
<h:dataTable var="row" border="0" value="#{beanCategory.collection}" binding="#{beanCategory.datatable}">
and
public List<Category> getCollection() {
// this.emf=Persistence.createEntityManagerFactory("timesheets1");
// System.out.println("Getting Collection");
try {
this.emf = Persistence.createEntityManagerFactory("timesheets1");
this.em = this.emf.createEntityManager();
Query query = this.em.createNamedQuery("findAll");
this.collection = query.getResultList();
return this.collection;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
You're loading the list inside a getter method. This is a very bad idea. A getter should solely be an access point to the bean property, not to do some business job. A getter can be called multiple times during bean's life. The DB will be hit on every call and the local collection property which was been updated by JSF during form submit will be overwritten again at a later point. This makes no sense.
Do the business job in the (post)constructor method or action(listener) methods. Definitely not in a getter. Here's a minimum kickoff example with some code improvements:
<h:dataTable value="#{bean.categories}" var="category">
<h:column>
<h:inputText value="#{category.description}" />
</h:column>
<h:column>
<h:outputText value="#{category.id}" />
</h:column>
<h:column>
<h:commandButton value="Delete" action="#{bean.delete(category)}" />
<h:commandButton value="Save" action="#{bean.update(category)}" />
</h:column>
</h:dataTable>
<h:inputText value="#{bean.newCategory.description}" />
<h:commandButton value="Add" action="#{bean.add}" />
(note that passing arguments in EL is supported since EL 2.2 (part of Servlet 3.0), Glassfish 3 is a Servlet 3.0 container, so it should definitely support it when web.xml is properly declared conform Servlet 3.0 spec)
with
#ManagedBean
#ViewScoped // Definitely don't use session scoped. I'm not sure about CDI approach, so here's JSF example.
public class Bean {
private List<Category> categories;
private Category newCategory;
#EJB
private CategoryService categoryService;
#PostConstruct
public void init() {
categories = categoryService.list();
newCategory = new Category();
}
public void add() {
categoryService.add(newCategory);
init();
}
public void delete(Category category) {
categoryService.delete(category);
init();
}
public void update(Category category) {
categoryService.update(category);
init();
}
public List<Category> getCategories() {
return categories;
}
public Category getNewCategory() {
return newCategory;
}
}
That should be it. See also:
Why JSF calls getters multiple times
Help understanding JSF's multiple calls to managed bean
<h:dataTable value=#{myBean.xxx}>: getXxx() get called so many times, why?
As I see, you have forgotten the <h:form>. This is very necessary to save inputs.