h:dataTable has no value - java

HI,
Have used JSF h:data Table - the jsf datatable is coming empty, my sp is returning values hence getList returns values but only headers are seen in the browser, table values are not seen in the browser.
Following is my JSP
<h:panelGrid>
<f:facet name="header">
<h:outputText value="Employee Details" />
</f:facet>
<h:dataTable value="#{dataTableBean.list}" var="loc"
bgcolor="#F1F1F1" border="10" cellpadding="5" cellspacing="3"
first="0" rows="5" width="50%">
<h:column>
<f:facet name="header">
<h:outputText value="Sponsor ID" />
</f:facet>
<h:outputText value="#{loc.sponsorID}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Sponsor Name" />
</f:facet>
<h:outputText value="#{loc.sponsorName}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Distributor ID" />
</f:facet>
<h:outputText value="#{loc.distributorID}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Distributor Name" />
</f:facet>
<h:outputText value="#{loc.distributorName}" />
</h:column>
</h:dataTable>
</h:panelGrid>
</h:form>
MY Bean
public class DataTableBean {
private List<BillTransPay> list;
public List<BillTransPay> getList() {
String SP_BILLPAY = "{call sp_aw_BillTransPay(?,?,?,?,?,?,?)}";
Connection con = null;
ResultSet rs = null;
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
con = java.sql.DriverManager
.getConnection(conString);
CallableStatement cbls = con
.prepareCall("{call sp_aw_BillTransPay(?,?,?,?,?,?,?)}");
cbls.setString(1, "csf");
cbls.setString(2, "20100101");
cbls.setString(3, "20100301");
cbls.setString(4, "B");
cbls.setString(5, "01CS");
cbls.setString(6, "ALL");
cbls.setInt(7, 14000);
rs = cbls.executeQuery();
list = new ArrayList<BillTransPay>();
while (rs.next()) {
BillTransPay btp = new BillTransPay();
btp.setSponsorID(rs.getString("SponsorCode"));
btp.setSponsorName(rs.getString("SponsorName"));
btp.setDistributorID(rs.getString("DistID"));
btp.setDistributorName(rs.getString("DistName"));
list.add(btp);
}
} catch (Exception ex) {
ex.printStackTrace();
}
return list;
}
public void setList(List<BillTransPay> list) {
this.list = list;
}
}
Faces-Config.xml
**<managed-bean>
<managed-bean-name>dataTableBean</managed-bean-name>
<managed-bean-class>
com.SQLProcess.dto.DataTableBean
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>**

Just run a debugger or add a System.out.println(list); right before return list; to see if the method get called and the list really contains items.
Said that, this expensive DB job should really not be done in a getter. It can be called multiple times during a request. You don't want to unnecessarily hit/stress your DB. Move the DB job into the bean's constructor. Also, you're leaking DB resources by not explicitly closing the Connection, Statement and ResultSet. You need to close them in finally block of the same try as where you have acquired them.

Related

Changing assigned user using p:selectOneMenu

I have been searching for similar issue but I could not find any.
so here is the thing
I am trying to create a web application that deals with HR stuff, like employee requests (Resign, loan, vacation, etc..)
I am using primeface and I have the following problem that I cant figure out.
The thing is I am trying to do is :
1- When user first creates the request and assigns the user and submit the form
the next step is
2- the manager would sees the request and then change the "Person responsible for the request" to a new one using the drop menu in the datatable and I have been trying to solve this problem with no luck.
Here is the dialog script
<h:form id='resignf'>
<p:dialog id='res' header="Resign Request" widgetVar="resign" minHeight="40">
<p:outputLabel value="Employee name" />
<p:inputText value="#{controller.resignName}" required="true" requiredMessage="This field is required" />
<p:outputLabel value="Employee Number" />
<p:inputText value="#{controller.resignEmployeNum}" required="true" />
<p:inputText value="#{controller.resignNationalIDNum}" required="true" />
<p:inputText value="#{controller.resignNotes}" required="true" />
<p:outputLabel for="AssignUser" value="User" />
<p:selectOneMenu id="AssignUser" value="#{controller.assignUser}" style="width:150px" converter="UConverter">
<f:selectItems value="#{controller.usersList}" var="user" itemLabel="#{user.username}"/>
</p:selectOneMenu >
<p:commandButton action="#{controller.createResignRequest()}" onclick="PF('resign').hide();" update="#all"/>
</p:dialog>
And the code is my controller.java file below to create the request in the table
/* Request to resign*/
private List<ResignationRequest> resignList;
private ResignationRequestController rController = new ResignationRequestController();
private String resignName;
private String resignEmployeNum;
private String resignNationalIDNum;
private String ResignNotes;
private int AutoAssignToIDNUM;
/* end of request to resign*/
public void createResignRequest() {
System.out.println("createResignRequest");
ResignationRequest newResign = new ResignationRequest();
newResign.setName(resignName);
newResign.setEmployeeNum(resignEmployeNum);
newResign.setNationalID(resignNationalIDNum);
newResign.setNotes(ResignNotes);
newResign.setUserID(AssignUser);
rController.create(newResign);
resignList = rController.findResignationRequestEntities(); //retrieves all the resigns from the database
}
Now all that is working perfectly, but when I try to change the old user with the new one here I get confused! so far what I have been thinking is I need to find the old user and then switch him, but I could not figure a way to do it using the select list. The script for for changing the "User responsible for the request" below
<p:dataTable id="resignTable1" cellSeparator="true" editMode="cell" editable="true" var="resign" value="#{controller.resignList}" paginator="true" rows="10" rowIndexVar="index1">
<p:ajax id="aj" event="cellEdit" listener="#{controller.editUser(user)}" update="resignTable1"/>
<p:column headerText="Employee number">
<p:cellEditor>
<f:facet name="output"> <h:outputText value="#{resign.employeeNum}" /></f:facet>
<f:facet name="input"> <h:inputText value="#{resign.employeeNum}" /></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="name">
<p:cellEditor>
<f:facet name="output"> <h:outputText value="#{resign.name}" /></f:facet>
<f:facet name="input"> <h:inputText value="#{resign.name}" /></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Request Number">
<p:cellEditor>
<f:facet name="output"> <h:outputText value="#{resign.id}" /></f:facet>
<f:facet name="input"> <h:inputText value="#{resign.id}" /></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="User responsible for the request">
<p:cellEditor>
<f:facet name="output"> <h:outputText value="#{resign.userID}" /></f:facet>
<f:facet name="input"> <h:inputText value="#{resign.userID}" /></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Comments">
<p:cellEditor>
<f:facet name="output"> <h:outputText value="#{resign.notes}" /></f:facet>
<f:facet name="input"> <h:inputText value="#{resign.notes}" /></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Send the request to the next employee">
<p:selectOneMenu id="AssignUser" value="#{controller.assignUser}" style="width:150px" converter="UConverter" onchange="submit();">
<f:selectItems value="#{controller.usersList}" var="user" itemLabel="#{user.username}" actionListener="#{controller.editRequestStep(resign)}" >
</f:selectItems>
</p:selectOneMenu >
In my controller file
public void editRequestStep(ResignationRequest r) {
System.out.println("Edit resign");
try {
System.out.println("Edit resign");
rController.edit(r);
} catch (Exception ex) {
Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
}
}
I tried to get as much as I could from the code but I have a lot of stuff that I am not sure if I should submit. I tried ajax
NOTE: I am using mySQL, apache tomcat in case if it matters.
Solved it.
public void editRequestStep(ResignationRequest r) {
System.out.println("Edit resign " + EditAssignUser +" this is userthig" + r.getName());
try {
System.out.println("Edit resign");
r.setUserID(EditAssignUser);
} catch (Exception ex) {
Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
}
}
<p:selectOneMenu id="AssignUser" value="#{controller.editAssignUser}" style="width:150px" converter="UConverter">
<p:ajax listener="#{controller.editRequestStep(resign)}" update="#all"/>
<f:selectItems value="#{controller.usersList}" var="user" itemLabel="#{user.username}" >
</f:selectItems>
I did not notice that I used the variable assignUser 2 times, which actually missed me up. So what I did is I created new Users variable called "editAssignUser" then in my controller I just set the user look at the code below
public void editRequestStep(ResignationRequest r) {
System.out.println("Edit resign " + EditAssignUser +" this is userthig" + r.getName());
try {
System.out.println("Edit resign");
r.setUserID(EditAssignUser);
} catch (Exception ex) {
Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
}
}

JSF <h:inputText> / <h:outputText> not rendering according to boolean value

I have a <h:dataTable> that is populated from an Entity class and displays different products. I want to be able to click a <h:commandLink> and edit row that the link belongs to. I have structured it mostly the same way as this nice example and article at mkyong.
The table (with some columns excluded):
<h:form>
<h:dataTable id="gnomeTable" value="#{gnome.productList}"
var="item"
styleClass="gnomeTable"
headerClass="gnomeTableHeader"
rowClasses="gnomeTableOddRow,gnomeTableEvenRow"
bgcolor="#F1F1F1" border="10" cellspacing="2"
rules="all" >
<f:facet name="header">
<h:outputText value="List of available gnomes for sale" />
</f:facet>
<h:column>
<f:facet name="header">
<h:outputText value="GnomeID" />
</f:facet>
<h:outputText value="#{item.id}"></h:outputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Name"/>
</f:facet>
<h:outputText value="#{item.name}" rendered="#{not item.editable}"></h:outputText>
<h:inputText value="#{item.name}" rendered="#{item.editable}"></h:inputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Available"/>
</f:facet>
<h:outputText value="#{item.available}" rendered="#{not item.editable}"></h:outputText>
<h:inputText value="#{item.available}" rendered="#{item.editable}"></h:inputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Edit"/>
</f:facet>
<h:commandLink value="Edit" action="#{gnome.editAction(item)}" rendered="#{not item.editable}" />
</h:column>
</h:dataTable>
<h:commandButton value="Save Changes" action="#{gnome.saveAction}" />
</h:form>
The Bean methods:
public String saveAction() {
for (Gnome g : productList) {
g.setEditable(false);
}
return null;
}
public String editAction(Gnome gnome) {
gnome.setEditable(true);
return null;
}
The property boolean editable in the entity class is annotated as #Transient since it's not a part of the persistant data and I don't want the entity manager to touch it:
#Transient
private boolean editable;
I thought this would result in the boolean variable being set to true when the Edit-button is clicked, the row re-renders with the fields now as <h:inputText>, but nothing happens. I have debugged it and made sure that the variable is set to true, which it is.
I also found this SO question that I thought perhaps could be something similar to the problem I am experiencing. The difference though is that a refresh of the page doesn't change anything.
What am I missing?
Edit 1:
In the first version of this question I had by mistake pasted the wrong code. The one that is included now is my current code, that in theory should work but does not.
Edit 2:
Initialization of productList, where Gnome is the entity class.
private List<Gnome> productList = new ArrayList<>();
public List<Gnome> getProductList() {
productList = gnomeFacade.findAll();
return productList;
}
public void setProductList(List<Gnome> productList) {
this.productList = productList;
}
After testing your example, the only possible error is that you are using a RequestScoped bean. In order to make it work, you need at least ViewScoped or SessionScoped. Ortherwise, the productList changed content is lost at every requests (button action).
According to the edit, the second mistake is how data is took. You need to load your data somewhere else than getter like this :
#PostConstruct
public void init()
{
productList = gnomeFacade.findAll();
}
public List<Gnome> getProductList()
{
return productList;
}
Ortherwise, at every actions your list is reset.

Bind property of property - JSF2 - <h:dataTable>

(Please view edit down below)
As a continuation of the code from this SO question, I am now trying to save the modified values of a <h:dataTable> using the persistance of the entity class.
I have a dataTable as follows:
<h:form>
<h:dataTable id="userTable" value="#{admin.customerList}"
var="c"
binding="#{admin.customerTable}"<!-- Not sure if this is necessary -->
styleClass="gnomeTable"
headerClass="gnomeTableHeader"
rowClasses="gnomeTableOddRow,gnomeTableEvenRow"
bgcolor="#F1F1F1" border="10" cellspacing="2"
rules="all" >
<f:facet name="header">
<h:outputText value="All registered customers" />
</f:facet>
<h:column>
<f:facet name="header">
<h:outputText value="User ID" />
</f:facet>
<h:outputText value="#{c.id}"></h:outputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Username"/>
</f:facet>
<h:outputText value="#{c.username}" rendered="#{not c.editable}"></h:outputText>
<h:inputText value="#{c.username}" rendered="#{c.editable}"></h:inputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Email"/>
</f:facet>
<h:outputText value="#{c.email}" rendered="#{not c.editable}"></h:outputText>
<h:inputText value="#{c.email}" rendered="#{c.editable}"></h:inputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Banned?"/>
</f:facet>
<h:selectBooleanCheckbox value="#{c.banned}" rendered="#{not c.editable}" disabled="true"></h:selectBooleanCheckbox>
<h:selectBooleanCheckbox value="#{c.banned}" rendered="#{c.editable}" disabled="false"></h:selectBooleanCheckbox>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Admin?"/>
</f:facet>
<h:selectBooleanCheckbox value="#{c.admin}" rendered="#{not c.editable}" disabled="true"></h:selectBooleanCheckbox>
<h:selectBooleanCheckbox value="#{c.admin}" rendered="#{c.editable}" disabled="false"></h:selectBooleanCheckbox>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Edit"/>
</f:facet>
<h:commandLink value="Edit" action="#{admin.editAction(c)}" rendered="#{not c.editable}" />
<h:commandButton value="Save" action="#{admin.saveAction(c)}" rendered="#{c.editable}" />
</h:column>
</h:dataTable>
</h:form>
The table is populated successfully, and when I click the edit button in the last column, I am able to modify the values of the columns. If I then click the Save button of the last column, #{admin.saveAction(c)}, is called with the parameter c, which is the customer that I believe I have just modified.
The method is called, though no changes are being made.
saveAction(Customer c) looks like this:
public String saveAction() {
for (Customer customer : customerList) {
System.out.println("Trying to update customer with ID: " + customer.getId());
customerFacade.updateCustomer(customer);
}
return null;
}
and updateCustomer(Customer c) looks like this:
public void updateCustomer(Customer c) {
em.merge(c);
}
Either I have not understood how the variable c corresponds to a Customer object in the list of customers customerList, or I have not successfully bound it to it's property. Simply put, no changes are made to the Customer object when I modify any of the fields.
Is there a way to bind the properties of each Customer object c in customerList, so that the values are being updated when the fields in the datatable connected to the current object is being changed?
Must I use a listener that monitors if a field is being modified, and then calls the setter of the objects property?
Edit:
Summarize of the changes to the code that I've made.
The main issue seems to be the fact that the customer object (entity class) doesn't get modified when I modify the field values in the datatable.
The saveAction method now look as follows
public String saveAction() {
for (Customer customer : customerList) {
System.out.println("Trying to update customer with ID: " + customer.getId());
customerFacade.updateCustomer(customer);
}
return null;
}
The bean class:
#ManagedBean(name = "admin")
#ViewScoped
public class AdminBean implements Serializable {
#EJB
CustomerFacade customerFacade;
private List<Customer> customerList = new ArrayList<>();
#PostConstruct
public void init() {
customerList = customerFacade.findAll();
}
...
So, the main question is now only why my values aren't being updated?

JSF - How to get old and new value when using Primefaces RowEditEvent?

I have a datatable with 2 columns(name and description) and I want to update my database when a person updates a row and clicks the checkmark which triggers the execBacking.update method.
In this method, I get the new values by casting event.getObject(), but how can i also get the old values? The name is my primary key so i need the old value to know which row to update in the db.
xhtml page
<p:ajax event="rowEdit" listener="#{execBacking.update}" update=":execForm:execMessages" />
<p:column headerText="Name">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{exec.name}" />
</f:facet>
<f:facet name="input">
<h:inputText value="#{exec.name}" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Description">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{exec.description}" />
</f:facet>
<f:facet name="input">
<h:inputText value="#{exec.description}" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Actions">
<p:rowEditor />
<p:commandLink styleClass="ui-icon ui-icon-trash" type="submit" actionListener="#{execBacking.delete}" update=":execForm:execMessages" >
<f:attribute name="execName" value="#{exec.name}" />
</p:commandLink>
</p:column>
</p:dataTable>
Backing bean
public void update(RowEditEvent event) {
Dao dao = new Dao(ds);
Exec exec = (Exec) event.getObject();
System.out.println("name = "+exec.getName()); //New name
System.out.println("desc = "+exec.getDescription()); //New desc
try {
// If the new exec was updated successfully
if(dao.updateExec(accessBacking.getUsername(), null, exec.getName(), exec.getDescription())) {
FacesContext.getCurrentInstance().addMessage("growl", new FacesMessage(FacesMessage.SEVERITY_INFO, "Success", "Exec Updated Successfully!"));
} else {
FacesContext.getCurrentInstance().addMessage("messages", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "Error Updating Exec!"));
}
} catch (Exception e) {
FacesContext.getCurrentInstance().addMessage("messages", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", e.getMessage()));
}
}
I would recommend not having name be your primary key, but instead add an auto-incrementing id field and make that your primary key, and don't make that field editable by the user. This guarantees you always have access to the record that you want to update.
Generally speaking it's bad practice to attempt to modify the primary key in a database the way you're trying to do it.
You can register a ValueChangeListener on the component you're interested in using:
<p:column headerText="Description">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{exec.name}" />
</f:facet>
<f:facet name="input">
<h:inputText value="#{exec.name}">
<f:valueChangeListener binding="#{keyChangedListener}"/>
<f:ajax/>
</h:inputText>
</f:facet>
</p:cellEditor>
</p:column>
keyChangeListener will correspond to an implementation of ValueChangeListener and we're using <f:ajax/> here to ensure that the valueChanged event is fired on the textbox. Otherwise the listener will not be notified. Your listener should look something like:
#ManagedBean(name="keyChangedListener")
#ViewScoped
public class KeyChangeListener implements ValueChangeListener{
public void processValueChange(ValueChangeEvent event) throws AbortProcessingException{
Object oldValue = event.getOldValue(); //get the old value
Object newValue = event.getNewValue(); //get the new value
}
I'm using the #ViewScopedhere as advised by the JSF Spec, to avoid unwanted side effects.

how to display the data from database on a button click in java jsf

<f:view>
<h:form>
<h:panelGrid>
<f:facet name="header">
<h:outputText value="Student Mark List"/>
</f:facet>
<h:column>
<h:outputText value="Student Number : "></h:outputText>
<h:inputText value="#{stuBean.stuNumber}"/>
</h:column>
<h:column>
<h:commandButton id = "getStuMarkList" value="Get Mark List" action="#{stuBean.listOfMarks}" >
</h:commandButton> </h:column>
</h:panelGrid>
<h:panelGrid bgcolor="#9AC8E6" width="100%">
<h:dataTable id="datatable" value="#{stuBean.marksList}" var="marksList">
<h:column>
<f:facet name="header">
<h:outputText style=""value="Maths Marks" />
</f:facet>
<h:inputText value="#{marksList.mMarks}" > </h:inputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText style=""value="English Marks" />
</f:facet>
<h:inputText value="#{marksList.eMarks}" > </h:inputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText style=""value="Physics Marks" />
</f:facet>
<h:inputText value="#{marksList.pMarks}" > </h:inputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText style=""value="Social Marks" />
</f:facet>
<h:inputText value="#{marksList.sMarks}" > </h:inputText>
</h:column>
</h:dataTable>
</h:panelGrid>
</h:form>
</f:view>
StudentBean.java
//... getters and setters
public String listOfMarks(){
student.marksListFromDb(stuNum);
return null;
}
private List marksList= new ArrayList();
public List getMarksList() {
return marksList;
}
Please check my above code where I'm trying to get the values from database on button click (listOfMarks) and display them in the datatable.
Using the above code it is not fetching the data.Kindly help me if I'm wrong doing wrong some where...
Some general things:
An action method in a commandButton should return void or String. The String is used for navigation. If you want to reload the same page return null.
You are mixing the getter method for your markList with an action method.
You should have an action method e.g. fillMarkList() that fills the list, returns a null String and reloads the current page and you should have a getter method getMarkList() that returns the list for the dataTable:
public String fillMarkList() {
// fill the list:
student.markListFromDb(stuNum);
// reload current page:
return null;
}
public List getMarkList() {
return markList();
}
Your button then should call fillMarkList() as action method:
<h:commandButton id="getStuMarkList"
value="Get Mark List"
action="#{stuBean.fillMarkList}" />
UPDATE:
Just noticed your usage of h:panelGrid. I tried your version and it renders as correct table. But I think correct usage is without columns. You have to define column number as attribute of h:panelGrid and simply put the containing elements inside the grid:
<h:panelGrid columns="3">
<f:facet name="header">
<h:outputText value="Student Mark List"/>
</f:facet>
<h:outputText value="Student Number : "></h:outputText>
<h:inputText value="#{stuBean.stuNumber}"/>
<h:commandButton id = "getStuMarkList" value="Get Mark List"
action="#{stuBean.listOfMarks}" >
</h:commandButton> </h:column>
</h:panelGrid>
Although that "please check my code" doesn't generally work here, one thing I spotted:
public List getMarkList() {
student.markListFromDb(stuNum);
return markList;
}
You don't put anything into markList here, do you?
Edit: also note that those are quite equal in terms of execution: #{stuBean.getMarkList} and #{stuBean.markList} since the latter is likely to be translated to StudentBean.getMarkList() by the framework, as will be #{stuBean.getMarkList}.

Categories