I had a school project this past semester building a web application with a database for a section of Habitat for Humanity. I was able to connect and write to the database just fine, but I had trouble reading the data that was in the database and placing it into a Primefaces DataTable.
I will add my Java Class to read from the database below, as well as my HTML that has my variables for the DataTable.
If someone can take a look at my code and see if they find any mistakes or have any hints/tips, it would be much appreciated. The class is over now, but I want to be able to try and figure out the rest of the web application to get it fully up and running, instead of just leaving it in the past. Any help would be appreciated!
UserDAO - Java Class:
package dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import model.UserBean;
/**
* #author rnikolich
*/
public class UserDAO {
String driverName = "org.apache.derby.jdbc.ClientDriver";
String connStr = "jdbc:derby://localhost:1527/HabitatDatabase";
public static ArrayList<UserBean> getOwners() {
ArrayList<UserBean> ownerCollection = new ArrayList<>();
Connection DBConn = null;
try {
DBHelper.loadDriver("org.apache.derby.jdbc.ClientDriver");
String myDB = "jdbc:derby://localhost:1527/HabitatDatabase";
DBConn = DBHelper.connect2DB(myDB, "test", "test");
// UserBean usr = new UserBean();
String query = "SELECT * FROM HABITATDATABASE.OWNER";
// With the connection made, create a statement to talk to the DB
server.
// Create a SQL statement to query, retrieve the rows one by one (by
going to the
// columns), and formulate the result string to send back to the
client.
Statement stmt = DBConn.createStatement();
ResultSet rs = stmt.executeQuery(query);
// Timestamp timestamp;
// Vote aVote;
while (rs.next()) {
UserBean own = new UserBean();
own.setOwnerID(rs.getString("OwnerID"));
own.setOwnerName(rs.getString("OwnerName"));
own.setPhone(rs.getString("Phone"));
own.setEmail(rs.getString("Email"));
// or rs.getString("PL_Name");
// timestamp = rs.getTimestamp("vote_TimeStamp");
//
// // make a VoteTally object out of the values
// aVote = new Vote(PL_Name, timestamp);
// add the newly created object to the collection
ownerCollection.add(own);
}
rs.close();
stmt.close();
} catch (Exception e) {
System.err.println("ERROR: Problems with SQL select");
e.printStackTrace();
}
try {
DBConn.close();
} catch (SQLException e) {
System.err.println(e.getMessage());
}
return ownerCollection;
}
}
usersController - Java Class:
package controller;
import dao.UserDAO;
import java.util.ArrayList;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import model.UserBean;
import java.io.Serializable;
#ManagedBean
#SessionScoped
public class UsersController implements Serializable {
private UserBean theModel;
private ArrayList<UserBean> owner;
/**
* *
*/
public ArrayList<UserBean> getOwner() {
UserDAO own = new UserDAO();
owner = UserDAO.getOwners();
return owner;
}
public void setOwner(ArrayList<UserBean> owner) {
this.owner = owner;
}
/**
* Creates a new instance of UsersController
*/
public UsersController() {
theModel = new UserBean();
}
public UserBean getTheModel() {
return theModel;
}
public void setTheModel(UserBean theModel) {
this.theModel = theModel;
}
}
viewOwner - XHTML:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:a="http://xmlns.jcp.org/jsf/passthrough">
<h:head>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<title>View Owner</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"></link>
</h:head>
<h:body style="background-color: gray">
<h:panelGroup layout="block" styleClass="container">
<h:panelGroup layout="block" styleClass="row centered-form">
<h:panelGroup layout="block" styleClass="col-xs-12 col-sm-8 col-md-10 col-sm-offset-2 col-md-offset-1"
style="background-color: limegreen">
<h:panelGroup layout="block" styleClass="panel panel-default">
<center><h:graphicImage value="#{resource['images:habitat-for-humanity-logo.jpg']}" width="200" height="180"/></center>
<h:panelGroup layout="block" styleClass="panel-heading">
<center><h3 class="panel-title">View Owner</h3></center>
</h:panelGroup>
<br></br>
<h:panelGroup layout="block" styleClass="panel-body">
<h:form id="viewOwnerForm">
<h:panelGroup layout="block" styleClass="form-group">
<p:growl id="msgs" showDetail="true" />
<p:dataTable id="viewOwnerDataTable" value="#{usersController.owner}" var="o" rows="10">
<f:facet name="header">
View Owners Table
</f:facet>
<p:column headerText="OwnerID">
<h:outputText value="#{o.ownerID}" />
</p:column>
<p:column headerText="OwnerName">
<h:outputText value="#{o.ownerName}" />
</p:column>
<p:column headerText="Phone">
<h:outputText value="#{o.phone}" />
</p:column>
<p:column headerText="Email">
<h:outputText value="#{o.email}" />
</p:column>
</p:dataTable>
<br></br>
<h:commandLink>
<p:graphicImage value="#{resource['images:pdf.png']}" width="24"/>
<p:dataExporter type="pdf" target="tbl" fileName="owners"/>
</h:commandLink>
<br></br>
<br></br>
<h:link outcome="home" value="Home" styleClass="btn btn-warning btn-block" id="Home" style="background-color: blue"/>
<h:link outcome="viewHome" value="View Entry Home" styleClass="btn btn-warning btn-block" id="viewHome" style="background-color: blue"/>
</h:panelGroup>
</h:form>
</h:panelGroup>
</h:panelGroup>
</h:panelGroup>
</h:panelGroup>
</h:panelGroup>
</h:body>
</html>
Related
I have a problem with CDI scope.
I have a bean with conversation scoped, ClientController, where I have client and phone object to be push in a service order. When I register a new client, I can push one or more phones to this client. For this, I have used conversation scope. However each request to push a new phone to my client is executing the #PostContruct method, doing the bean lose its state, even I am giving begin on the conversation when I push the first phone.
At first, I guess the problem was the bean configuration, but when I removed the template that was declared on the client page, the application works correct. This template use a bean with session scope, to control the page language by the user choice.
Next has my code, and you can follow my code on github repository by this link https://github.com/mcqueide/service-order.
ClientController.java
package br.com.codeshare.controller;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.enterprise.inject.Produces;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import br.com.codeshare.enums.ErrorCode;
import br.com.codeshare.exception.BusinessException;
import br.com.codeshare.model.Client;
import br.com.codeshare.model.Phone;
import br.com.codeshare.qualifiers.SessionMap;
import br.com.codeshare.service.ClientService;
import br.com.codeshare.service.PhoneService;
import br.com.codeshare.util.WebResources;
#Named
#ConversationScoped
public class ClientController implements Serializable {
private static final long serialVersionUID = 1L;
#Inject
private FacesContext facesContext;
#Inject #SessionMap
private Map<String, Object> sessionMap;
#Inject
private ClientService clientService;
private Client newClient;
#Inject
private PhoneController phoneController;
#Inject
private PhoneService phoneService;
#Inject
private Conversation conversation;
private String filterName;
private List<Client> listClients;
private Client clientSelected;
private List<Phone> phoneToBeRemove;
#Produces
#Named
public Client getNewClient() {
return newClient;
}
#PostConstruct
public void initNewClient() {
newClient = new Client();
newClient.setTelefones(new ArrayList<Phone>());
listClients = clientService.findAll();
}
public String save() throws Exception {
try {
validatePhoneLeastOnePhoneObligatory(newClient);
clientService.save(newClient);
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, WebResources.getMessage("register"),WebResources.getMessage("sucess_register")));
initNewClient();
}catch (BusinessException e) {
FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_ERROR,WebResources.getMessage(e.getErrorCode()),"");
facesContext.addMessage(null, m);
}catch (Exception e) {
String errorMessage = getRootErrorMessage(e);
FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_ERROR,errorMessage,WebResources.getMessage("unsuccessful"));
facesContext.addMessage(null, m);
}
if(!conversation.isTransient()){
conversation.end();
}
return null;
}
public String update(Client client) throws Exception{
try {
validatePhoneLeastOnePhoneObligatory(client);
clientService.update(client,phoneToBeRemove);
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, WebResources.getMessage("register"),WebResources.getMessage("sucess_register")));
initNewClient();
}catch (BusinessException e) {
FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_ERROR,WebResources.getMessage(e.getErrorCode()),"");
facesContext.addMessage(null, m);
return null;
} catch (Exception e) {
String errorMessage = getRootErrorMessage(e);
FacesMessage m = new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, WebResources.getMessage("unsuccessful"));
facesContext.addMessage(null, m);
return null;
}
if(!conversation.isTransient()){
conversation.end();
}
return "clients";
}
private void validatePhoneLeastOnePhoneObligatory(Client client) throws BusinessException {
if(client.getHomePhone().isEmpty() && client.getBisenessPhone().isEmpty()){
throw new BusinessException(ErrorCode.LEAST_ONE_PHONE_OBLIGATORY.getErrorCode());
}
}
private String getRootErrorMessage(Exception e) {
String errorMessage = "Registration failed. See server log for more information";
if (e == null) {
return errorMessage;
}
Throwable t = e;
while (t != null) {
errorMessage = t.getLocalizedMessage();
t = t.getCause();
}
return errorMessage;
}
public void addClientPhone() {
if(conversation.isTransient()){
conversation.begin();
}
phoneController.getNewPhone().setClient(newClient);
if (newClient.getPhones() == null) {
newClient.setTelefones(new ArrayList<Phone>());
}
newClient.getPhones().add(phoneController.getNewPhone());
phoneController.initNewPhone();
}
public void removeClientPhone(Phone phone){
if(conversation.isTransient()){
conversation.begin();
}
clientSelected.getPhones().remove(phone);
if(phoneToBeRemove == null){
phoneToBeRemove = new ArrayList<Phone>();
}
phoneToBeRemove.add(phone);
}
public void addClientPhoneOnUpdate() {
if(conversation.isTransient()){
conversation.begin();
}
phoneController.getNewPhone().setClient(clientSelected);
if (clientSelected.getPhones() == null) {
clientSelected.setTelefones(new ArrayList<Phone>());
}
clientSelected.getPhones().add(phoneController.getNewPhone());
phoneController.initNewPhone();
}
public void searchByName() {
listClients = null;
if(filterName == null){
listClients = clientService.findAll();
}
listClients = clientService.findByName(filterName);
}
public String edit(Client client) {
if(conversation.isTransient()){
conversation.begin();
}
this.clientSelected = client;
List<Phone> phoneList = phoneService.findPhoneByClientId(clientSelected.getId());
clientSelected.setTelefones(phoneList);
sessionMap.put("client", client);
return "update_client";
}
public Client getClientSelected() {
return (Client) sessionMap.get("client");
}
public String getFilterName() {
return filterName;
}
public void setFilterName(String filterName) {
this.filterName = filterName;
}
public List<Client> getListClients() {
return listClients;
}
}
Language.java
package br.com.codeshare.util;
import java.io.Serializable;
import java.util.Locale;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
#Named
#SessionScoped
public class Language implements Serializable {
private static final long serialVersionUID = 1L;
#Inject
private FacesContext facesContext;
#PostConstruct
public void init(){
localeCode = "pt";
countryLocaleCodeChanged();
}
private String localeCode;
public String getLocaleCode() {
return localeCode;
}
public void setLocaleCode(String localeCode) {
this.localeCode = localeCode;
}
// value change event listener
public void countryLocaleCodeChanged() {
facesContext.getViewRoot().setLocale(new Locale(localeCode));
}
}
client.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets" template="/template.xhtml">
<ui:define name="titulo">
#{label['client.title']}
</ui:define>
<ui:define name="body">
<h:form id="form">
<p:messages />
<p:fieldset legend="#{label['client.fieldset.client']}" id="client">
<p:panelGrid columns="1" styleClass="panelGrid-semBorda">
<p:outputLabel for="name" value="#{label['client.name']}" />
<p:inputText id="name" value="#{newClient.name}" />
<p:outputLabel for="adress" value="#{label['client.adress']}" />
<p:inputText id="adress" value="#{newClient.adress}" />
<p:fragment rendered='#{!language.localeCode.equals("en")}'>
<p:panelGrid columns="1" styleClass="panelGrid-semBorda">
<p:outputLabel for="homePhone_pt" value="#{label['client.homePhone']}" />
<p:inputMask id="homePhone_pt" value="#{newClient.homePhone}" mask="(99)99999-9999"/>
<p:outputLabel for="bisenessPhone_pt" value="#{label['client.businessPhone']}" />
<p:inputMask id="bisenessPhone_pt" value="#{newClient.bisenessPhone}" mask="(99)9999-9999"/>
</p:panelGrid>
</p:fragment>
<p:fragment rendered='#{language.localeCode.equals("en")}'>
<p:panelGrid columns="1" styleClass="panelGrid-semBorda">
<p:outputLabel for="homePhone_en" value="#{label['client.homePhone']}" />
<p:inputText id="homePhone_en" value="#{newClient.homePhone}"/>
<p:outputLabel for="bisenessPhone_en" value="#{label['client.businessPhone']}" />
<p:inputText id="bisenessPhone_en" value="#{newClient.bisenessPhone}"/>
</p:panelGrid>
</p:fragment>
</p:panelGrid>
</p:fieldset>
<p:fieldset legend="#{label['client.fieldset.phone']}" id="phones">
<p:panelGrid id="phone" columns="1" styleClass="panelGrid-semBorda">
<p:outputLabel for="brand" value="#{label['phone.brand']}" />
<p:inputText id="brand" value="#{newPhone.brand}" />
<p:outputLabel for="model" value="#{label['phone.model']}" />
<p:inputText id="model" value="#{newPhone.model}" />
<p:outputLabel for="state" value="#{label['phone.state']}"/>
<p:selectOneRadio id="state" value="#{newPhone.state}">
<f:selectItems value="#{phoneStates}" var="p" itemValue="#{p}" itemLabel="#{label[p.label]}" />
</p:selectOneRadio>
<p:outputLabel for="esn" value="#{label['phone.esn']}" />
<p:inputText id="esn" value="#{newPhone.esn}" />
</p:panelGrid>
<p:commandButton value="#{label['phone.add']}" action="#{clientController.addClientPhone}" update="phoneTable phones"/>
<p:dataTable value="#{newClient.phones}" var="phone" emptyMessage="#{label['phone.notadd']}"
id="phoneTable">
<p:column headerText="#{label['phone.brand']}">
<p:outputLabel value="#{phone.brand}"/>
</p:column>
<p:column headerText="#{label['phone.model']}">
<p:outputLabel value="#{phone.model}"/>
</p:column>
</p:dataTable>
</p:fieldset>
<p:commandButton action="#{clientController.save}" value="#{label['client.save']}" update="#form"/>
</h:form>
</ui:define>
</ui:composition>
template.xhtml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets">
<f:view locale="#{language.localeCode}" encoding="utf-8">
<h:head>
<title>
<ui:insert name="title"/>
</title>
<link rel="stylesheet" type="text/css" href="resources/css/reset.css" />
<link rel="stylesheet" type="text/css" href="resources/css/style.css" />
<link rel="stylesheet" type="text/css" href="resources/css/fonts/font-awesome.min.css" />
</h:head>
<body>
<div class="main">
<div class="menu">
<ui:include src="/menu.xhtml" />
</div>
<div id="body">
<ui:insert name="body"/>
</div>
</div>
</body>
</f:view>
</html>
menu.xhtml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:composition>
<p:menubar>
<p:submenu label="#{label['menu.serviceorder']}">
<p:menuitem value="#{label['menu.serviceorder']}" url="/service-order.jsf"/>
<p:menuitem value="#{label['menu.serviceorder.new']}" url="/new-service-order.jsf"/>
</p:submenu>
<p:submenu label="#{label['menu.client']}">
<p:menuitem value="#{label['menu.client.new']}" url="/client.jsf"></p:menuitem>
<p:menuitem value="#{label['menu.clients']}" url="/clients.jsf"></p:menuitem>
</p:submenu>
</p:menubar>
<h:form class="menu_languages">
<p:selectOneMenu value="#{language.localeCode}">
<f:selectItem itemLabel="Português" itemValue="pt" />
<f:selectItem itemLabel="English" itemValue="en" />
<p:ajax listener="#{language.countryLocaleCodeChanged}" update="#all" />
</p:selectOneMenu>
</h:form>
</ui:composition>
</html>
I am pretty convinced that you are running into one of the following problems:
Conversation ends
try to play with some #PreDestroy methods to see when does the conversation vanish
make sure you do not end() conversations earlier (checking your code that would mean calling save/update)
New conversation is created every time you add phone (this is most likely the cause)
when you want another request to be associated with your running conversation, you need to make use of conversation ID (propagate it)
note that you can obtain the ID by calling conversation.getId()
to verify this, check that your URL contains the given conversation ID
also note that if you every time create a new Conversation, the old long-running ones are still hanging in there
Propagation of Conversation is done by appending a cid (conversation ID) to the request URL. Here is a quote from CDI spec (which I suggest you read) explaining when is conversation propagated automatically:
If the current Servlet request is a JSF request, and the conversation is in long-running state, it is propagated according to the following rules:
The long-running conversation context associated with a request that renders a JSF view is automatically propagated to any faces request (JSF form submission) that originates from that rendered page.
The long-running conversation context associated with a request that results in a JSF redirect (a redirect resulting from a navigation rule or JSF NavigationHandler) is automatically propagated to the resulting non-faces request, and to any other subsequent request to the same URL. This is accomplished via use of a request parameter named cid containing the unique identifier of the conversation.
I could resolved this with this:
<f:metadata>
<f:event listener="#{clientController.initConversation()}" type="preRenderView" />
</f:metadata>
Now when my page is render, I have my cid on my post action. But I don’t know if it is the better way to resolve this, because I want to transform my transaction in long-running just when the user click to add a phone, so if someone has a better idea, share please.
I have a set of p:accordionPanel's that I wish to update in my JSF 2.2 page.
The first one lists items of the list as tabs, in the tab it shows the name of the list item plus a button to delete that item. Clicking delete correctly removes the item and updates the panel via ajax
When all items have been removed it will render a new accordion panel informing the user there are no items and one needs to be added.
This all works fine, however when a new item is added is should once again render the first accordion panel showing the item with the option to remove it.
I believe the following is Minimal, Complete and Verifiable (if not please let me know why not)
The xHTML
<!DOCTYPE html>
<html xmlns="http://www.w3c.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Forms</title>
</h:head>
<h:body>
<h:form id="mainForm">
<p:outputPanel id="panelContainer">
<p:accordionPanel id="formsPanel" value="#{formController.forms}"
var="formInstance" rendered="#{not empty formController.forms}">
<p:tab title="#{formInstance.name}">
<p:panelGrid columns="3" layout="grid">
<h:outputLabel for="name" value="Form name:" />
<h:outputText id="name" value="#{formInstance.name}" />
<p:commandButton
action="#{formController.deleteForm(formInstance.name)}"
value="Delete form" update=":mainForm:panelContainer" />
</p:panelGrid>
</p:tab>
</p:accordionPanel>
<p:accordionPanel id="addFormPanel"
rendered="#{empty formController.forms}">
<p:tab title="No forms added yet, please add some">
<h:form>
<p:panelGrid columns="3" layout="grid">
<h:outputLabel value="Form name:" />
<p:inputText value="#{formController.form.name}" required="true"
label="text" />
<p:commandButton update=":mainForm:panelContainer"
action="#{formController.createForm}" value="Add form" />
</p:panelGrid>
</h:form>
</p:tab>
</p:accordionPanel>
</p:outputPanel>
</h:form>
</h:body>
</html>
The Form
public class Form implements Serializable
{
private String name;
public Form()
{
}
public Form(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}
And the FormController
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
#Named
#ViewScoped
public class FormController implements Serializable
{
private static List<Form> forms;
{
forms = new ArrayList<>();
forms.add(new Form("Form 1"));
forms.add(new Form("Form 2"));
}
private Form form = new Form();
public void createForm()
{
forms.add(form);
form = new Form();
}
public void deleteForm(String name)
{
for(int i=0; i < forms.size(); i++)
{
Form form = forms.get(i);
if (form.getName().equals(name))
{
forms.remove(i);
}
}
}
public List<Form> getForms()
{
return forms;
}
public Form getForm()
{
return form;
}
}
I try to get the information about the clicked button in a <p:datalist>, but it doesn't work.
My View:
<ui:composition 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"
xmlns:p="http://primefaces.org/ui" template="/WEB-INF/template.xhtml">
<ui:define name="head">
<title>Hash Generator</title>
</ui:define>
<ui:define name="content">
<h:form id="hashForm">
<p:dataList id="hashList" value="#{hashGeneratorBean.hashList}" var="entry" rowIndexVar="idx" itemType="none">
<p:column>
<h:outputText value="#{idx + 1}" />
<h:inputText value="#{entry.clearText}" />
<h:inputText value="#{entry.hashedText}" readonly="true" disabled="true" size="#{entry.hashedText.length() + 15}"/>
<p:commandButton id="addRow" actionListener="#{hashGeneratorBean.addRow}" icon="ui-icon-plus" title="Icon Only" update="hashList">
<f:setPropertyActionListener value="#{entry}" target="#{hashGeneratorBean.selectedRow}" />
</p:commandButton>
<p:commandButton id="debugBtn" icon="ui-icon-disc" title="Icon Only" update=":hashForm:display" oncomplete="PF('dlg').show()">
<f:setPropertyActionListener value="#{entry}" target="#{hashGeneratorBean.selectedRow}" />
</p:commandButton>
</p:column>
</p:dataList>
<p:commandButton actionListener="#{hashGeneratorBean.hash}" value="Generate Hashes" update="hashList" />
<p:dialog modal="true" widgetVar="dlg">
<h:panelGrid id="display" columns="2">
<f:facet name="header">
<h:outputText value="#{hashGeneratorBean.selectedRow.clearText}" />
</f:facet>
<h:outputText value="#{hashGeneratorBean.selectedRow.hashedText}" />
</h:panelGrid>
</p:dialog>
</h:form>
</ui:define>
</ui:composition>
My Controller:
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;
import com.google.common.base.Charsets;
import com.google.common.hash.Hashing;
#ManagedBean
#ViewScoped
public class HashGeneratorBean {
private List<HashDTO> hashList = new ArrayList<HashDTO>();
private HashDTO selectedRow = new HashDTO();
#PostConstruct
public void init() {
hashList.add(new HashDTO());
}
public void addRow(ActionEvent ae){
hashList.add(new HashDTO());
}
public void hash(ActionEvent ae){
for (HashDTO entry : hashList){
entry.setHashedText(generateHash(entry.getClearText()));
}
}
/**
* Hashes the given password with SHA-256
* #param password
* #return passwordHash
*/
public static String generateHash(String password) {
return Hashing.sha256().hashString(password, Charsets.UTF_8).toString();
}
public List<HashDTO> getHashList() {
return hashList;
}
public void setHashList(List<HashDTO> hashList) {
this.hashList = hashList;
}"
public HashDTO getSelectedRow() {
return selectedRow;
}
public void setSelectedRow(HashDTO selectedRow) {
this.selectedRow = selectedRow;
}
}
If I click the "debugBtn"-button the dialog popups up and shows the correct information about the row. But If I click the "addRow"-button the data in the managed-bean isn't filled correct. The selectedRow-property allways stores the last added row from the hashList-property.
I found the solution.
The PropertyActionListener is called after the ActionListener.
the Solution is to use "Action" or register the the ActionListener with and a Extended Action Listener
I have tried various different was but cannot seem to set the "selected" variable.
JavaBean:
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import javax.annotation.Resource;
import javax.inject.Named;
import javax.enterprise.context.Dependent;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.sql.DataSource;
#Named(value = "lab3")
#Dependent
#ManagedBean
#SessionScoped
public class Lab3 {
public Lab3() {
}
#Resource (name="jdbc/sample") // This is the JNDI name
private DataSource ds;
private ArrayList<Cars> c = new ArrayList<>();
public ArrayList<Cars> getC() {
// Declare the JDBC objects.
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
// Establish the connection
connection = ds.getConnection("app", "app");
// Create and execute an SQL statement that returns some data.
String SQL = "SELECT * FROM cars";
statement = connection.createStatement();
resultSet = statement.executeQuery(SQL);
// Iterate through the data in the result set and each column
while (resultSet.next()) {
c.add(new Cars(resultSet.getInt("CARID"),
resultSet.getString("CARMAKE"),
resultSet.getString("CARMODEL"),
resultSet.getInt("CARYEAR")));
}
} // Handle any errors that may have occurred.
catch (SQLException e) {
System.out.println(Arrays.toString(e.getStackTrace()));
}
finally
{
try
{
if (resultSet != null)
resultSet.close();
if (statement != null)
statement.close();
if (connection != null)
connection.close();
}
catch (Exception ex) {
System.out.println ("Exception cleaning up Database objects " +
ex.getMessage());
}
}
return c;
}
public void setC(ArrayList<Cars> c) {
this.c = c;
}
private int selected;
/**
* Get the value of selected
*
* #return the value of selected
*/
public int getSelected() {
return selected;
}
/**
* Set the value of selected
*
* #param selected new value of selected
*/
public void setSelected(int selected) {
this.selected = selected;
}
private ArrayList<Mileage> m = new ArrayList<>();
public ArrayList<Mileage> getM() {
// Declare the JDBC objects.
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
// Establish the connection
connection = ds.getConnection("app", "app");
// Create and execute an SQL statement that returns some data.
String SQL = "SELECT * FROM mileage where mileagecarid = " + selected;
statement = connection.createStatement();
resultSet = statement.executeQuery(SQL);
// Iterate through the data in the result set and each column
while (resultSet.next()) {
m.add(new Mileage(resultSet.getInt("MILEAGEID"),
resultSet.getInt("MILEAGESTART"),
resultSet.getInt("MILEAGEEND"),
resultSet.getDouble("MILEAGEGASUSED")));
}
} // Handle any errors that may have occurred.
catch (SQLException e) {
System.out.println(Arrays.toString(e.getStackTrace()));
}
finally
{
try
{
if (resultSet != null)
resultSet.close();
if (statement != null)
statement.close();
if (connection != null)
connection.close();
}
catch (Exception ex) {
System.out.println ("Exception cleaning up Database objects " +
ex.getMessage());
}
}
return m;
}
public void setM(ArrayList<Mileage> m) {
this.m = m;
}
public String results() {
return "carresults";
}
}
index.xhtml:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Lab3</title>
</h:head>
<h:body>
<h:outputStylesheet library="css" name="style.css" />
<h:form>
<h:dataTable id="dbresults" value="#{lab3.c}" var="row" >
<h:column>
<f:facet name="header" >Make</f:facet>
<h:outputText value="#{row.carmake}">
</h:outputText>
</h:column>
<h:column>
<f:facet name="header" >Model</f:facet>
<h:outputText value="#{row.carmodel}">
</h:outputText>
</h:column>
<h:column>
<f:facet name="header" >Year</f:facet>
<h:outputText value="#{row.caryear}">
</h:outputText>
</h:column>
<h:column>
<f:facet name="header" >Details</f:facet>
<h:commandButton id="submit" value="Details" action="#{lab3.results}" >
<f:setPropertyActionListener target="#{lab3.selected}" value="#{row.carid}" />
</h:commandButton>
</h:column>
</h:dataTable>
</h:form>
</h:body>
</html>
carresults.xhtml:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Lab3</title>
</h:head>
<h:body>
<h:outputStylesheet library="css" name="style.css" />
<h:outputText value="#{lab3.selected}" ></h:outputText>
<h:form>
<h:dataTable id="dbresults" value="#{lab3.m}" var="row" >
<h:column>
<f:facet name="header" >Start<br />(km)</f:facet>
<h:outputText value="#{row.mileagestart}">
</h:outputText>
</h:column>
<h:column>
<f:facet name="header" >End<br />(km)</f:facet>
<h:outputText value="#{row.mileageend}">
</h:outputText>
</h:column>
<h:column>
<f:facet name="header" >Trip<br />(km)</f:facet>
<h:outputText value="#{row.trip}">
</h:outputText>
</h:column>
<h:column>
<f:facet name="header" >Gas Used<br />(L)</f:facet>
<h:outputText value="#{row.mileagegasused}">
</h:outputText>
</h:column>
<h:column>
<f:facet name="header" >Fuel Economy<br />(L/100km)</f:facet>
<h:outputText value="#{row.litre}">
</h:outputText>
</h:column>
</h:dataTable>
</h:form>
</h:body>
</html>
I have outputted the "selected" variable on the carresults.xhtml page and it always returns zero.
first you need to correct this imports and this annotations:
import javax.inject.Named;
import javax.enterprise.context.Dependent;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#Named(value = "lab3")
#Dependent
#ManagedBean
#SessionScoped
You don't need Named and ManagedBean, yous should have one or the other. ManagedBean are bean managed by JSF, Named are beans managed by CDI.
Then you need to see what is the scope you want, maybe #Dependent is wrong for what you want. You shouldn't have #SessionScoped and #Dependent at the same time, both are scopes with different lifecycles.
Try deleting #Dependent, it has a smaller scope than #SessionScoped. If you delete #ManagedBean you need to change the import of #SessionScoped, it needs to be:
import javax.enterprise.context.SessionScoped;
This import is for CDI beans, if you choose to only have:
#Named
#SessionScoped
Try as below
<h:commandButton id="submit" value="Details" action="#{lab3.results(row.carid)}"/>
public String results(int selected) {
this.selected = selected;
return "carresults";
}
The Data that I have entered in the input text field of the prime faces data table is not displayed in the dialog box JSF file and Data is not displayed in the dialog box
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!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:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Add/Remove Row</title>
</h:head>
<body>
<h:form id="form">
<p:dataTable id="buss" value="#{busBean.mediumBusModel}" var="bus"
selection="#{busBean.selectedBus}" selectionMode="single" >
<p:column headerText="Brand" style="width:5%">
<p:inputText value="#{bus.brand}" />
</p:column>
<p:column headerText="Model" style="width:5%">
<p:inputText value="#{bus.model}" />
</p:column>
<p:column headerText="Action" style="width:10%">
<p:commandButton actionListener="#{busBean.addBus()}" icon="ui-icon-plus" update=":form" ajax="false" title="add"/>
<p:commandButton actionListener="#{busBean.removeBus(bus)}" icon="ui-icon-minus" update=":form" ajax="false" title="remove"/>
</p:column>
<f:facet name="footer">
<p:commandButton id="viewButton" value="View" icon="ui-icon-search"
update=":form:displayBus" oncomplete="PF('singleBusDialog').show()"/>
</f:facet>
</p:dataTable>
<br/>
<p:dialog id="dialog" header="Bus Detail" widgetVar="singleBusDialog" resizable="false"
showEffect="fade" hideEffect="explode">
<h:panelGrid id="displayBus" columns="2" cellpadding="4">
<h:outputText value="Brand:" />
<h:outputText value="#{bus}" style="font-weight:bold"/>
<h:outputText value="Model:" />
<h:outputText value="#{bus}" style="font-weight:bold"/>
</h:panelGrid>
</p:dialog>
</h:form>
</body>
</html>
Below is the bean class that I have used
package com.bus.bean;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import org.primefaces.event.SelectEvent;
import org.primefaces.event.UnselectEvent;
import com.bus.bean.Bus;
#ManagedBean
#SessionScoped
public class BusBean implements Serializable {
private List<Bus> busList;
private Bus selectedBus;
private BusDataModel mediumBusModel;
public BusBean() {
busList=new ArrayList<Bus>();
busList.add(new Bus("a","b"));
mediumBusModel = new BusDataModel(busList);
//populateRandomCars(cars, 50);
}
public List<Bus> getBusList()
{
return busList;
}
public void setBusList(List<Bus> busList) {
this.busList = busList;
}
public void addBus()
{
Bus newBus=new Bus();
busList.add(newBus);
}
public Bus getSelectedBus() {
return selectedBus;
}
public void setSelectedBus(Bus selectedBus) {
this.selectedBus = selectedBus;
}
public void removeBus(Bus bus)
{
busList.remove(bus);
}
public BusDataModel getMediumBusModel() {
return mediumBusModel;
}
}
-------------------------------------------------------
package com.bus.bean;
import java.util.List;
import javax.faces.model.ListDataModel;
import com.bus.bean.Bus;
import org.primefaces.model.SelectableDataModel;
public class BusDataModel extends ListDataModel<Bus> implements SelectableDataModel<Bus> {
public BusDataModel() {
}
public BusDataModel(List<Bus> data) {
super(data);
}
#Override
public Bus getRowData(String rowKey) {
//In a real app, a more efficient way like a query by rowKey should be implemented to deal with huge data
List<Bus> buss = (List<Bus>) getWrappedData();
for(Bus bus : buss) {
if(bus.getModel().equals(rowKey))
return bus;
}
return null;
}
#Override
public Object getRowKey(Bus bus) {
return bus.getBrand();
}
}
-----------------------------------------------------------------------------------------------/
package com.bus.bean;
import java.io.Serializable;
public class Bus implements Serializable
{
public String model;
public String brand;
public Bus()
{
}
public Bus(String Model,String Brand)
{
this.model = model;
this.brand = brand;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getBrand() {
System.out.println("in set:"+brand);
return brand;
}
public void setBrand(String brand) {
System.out.println("in set:"+brand);
this.brand = brand;
}
#Override
public boolean equals(Object obj) {
if(obj == null)
return false;
if(!(obj instanceof Bus))
return false;
Bus compare = (Bus) obj;
return compare.model.equals(this.model);
}
#Override
public int hashCode() {
int hash = 1;
return hash * 31 + model.hashCode();
}
#Override
public String toString() {
return "Bus{" + "model=" + model + ", brand=" + brand + '}';
}
enter code here
}
Please let me know how to get the data that I have entered in the text field of Primefaces data table to the dialog box
You should use the selected value from the datatable.
selection="#{busBean.selectedBus}"
So , in your dialog box
<h:outputText value="Brand:" />
<h:outputText value="#{busBean.selectedBus.brand}" />
Also,
<p:commandButton id="viewButton" value="View" icon="ui-icon-search"
update=":form:displayBus,:form:dialog" oncomplete="PF('singleBusDialog').show()"/>
Updating the dialog box with value of the selected row.
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!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:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Add/Remove Row</title>
</h:head>
<body>
<h:form id="form">
<p:growl id="messages" showDetail="true"/>
<p:contextMenu for="buss">
<p:menuitem value="Edit Cell" icon="ui-icon-search" onclick="PF('busTable').showCellEditor();return false; "/>
</p:contextMenu>
<p:dataTable id="buss" var="bus" value="#{busBean.busModel}" editable="true" editMode="cell" widgetVar="busTable"
selection="#{busBean.selectedBus}">
<p:ajax event="cellEdit" listener="#{busBean.onCellEdit}" update=":form:messages" />
<p:column selectionMode="single" style="width:2%" />
<p:column headerText="Brand" style="width:25%">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{bus.brand}" /></f:facet>
<f:facet name="input"><p:inputText id="brandInput" value="#{bus.brand}" style="width:96%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Model" style="width:25%">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{bus.model}" /></f:facet>
<f:facet name="input"><p:inputText id="modelInput" value="#{bus.model}" style="width:96%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Action" style="width:10%">
<p:commandButton actionListener="#{busBean.addBus()}" icon="ui-icon-plus" update=":form" ajax="false" title="add"/>
<p:commandButton actionListener="#{busBean.removeBus(bus)}" icon="ui-icon-minus" update=":form" ajax="false" title="remove"/>
</p:column>
<f:facet name="footer">
<p:commandButton id="viewButton" value="View" icon="ui-icon-search"
update=":form:buss,:form:displayBus,:form:dialog" oncomplete="PF('singleBusDialog').show()"/>
</f:facet>
</p:dataTable>
<br/>
<p:dialog id="dialog" header="Bus Detail" widgetVar="singleBusDialog" resizable="false"
showEffect="fade" hideEffect="explode">
<h:panelGrid id="displayBus" columns="2" cellpadding="4">
<h:outputText value="Brand:" />
<h:outputText value="#{busBean.selectedBus.brand}" style="font-weight:bold"/>
<h:outputText value="Model:" />
<h:outputText value="#{busBean.selectedBus.model}"/>