Setters don't get called when I use view parameters - jsf

I am using JSF 2.1.1. I have a sample JSF page that is used to post country comments. I use the f:viewparam tag to select country pages. Here is the code:
country.xhtml:
<f:metadata>
<f:viewParam name="country" value="#{countryBean2.selectedCountry}" converter="countryConverter" />
</f:metadata>
<h:head>
<title>Country</title>
</h:head>
<h:body>
<h:form id="form">
<h:outputText value="#{countryBean2.selectedCountry.countryName}" />
<br/><br/>
<h:outputText value="Comment:" />
<h:inputText value="#{countryBean2.comment}" />
<br/>
<h:commandButton value="Send">
<f:ajax listener="#{countryBean2.sendComment}" render="form" />
</h:commandButton>
</h:form>
</h:body>
CountryBean2.java:
#Named("countryBean2")
#SessionScoped
public class CountryBean2 implements Serializable {
private EntityCountry selectedCountry;
private String comment;
public EntityCountry getSelectedCountry() { return selectedCountry; }
public void setSelectedCountry(EntityCountry newValue) { selectedCountry = newValue; }
public String getComment() { return comment; }
public void setComment(String newValue) { comment = newValue; }
EntityManagerFactory emf = Persistence.createEntityManagerFactory("testPU");
public void sendComment() {
EntityManager em = emf.createEntityManager();
try {
FacesMessage msg = null;
EntityTransaction entr = em.getTransaction();
boolean committed = false;
entr.begin();
try {
EntityCountryComment c = new EntityCountryComment();
c.setCountry(selectedCountry);
c.setComment(comment);
em.persist(c);
committed = true;
msg = new FacesMessage();
msg.setSeverity(FacesMessage.SEVERITY_INFO);
msg.setSummary("Comment was sended");
} finally {
if (!committed) entr.rollback();
}
} finally {
em.close();
}
}
}
CountryConverter.java:
public class CountryConverter implements Converter {
public static EntityCountry country = new EntityCountry();
EntityManagerFactory emf = Persistence.createEntityManagerFactory("testPU");
#Override
public EntityCountry getAsObject(FacesContext context, UIComponent component, String value) {
EntityManager em = emf.createEntityManager();
Query query = em.createQuery("SELECT c FROM EntityCountry c WHERE c.countryName = :countryName")
.setParameter("countryName", value);
country = (EntityCountry) query.getSingleResult();
return country;
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
EntityCountry c = (EntityCountry) value;
return c.getCountryName();
}
}
I can open a country pages successfully (for example http://localhost:8080/test/faces/country.xhtml?country=england), but when I try to post a comment using the commandButton, the setComment setter is not called and the comment variable remains null. I tried to set immediate="true" on both inputText and commandButton, it does not work.

The execute attribute of <f:ajax> defaults to #this, the current component. If you want to submit the entire form, then you need #form instead. Use this in the render as well.
<h:commandButton value="Send">
<f:ajax execute="#form" listener="#{countryBean2.sendComment}" render="#form" />
</h:commandButton>

Related

How do I pass an attribute from composite component to backing bean by using backing component?

I have the following code in my facelet page:
<hc:rangeChooser1 id="range_chooser"
from="#{testBean.from}"
to="#{testBean.to}"
listener="#{testBean.update}"
text="#{testBean.text}">
<f:ajax event="rangeSelected"
execute="#this"
listener="#{testBean.update}"
render=":form:growl range_chooser"/>
</hc:rangeChooser1>
This is my composite component:
<ui:component xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:p="http://primefaces.org/ui">
<cc:interface componentType="rangeChooser">
<!-- Define component attributes here -->
<cc:clientBehavior name="rangeSelected" event="change" targets="hiddenValue"/>
<cc:attribute name="from" type="java.util.Calendar"/>
<cc:attribute name="to" type="java.util.Calendar"/>
<cc:attribute name="text" type="java.lang.String"/>
</cc:interface>
<cc:implementation>
<div id="#{cc.clientId}">
...
<p:inputText id="hiddenValue" value="#{cc.attrs.text}"/>
...
</div>
</cc:implementation>
</ui:component>
How do I pass attributes from, to and text from composite component to backing bean? I mean inject these values in backing component, and not through
<p:inputText id="hiddenValue" value="#{cc.attrs.text}"/>
Update: there's more correct definition what do I need: Be able to mutate objects which I pass from the backing bean to the composite component inside a backing component of the composite component. So when I perform process or execute my composite component I get the updated values.
This is my backing component:
#FacesComponent("rangeChooser")
public class RangeChooser extends UIInput implements NamingContainer {
private String text;
private Calendar from;
private Calendar to;
#Override
public void encodeBegin(FacesContext context) throws IOException{
super.encodeBegin(context);
}
public String getText() {
String text = (String)getStateHelper().get(PropertyKeys.text);
return text;
}
public void setText(String text) {
getStateHelper().put(PropertyKeys.text, text);
}
/*
same getters and setters for Calendar objects, from and to
*/
}
I just can't realize how do I move on? In general I need to take a value from <p:inputText id="hiddenValue" value="#{cc.attrs.text}"/> and convert it to two Calendars object from and to.
It will be great if somebody can point me toward right direction from here. I know that I need to use getAttributes().put(key,value) but don't know where to put this code. Thank you in advance.
Based on your comments this is what you expect.
Note that even if this implementation works, it is conceptually incorrect!
You are considering from and to as INPUTS (not input components, but input values) and text as OUTPUT. This is not the way JSF is intended to work!
However, here it is
<cc:interface componentType="rangeComponent">
<cc:attribute name="from" />
<cc:attribute name="to" />
<cc:clientBehavior name="rangeSelected" event="dateSelect" targets="from to"/>
</cc:interface>
<cc:implementation>
<div id="#{cc.clientId}">
<p:calendar id="from" value="#{cc.attrs.from}"/>
<p:calendar id="to" value="#{cc.attrs.to}"/>
</div>
</cc:implementation>
used in page:
<h:form>
<e:inputRange from="#{rangeBean.from}" to="#{rangeBean.to}" text="#{rangeBean.text}">
<p:ajax event="rangeSelected" process="#namingcontainer" update="#form:output" listener="#{rangeBean.onChange}" />
</e:inputRange>
<h:panelGrid id="output" columns="1">
<h:outputText value="#{rangeBean.from}"/>
<h:outputText value="#{rangeBean.to}"/>
<h:outputText value="#{rangeBean.text}"/>
</h:panelGrid>
</h:form>
with this backing component:
#FacesComponent("rangeComponent")
public class RangeComponent extends UINamingContainer
{
#Override
public void processUpdates(FacesContext context)
{
Objects.requireNonNull(context);
if(!isRendered())
{
return;
}
super.processUpdates(context);
try
{
Date from = (Date) getValueExpression("from").getValue(context.getELContext());
Date to = (Date) getValueExpression("to").getValue(context.getELContext());
ValueExpression ve = getValueExpression("text");
if(ve != null)
{
ve.setValue(context.getELContext(), from + " - " + to);
}
}
catch(RuntimeException e)
{
context.renderResponse();
throw e;
}
}
}
with this backing bean:
#ManagedBean
#ViewScoped
public class RangeBean implements Serializable
{
private static final long serialVersionUID = 1L;
private Date from = new Date(1000000000);
private Date to = new Date(2000000000);
private String text = "range not set";
public void onChange(SelectEvent event)
{
Messages.addGlobalInfo("[{0}] changed: [{1}]", event.getComponent().getId(), event.getObject());
}
// getters/setters
}
I rewrote the code using BalusC tecnique (and without PrimeFaces):
the form:
<h:form>
<e:inputRange value="#{rangeBean.range}">
<p:ajax event="change" process="#namingcontainer" update="#form:output"
listener="#{rangeBean.onChange}" />
</e:inputRange>
<h:panelGrid id="output" columns="1">
<h:outputText value="#{rangeBean.range}" />
</h:panelGrid>
</h:form>
the composite:
<cc:interface componentType="rangeComponent">
<cc:attribute name="value" />
<cc:clientBehavior name="change" event="change" targets="from to"/>
</cc:interface>
<cc:implementation>
<div id="#{cc.clientId}">
<h:inputText id="from" binding="#{cc.from}">
<f:convertDateTime type="date" pattern="dd/MM/yyyy" />
</h:inputText>
<h:inputText id="to" binding="#{cc.to}">
<f:convertDateTime type="date" pattern="dd/MM/yyyy" />
</h:inputText>
</div>
</cc:implementation>
the backing component:
#FacesComponent("rangeComponent")
public class RangeComponent extends UIInput implements NamingContainer
{
private UIInput from;
private UIInput to;
#Override
public String getFamily()
{
return UINamingContainer.COMPONENT_FAMILY;
}
#Override
public void encodeBegin(FacesContext context) throws IOException
{
String value = (String) getValue();
if(value != null)
{
String fromString = StringUtils.substringBefore(value, "-");
String toString = StringUtils.substringAfter(value, "-");
try
{
from.setValue(from.getConverter().getAsObject(context, from, fromString));
}
catch(Exception e)
{
from.setValue(new Date());
}
try
{
to.setValue(to.getConverter().getAsObject(context, to, toString));
}
catch(Exception e)
{
to.setValue(new Date());
}
}
super.encodeBegin(context);
}
#Override
public Object getSubmittedValue()
{
return (from.isLocalValueSet() ? from.getValue() : from.getSubmittedValue()) + "-" + (to.isLocalValueSet() ? to.getValue() : to.getSubmittedValue());
}
#Override
protected Object getConvertedValue(FacesContext context, Object submittedValue)
{
return from.getSubmittedValue() + "-" + to.getSubmittedValue();
}
public UIInput getFrom()
{
return from;
}
public void setFrom(UIInput from)
{
this.from = from;
}
public UIInput getTo()
{
return to;
}
public void setTo(UIInput to)
{
this.to = to;
}
}
and the managed bean:
#ManagedBean
#ViewScoped
public class RangeBean implements Serializable
{
private static final long serialVersionUID = 1L;
private String range = "01/01/2015-31/12/2015";
public void onChange(AjaxBehaviorEvent event)
{
Messages.addGlobalInfo("[{0}] changed: [{1}]", event.getComponent().getId(), event.getBehavior());
}
public String getRange()
{
return range;
}
public void setRange(String range)
{
this.range = range;
}
}
Note that managed bean only retains range property for get/set. From and to are gone, the backing component derives and rebuilds them itself.

How to send values to a list in a backing bean and display as a dataTable

I'm still learning how to use Facelets and I am trying to send inputted values from a JSF page to a list in a ManagedBean and then display that information in a dataTable. I have JSF page to enter in the data, a backing bean to manage the list, and a regular application for the normal objects. I can't figure out how to send the input value from the JSF to the backing bean, however.
Here is my view:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Guestbook Form</title>
</h:head>
<h:body>
<h:form>
<h1>Guestbook Application Form</h1>
<p>Please fill out all entries and click the Submit button</p>
<h:panelGrid columns="3">
<h:outputText value = "Name: "></h:outputText>
<h:inputText id="nameInputText" required ="true"
requiredMessage="Please enter your name"
value = "#{guestbookBean.name}"
validatorMessage="Name must be fewer than 20
characters">
<f:validateLength maximum="20"/>
</h:inputText>
<h:message for="nameInputText" styleClass="error"/>
<h:outputText value = "Email: "></h:outputText>
<h:inputText id="emailInputText" required ="true"
requiredMessage="Please enter your email address"
value="#{guestbookBean.email}"
validatorMessage="Invalid email address format">
<f:validateRegex pattern ="\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*"/>
</h:inputText>
<h:message for="emailInputText" styleClass="error"/>
<h:outputText value = "Enter a message: "></h:outputText>
<h:inputTextarea id="messageInputText" required ="true"
requiredMessage="Please enter a message"
value="#{guestbookBean.message}"
validatorMessage="Message must be fewer than 140 characters">
<f:validateLength maximum="140"/>
</h:inputTextarea>
<h:message for="messageInputText" styleClass="error"/>
</h:panelGrid>
<h:commandButton value="Submit" type ="Submit" action ="#{guestbookBean.setList()}"/>
<h:commandButton value ="Reset Form" type ="reset"/>
<h:outputText escape="false" value ="#{guestbookBean.result}"/>
<h:dataTable value="#{guestbookBean.list}" var="guests"
styleClass="table" cellpadding="5" cellspacing="1" border="2">
<h:column>
<f:facet name ="header">Name</f:facet>
#{guests.name}
</h:column>
<h:column>
<f:facet name ="header">Email</f:facet>
#{guests.email}
</h:column>
<h:column>
<f:facet name ="header">Message</f:facet>
#{guests.message}
</h:column>
</h:dataTable>
</h:form>
</h:body>
</html>
Here is my backing bean:
package guestbook;
import java.util.List;
import java.util.ArrayList;
import java.io.Serializable;
import javax.enterprise.context.Dependent;
import javax.faces.bean.*;
#ManagedBean(name = "guestbookBean")
public class GuestbookBean implements Serializable{
private String na;
private String em;
private String m;
private List<GuestbookEntry> bookList = new ArrayList<>();
//Set name
public void setName(String first)
{
this.na = first;
}
//Set email
public void setEmail(String mail)
{
this.em = mail;
}
//Set message
public void setMessage(String msg)
{
this.m = msg;
}
//Return the name
public String getName()
{
return na;
}
//Return the email
public String getEmail()
{
return em;
}
//Return the message
public String getMessage()
{
return m;
}
public void setList()
{
GuestbookEntry bk = new GuestbookEntry();
bk.setName(na);
bk.setEmail(em);
bk.setMessage(m);
bookList.add(0, bk);
}
public List<GuestbookEntry> getList()
{
return bookList;
}
// returns result for rendering on the client
public String getResult()
{
if ( !bookList.isEmpty())
{
return "<p style=\"background-color:yellow;width:200px;" +
"padding:5px\">Data submitted successfully"+ "</p>";
}
else
{
return ""; // request has not yet been made
}
} // end method getResult
}
Here is my model:
package guestbook;
public class GuestbookEntry {
private String firstName;
private String lastName;
private String email;
private String message;
public void setFirstName(String fn)
{
firstName = fn;
}
public void setLastName(String ln)
{
lastName = ln;
}
public void setEmail(String em)
{
email = em;
}
public void setMessage(String m)
{
message = m;
}
public String getFirstName()
{
return firstName;
}
public String getLastName()
{
return lastName;
}
public String getEmail()
{
return email;
}
public String getMessage()
{
return message;
}
}
The data is not being reset because you are not clearing the fields after the submit
You can set to null na, em and m to reset the fields
Regarding the table, try adding #ViewScoped to your bean, the default scope is RequestScope, which is not keeping your table

Send p:autoComplete value as a param in JSF

i have a rare situation in my page i have a "p:autoComplete" which is bind to a backing bean i can read that auto complete item form the backing bean.
but the problem is the selected value from that auto complete need to be passed as a parameter, when user pressed the button, with some other parameters. which i really don't know how to do it?
this is my page which has the autocomplete
<p:panel header="Employee sales" style="width:500px"
toggleable="true" toggleSpeed="500" closeSpeed="500">
<p:autoComplete id="user_auto_complete"
value="#{salesReportMainController.userFromAutoComplete}"
completeMethod="#{salesReportMainController.completeUser}"
var="user" itemLabel="#{user.userName}" itemValue="#{user}"
converter="#{userConverter}" forceSelection="true" />
<p:commandButton id="Search" value="Generate"
action="admin_common_barchart">
<f:param name="todaysDate"
value="#{salesReportMainController.todaysDate}" />
<f:param name="beforDate"
value="#{salesReportMainController.dateBeforOneYear}" />
<f:param name="employeeName"
value="#{salesReportMainController.userFromAutoComplete.userName}" />
</p:commandButton>
</p:panel>
and this is the backing bean that binds to that page
#ViewScoped
public class SalesReportMainController implements Serializable{
private static final long serialVersionUID = 1L;
#ManagedProperty(value = "#{userService}")
public UserService userService;
public DateTime todaysDate;
public DateTime dateBeforOneYear;
public DateTime dateBeforsixMonths;
public List<User> allUsers;
public List<User> acFilterdUsers;
public User userFromAutoComplete;
#PostConstruct
public void init(){
int oneYear = ConstantConfiguration.YearsInMonths.ONE_YEAR.getValue();
int sixMonths = ConstantConfiguration.YearsInMonths.SIX_MONTH.getValue();
todaysDate = new DateTime();
dateBeforOneYear = new DateTime(todaysDate).minusMonths(oneYear);
dateBeforsixMonths = new DateTime(todaysDate).minusMonths(sixMonths);
}
// public String buttonClick(){
// System.out.println("aaaaaaaa");
// return null;
// }
public List<User> completeUser(String query) {
allUsers = userService.getAllUsers();
acFilterdUsers = new ArrayList<User>();
for (User user : allUsers) {
if(user.getUserName().toLowerCase().startsWith(query)){
acFilterdUsers.add(user);
}
}
return acFilterdUsers;
}
public String getAutoCompleteUser() {
if (userFromAutoComplete != null) {
//i can get the value of the selected item form auto complete
}
return null;
}
//getters and setters
}
and this is the page that i want to load
<h:form id="common_chart_form" prependId="flase">
<p:growl id="growl" showDetail="true" autoUpdate="true"
sticky="false" />
<p:outputLabel id="labelvalue" value="aaaaaaaaaa"/>
<p:chart id="chart" type="bar"
model="#{commonChartController.barModel}" style="height:600px" />
<p:commandButton value="Print" type="button" icon="ui-icon-print">
<p:printer target="chart" />
</p:commandButton>
<p:commandButton value="Back" action="admin_sales_reports" />
</h:form>
and this the backing bean of the above page
#Component
#ManagedBean
#RequestScoped
public class CommonChartController implements Serializable{
private static final long serialVersionUID = 1L;
#ManagedProperty(value = "#{orderService}")
public OrderService orderService;
#ManagedProperty(value = "#{userService}")
public UserService userService;
List<MonthSales> salesList;
private BarChartModel barModel;
#PostConstruct
public void init() {
String dateTo = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("todaysDate");
String dateFrom = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("beforDate");
String employeeName = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("employeeName");
System.out.println("user Name : "+employeeName);
if(employeeName != null && !employeeName.equals("")){
User user = userService.getUserByUserName("admin");
salesList = orderService.getMonthlySalesByUserName(UserUtility.stringDateToJodaDateTime(dateFrom).toDate(), UserUtility.stringDateToJodaDateTime(dateTo).toDate(), user);
createBarModel(salesList, user);
}else {
salesList = orderService.getMonthlySales(UserUtility.stringDateToJodaDateTime(dateFrom).toDate(), UserUtility.stringDateToJodaDateTime(dateTo).toDate());
createBarModel(salesList);
}
//
// salesList = orderService.getMonthlySales(UserUtility.stringDateToJodaDateTime(dateFrom).toDate(), UserUtility.stringDateToJodaDateTime(dateTo).toDate());
// createBarModel(salesList);
}
}
i can read the "dateTo" param and "dateFrom" param. problem is "employeeName" param is alwayas null

JSF/Primefaces issue when form field rendering depends on selectOneMenu

Form field rendering is depending on selected item in selectOneMenu.
Page:
<h:body>
<f:view>
<h:form>
<h:panelGrid>
<p:inputText value="#{user.username}"/>
<p:selectOneMenu value="#{user.moreInputs}"
required="true">
<p:ajax event="change"
update="moreInputGrid"/>
<f:selectItem itemLabel="" itemValue=""/>
<f:selectItems value="#{user.selectItems}"/>
</p:selectOneMenu>
</h:panelGrid>
<h:panelGrid id="moreInputGrid">
<p:inputText rendered="#{user.renderMoreInputs}"
value="#{user.name}"/>
</h:panelGrid>
<p:commandButton action="#{user.register}"
value="Register user"/>
</h:form>
</f:view>
</h:body>
Backing bean:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.model.SelectItem;
#ManagedBean
#ViewScoped
public class User {
private String username;
private MoreInputs moreInputs;
private String name;
public enum MoreInputs {
YES,
NO
}
public boolean isRenderMoreInputs() {
return (moreInputs == MoreInputs.YES);
}
public SelectItem[] getSelectItems() {
SelectItem[] items = new SelectItem[2];
items[0] = new SelectItem(
MoreInputs.YES,
"yes");
items[1] = new SelectItem(
MoreInputs.NO,
"no");
return items;
}
public String register() {
return null;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public MoreInputs getMoreInputs() {
return moreInputs;
}
public void setMoreInputs(MoreInputs moreInputs) {
this.moreInputs = moreInputs;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Issue arrises if the client does page refresh after choosing an item causing form fields to render. Such form fields will not be rendered on page refresh, although they should. Plus, if client then tries to submit form, validation is skipped for those hidden fields and form is successfully processed.
Am I doing something wrong? Is there an elegant solution?

change the datatable outputText to inputText when clicked on Edit Button

I m trying to display data in jsf datable data from the database,ans in a same row i m displaying link for Edit. Now when user will clicked on edit button then it should be inputText from outputText. Here i have done coding for that but i can't change the textbox can u please help me? Thanks in advance.
ShowData.xhtml
<h:dataTable value="#{customerdata.customerList}" var="c"
styleClass="order-table" binding="#{customerdata.dataTable}"
headerClass="order-table-header" border="1" width="100%"
rowClasses="order-table-odd-row,order-table-even-row" rows="3">
<h:column>
<h:selectBooleanCheckbox></h:selectBooleanCheckbox>
</h:column>
<h:column>
<f:facet name="heder">User ID</f:facet>
<h:inputText value="#{c.cust_id}" size="10" rendered="#{c.editable}"/>
<h:outputLabel value="#{c.cust_id}" rendered="#{not c.editable}" />
</h:column>
<h:column>
<f:facet name="heder">User Name</f:facet>
<h:inputText value="#{c.cust_name}" size="10" rendered="#{c.editable}"/>
<h:outputLabel value="#{c.cust_name}" rendered="#{not c.editable}" />
</h:column>
<h:column>
<h:commandLink value="Update" rendered="#{c.editable}" action="#{customerdata.editAction(c)}" />
<h:commandLink value="Edit" action="#{customerdata.editAction(c)}" rendered="#{not c.editable}"/>
</h:column>
<h:column>
<h:commandLink value="Delete" action="#{customerdata.deleteAction(c)}" />
</h:column>
<!-- Footer Setting -->
<f:facet name="footer">
<h:panelGroup>
<h:commandButton value="prev" action="#{customerdata.pagePrevious}"
disabled="#{customerdata.dataTable.first == 0}" />
<h:commandButton value="next" action="#{customerdata.pageNext}"
disabled="#{customerdata.dataTable.first + customerdata.dataTable.rows
>= customerdata.dataTable.rowCount}" />
</h:panelGroup>
</f:facet>
</h:dataTable>
CustomerData.java
package model;
#ManagedBean(name="customerdata")
public class CustomerData implements Serializable {
private static final long serialVersionUID = 1L;
Connection con;
Statement smt;
HtmlDataTable dataTable;
//Customer cust=new Customer();
public List<Customer> getcustomerList() throws SQLException{
//System.out.println("in getcustomerlist");
List<Customer> list= new ArrayList<Customer>();
try{
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/openid","root","root");
smt = con.createStatement();
String query="select * from jsftable";
ResultSet rs= smt.executeQuery(query);
while(rs.next()){
Customer cust = new Customer();
cust.setCust_id(rs.getInt("cust_id"));
cust.setCust_name(rs.getString("cust_name"));
cust.setHas_attachment(rs.getBoolean("has_attachment"));
System.out.println("in cusotomer data"+cust.isEditable());
//store all data into a List
list.add(cust);
}
}
catch(Exception e){
e.printStackTrace();
}
return list;
}
public void pageFirst() {
dataTable.setFirst(0);
}
public void pagePrevious() {
dataTable.setFirst(dataTable.getFirst() - dataTable.getRows());
System.out.println("Prevoius"+dataTable.getFirst());
}
public void pageNext() {
dataTable.setFirst(dataTable.getFirst() + dataTable.getRows());
System.out.println("Next"+dataTable.getFirst());
}
public void pageLast() {
int count = dataTable.getRowCount();
int rows = dataTable.getRows();
dataTable.setFirst(count - ((count % rows != 0) ? count % rows : rows));
}
public HtmlDataTable getdataTable() {
return dataTable;
}
public void setdataTable(HtmlDataTable dataTable) {
this.dataTable = dataTable;
}
public void showRow(){
System.out.println(dataTable.getRows());
}
public String deleteAction(Customer customer) throws SQLException{
//list.remove(customer);
//System.out.println(customer.cust_id);
try{
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/openid","root","root");
smt = con.createStatement();
String query="delete from jsftable where cust_id="+customer.cust_id+"";
//ResultSet rs= smt.executeQuery(query);
smt.executeUpdate(query);
}
catch(Exception e){
e.printStackTrace();
}
return null;
}
public String editAction(Customer customer) {
//list.remove(customer);
System.out.println(customer.cust_id);
customer.setEditable(true);
return null;
}
}
Customer.java
public class Customer {
int cust_id;
String cust_name;
boolean has_attachment;
boolean editable;
String edit_value;
public String getEdit_value() {
System.out.println("in getter");
return edit_value;
}
public void setEdit_value(String editvalue) {
this.edit_value = editvalue;
}
public boolean isHas_attachment() {
System.out.println("in getter of has_attach");
return has_attachment;
}
public void setHas_attachment(boolean hasAttachment) {
has_attachment = hasAttachment;
}
public int getCust_id() {
System.out.println("in getter of cust_id");
return cust_id;
}
public void setCust_id(int custId) {
cust_id = custId;
}
public String getCust_name() {
return cust_name;
}
public void setCust_name(String custName) {
cust_name = custName;
}
public boolean isEditable() {
//System.out.println("in isEditable"+editable);
return editable;
}
public void setEditable(boolean editable) {
this.editable = editable;
//System.out.println("in set editable"+editable);
}
}
To be honest, I wonder how your code works at all. It has several major flaws.
You should start with
giving your managed bean a scope, the #ViewScoped seems the most appropriate (see here)
removing the database access from the getter method. Put it inside an #PostConstruct annotated method in your bean. Getter methods can be called several times during JSF lifecycle. The #PostConstruct method only after bean construction.
closing sql statement and connection when you are done (stmt.close() and con.close())
following bean field and method naming conventions: A private field xxx has a getter getXxx and a setter setXxx (the capitalization is important)
removing datatable binding. It is not necessary here.
I recommend to go through this simple CRUD example by BalusC and adapting it for your functional requirements.
Add id tag for datatable:
<h:dataTable value="#{customerdata.customerList}" var="c" id="customerDT"
styleClass="order-table" binding="#{customerdata.dataTable}"
headerClass="order-table-header" border="1" width="100%"
rowClasses="order-table-odd-row,order-table-even-row" rows="3">
Add in your edit CommandButton update tag:
But why you don't use the inplace component using primefaces? http://www.primefaces.org/showcase-labs/ui/inplace.jsf (need a save button)

Resources