My form is working if editable is set to true but not when it's false. When false the submit action method is not even called. I need it to be false (not editable so I can store the correct value in db).
This is the menu I added.
<tr><td>
<h:outputLabel for="country">#{registering.Country}: </h:outputLabel></td>
<td><p:selectOneMenu editable="false" id="country" required="true" requiredMessage="Required" value="#{subscribeUser.user.countryBean}" converter="#{countriesConverter}" effect="fold" >
<f:selectItem itemValue="#{null}" itemLabel="#{registering.SelectCountry}" />
<f:selectItems value="#{countriesConverter.countries}" var="country" itemLabel="#{country.shortName}" itemValue="#{country}" />
</p:selectOneMenu></td><td></td><td>
<span class="error"><h:message id="countryMessage" for="country"/></span></td>
</tr>
Notice that the select one menu has editable="false" it doesn't work in that case. But if I put editable="true" it works.
here is the full form, last 2 fields are problematic:
<h:form>
<table class="registration">
<!-- username -->
<tr><td>
<h:outputLabel for="username">#{registering.Username}: </h:outputLabel></td><td>
<p:inputText id="username" value="#{subscribeUser.user.username}"
validator="#{usernameValidator.validate}" maxlength="#{values.small}">
<f:passThroughAttribute name="required" value="true"/>
<f:ajax event="blur" render="usernameCheck usernameMessage submit"></f:ajax>
</p:inputText></td><td>
<h:panelGroup id="usernameCheck">
<h:graphicImage library="images/icons" name="failed_indicator.png" rendered="#{usernameValidator.isIndicatorVisible.usernameFailed}"></h:graphicImage>
<h:graphicImage library="images/icons" name="success_indicator.png" rendered="#{usernameValidator.isIndicatorVisible.usernameSuccess}"></h:graphicImage>
</h:panelGroup></td><td>
<span class="error"><h:message id="usernameMessage" for="username"/></span></td>
</tr>
<!-- password -->
<tr><td>
<h:outputLabel for="password">#{registering.Password}: </h:outputLabel></td><td>
<p:password id="password" value="#{subscribeUser.userCredential.password}" feedback="true"
promptLabel="#{registering.PleaseEnterPass}" weakLabel="#{registering.Weak}"
goodLabel="#{registering.Good}" strongLabel="#{registering.Strong}"
requiredMessage="#{registering.reqPassword}"
validator="#{passwordValidator.validate}">
<f:passThroughAttribute name="required" value="true"/>
<f:attribute name="confirm" value="#{confirmPassword}" />
<f:passThroughAttribute name="required" value="true"/>
<f:ajax event="blur" execute="password confirmPassword" render="passwordMessage passwordCheck confpasswordCheck submit"></f:ajax>
</p:password></td><td>
<h:panelGroup id="passwordCheck">
<h:graphicImage library="images/icons" name="failed_indicator.png" rendered="#{passwordValidator.isIndicatorVisible.passwordFailed}"></h:graphicImage>
<h:graphicImage library="images/icons" name="success_indicator.png" rendered="#{passwordValidator.isIndicatorVisible.passwordSuccess}"></h:graphicImage>
</h:panelGroup>
</td><td>
<span class="error"><h:message id="passwordMessage" for="password"/></span></td>
</tr>
<!-- Confirm password -->
<tr><td>
<h:outputLabel for="confirmPassword" value="#{registering.ConfirmPass}: "/></td><td>
<p:password id="confirmPassword" required="true"
requiredMessage="#{registering.PleaseConfirmPassword}"
binding="#{confirmPassword}">
<f:passThroughAttribute name="required" value="true"/>
<f:ajax event="blur" execute="password confirmPassword" render="passwordMessage passwordCheck confpasswordCheck submit"></f:ajax>
</p:password> </td><td>
<h:panelGroup id="confpasswordCheck">
<h:graphicImage library="images/icons" name="failed_indicator.png" rendered="#{passwordValidator.isIndicatorVisible.passwordFailed}"></h:graphicImage>
<h:graphicImage library="images/icons" name="success_indicator.png" rendered="#{passwordValidator.isIndicatorVisible.passwordSuccess}"></h:graphicImage>
</h:panelGroup>
</td><td>
<span class="error"><h:message id="passwordConfMessage" for="confirmPassword" /></span></td>
</tr>
<!-- Email -->
<tr><td>
<h:outputLabel for="email">#{registering.Email}: </h:outputLabel></td><td>
<p:inputText id="email" required="true" value="#{subscribeUser.user.email}"
validator="#{emailValidator.validate}"
requiredMessage="#{registering.reqEmail}">
<f:passThroughAttribute name="required" value="true"/>
<f:passThroughAttribute name="type" value="email"/>
<f:passThroughAttribute name="maxlength" value="100"/>
<f:ajax event="blur" render="emailCheck emailMessage submit"></f:ajax>
</p:inputText></td><td>
<h:panelGroup id="emailCheck">
<h:graphicImage library="images/icons" name="failed_indicator.png" rendered="#{emailValidator.isIndicatorVisible.emailFailed}"></h:graphicImage>
<h:graphicImage library="images/icons" name="success_indicator.png" rendered="#{emailValidator.isIndicatorVisible.emailSuccess}"></h:graphicImage>
</h:panelGroup> </td><td>
<span class="error"><h:message id="emailMessage" for="email"/></span></td>
</tr>
<!-- Country -->
<tr><td>
<h:outputLabel for="country">#{registering.Country}: </h:outputLabel></td>
<td colspan="3"><p:selectOneMenu required="true" editable="true" id="country" value="#{subscribeUser.user.countryBean}" converter="#{countriesConverter}" effect="fold">
<f:selectItems value="#{countriesConverter.countries}" var="country" itemLabel="#{country.shortName}" itemValue="#{country}" />
</p:selectOneMenu></td>
</tr>
<!-- Timezone -->
<tr><td>
<h:outputLabel for="timezone">#{registering.Timezone}: </h:outputLabel></td>
<td colspan="3">
<p:selectOneMenu id="timezone" editable="true" required="true" value="#{subscribeUser.user.timezoneOffset}" converter="#{timezonesConverter}" effect="fold" >
<f:selectItems value="#{timezonesConverter.timezonesList}" var="timezone" itemLabel="#{timezone.name}" itemValue="#{timezone}" />
</p:selectOneMenu></td>
</tr>
</table>
<div class="areYouARobot" ><div class="captchaLabel">#{registering.AreYouARobot}</div>
<!-- <div class="g-recaptcha" data-sitekey="6LdFTgcTAAAAAHQeLLEKPE-of2si0GrwuZXoEAHb"></div> --></div>
<div class="submit">
<p:commandButton value="#{registering.Submit}" id="submit" action="#{subscribeUser.inscrireUser}" icon="ui-icon-disk"
disabled="#{!(usernameValidator.ok and passwordValidator.ok and emailValidator.ok)}" >
</p:commandButton></div>
</h:form>
Here is the country converter:
#ManagedBean
public class CountriesConverter implements Converter {
private List<Country> countries;
private List<String> countriesStr;
private List<Integer> countriesId;
private Country country;
#EJB
private CountriesService cs;
#PostConstruct
public void init() {
this.countries = cs.getAllCountries();
this.countriesStr = new ArrayList<String>();
this.countriesId = new ArrayList<Integer>();
for (Country c : countries) {
this.countriesStr.add(c.getShortName());
}
for (Country c : countries) {
this.countriesId.add(c.getIdCountry());
}
}
#Override
public Country getAsObject(FacesContext ctx, UIComponent component,
String submittedValue) {
if (submittedValue == null || submittedValue.isEmpty()) {
return null;
}
try {
return cs.findByName(submittedValue);
} catch (Exception e) {
return null;
}
}
#Override
public String getAsString(FacesContext fc, UIComponent uic,
Object modelValue) {
Country datCountry = (Country) modelValue;
if (datCountry == null) {
return "";
}
else if (datCountry instanceof Country) {
return datCountry.getShortName();
} else {
return null;
}
}
//get&sets
}
The country entity:
#Entity
#Table(name="countries")
#NamedQuery(name="Country.findAll", query="SELECT c FROM Country c")
public class Country implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private int idCountry;
#Column(name="calling_code")
private String callingCode;
private String cctld;
private String iso2;
private String iso3;
#Column(name="long_name")
private String longName;
private String numcode;
#Column(name="short_name")
private String shortName;
#Column(name="un_member")
private String unMember;
//bi-directional many-to-one association to User
#OneToMany(mappedBy="countryBean")
private List<User> users;
public Country() {
}
//getter & setters
}
My timezone converter:
#ManagedBean
public class TimezonesConverter implements Converter {
private List<Timezone> timezonesList;
private Map<String, Timezone> myMap;
private static final String[] timezonesStr = {
"(GMT -12:00) Eniwetok, Kwajalein",
"etcetera" };
public TimezonesConverter() {
timezonesList = new ArrayList<Timezone>();
myMap = new TreeMap<String, Timezone>();
int offset = -720;
for (String s : timezonesStr) {
Timezone timezone = new Timezone(s, offset);
timezonesList.add(timezone);
myMap.put(s, timezone);
offset += 60;
}
}
#Override
public Object getAsObject(FacesContext arg0, UIComponent arg1,
String submittedValue) {
if (submittedValue == null || submittedValue.isEmpty()) {
return null;
}
try {
return myMap.get(submittedValue);
} catch (Exception e) {
return null;
}
}
#Override
public String getAsString(FacesContext arg0, UIComponent arg1,
Object modelValue) {
// casting error here.
Timezone timezone = (Timezone) modelValue;
if (timezone == null) {
return "";
} else if (timezone instanceof Timezone) {
return timezone.getName();
} else {
return null;
}
}
//getters
}
Timezone class:
public class Timezone {
private String name;
private int offset;
public Timezone(String name, int offset) {
this.name = name;
this.value = offset;
}
//getters and setters
}
I commented the timezone thing but when uncommented it gives me this error, which makes no sens to me since the var I put in the timezone menu is a timezone object:
java.lang.ClassCastException: java.lang.Integer cannot be cast to main.java.utils.Timezone
at main.java.converters.TimezonesConverter.getAsString(TimezonesConverter.java:82)
I did a workaround for this but I'm unhappy with it:
#Override
public String getAsString(FacesContext arg0, UIComponent arg1,
Object modelValue) {
int offset = (int) modelValue;
if (modelValue == null) {
return "";
} else {
for (Timezone tz : timezonesList) {
if (tz.getOffset() == offset) {
return tz.getName();
}
}
}
return null;
}
and I switched the value in the form to :
<f:selectItems value="#{timezonesConverter.timezonesList}" var="timezone" itemLabel="#{timezone.name}" itemValue="#{timezone.offset}" />
So instead of the value being a Timezone object (that x reason was considered as an Integer and caused the cast exception), it is the int variable inside the Timezone object that is taken, and that works.
the user entity:
#Entity
#Table(name="users")
#NamedQuery(name="User.findAll", query="SELECT u FROM User u")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private String username;
private String email;
#Column(name="is_enabled")
private int isEnabled;
#Temporal(TemporalType.DATE)
#Column(name="member_since")
private Date memberSince;
#Column(name="profile_pic")
private String profilePic;
private int reputation;
private String role;
private String status;
private int timezoneOffset;
#Column(name="warning_lvl")
private int warningLvl;
private String xxx;
//bi-directional many-to-one association to Friend
#OneToMany(mappedBy="user1")
private List<Friend> friends1;
//bi-directional many-to-one association to Friend
#OneToMany(mappedBy="user2")
private List<Friend> friends2;
//bi-directional many-to-one association to Message
#OneToMany(mappedBy="user1")
private List<Message> messages1;
//bi-directional many-to-one association to Message
#OneToMany(mappedBy="user2")
private List<Message> messages2;
//bi-directional many-to-one association to Thethread
#OneToMany(mappedBy="user1")
private List<Thethread> thethreads1;
//bi-directional many-to-one association to Thethread
#OneToMany(mappedBy="user2")
private List<Thethread> thethreads2;
//bi-directional many-to-one association to Usercfg
#OneToMany(mappedBy="user")
private List<Usercfg> usercfgs;
//bi-directional many-to-one association to Userinfo
#OneToMany(mappedBy="user")
private List<Userinfo> userinfos;
//bi-directional many-to-one association to Country
#ManyToOne
#JoinColumn(name="country")
private Country countryBean;
public User() {
}
// getters & setters
}
The reason why method is not called is, that conversion of values fails.
Country field
CountriesConverter method getAsObject should have return type Object, I expect it's not called at all now.
Country class must implement the equals and hashCode methods.
Timezone field
The timezoneOffset property of the User class must be instance of the Timezone class.
OR
Keep the timezoneOffset int, remove the converter and set the int value using the itemValue attribute. See the example:
<p:selectOneMenu id="timezone" editable="true" required="true"
value="#{subscribeUser.user.timezoneOffset}" effect="fold" >
<f:selectItems value="#{timezonesConverter.timezonesList}" var="timezone"
itemLabel="#{timezone.name}" itemValue="#{timezone.offset}" />
</p:selectOneMenu>
Related
I do not why although I verify everything which is right. Anyone know?
I tried to debug:
- getAsString() return ID (that's right)
- when I submitted - getAsObject() always throw exception because the label values was always passed instead of ID values.
My code as below:
my xhtml file:
<div class="ui-grid-row" style="margin-top: 5px; margin-bottom: 5px;">
<div class="ui-grid-col-2 pdt4">
<p:outputLabel for="txtApprovalScheduler"
value="#{lang['workforce.category.parttimeManagement.approved.scheduler']}"/>
</div>
<div class="ui-grid-col-2">
<p:selectOneMenu value="#{parttimeController.selectedAgentDTO}"
id="txtApprovalScheduler"
filterMatchMode="contains" editable="true"
style="width: 86%;"
required="true"
requiredMessage="#{lang['workforce.category.parttimeManagement.approved.scheduler.missing']}">
<f:converter converterId="agentConverter"/>
<f:selectItem itemValue="" itemLabel="#{lang['wf.common.choose']}"/>
<f:selectItems value="#{parttimeController.agentDTOs}" var="agentItem1"
itemLabel="#{agentItem1.userName}"
itemValue="#{agentItem1}"/>
</p:selectOneMenu>
</div>
<div class="ui-grid-col-2 pdt4">
<p:outputLabel for="txtApprovalRegister"
value="#{lang['workforce.category.parttimeManagement.approved.register']}"/>
</div>
<div class="ui-grid-col-2">
<p:selectOneMenu value="#{parttimeController.selectedAgentDTOForRegister}"
id="txtApprovalRegister" editable="true"
filterMatchMode="contains" style="width: 86%; font-size: 12px !important;"
required="true"
requiredMessage="#{lang['workforce.category.parttimeManagement.approved.register.missing']}">
<f:converter converterId="agentConverter"/>
<f:selectItem itemValue="" itemLabel="#{lang['wf.common.choose']}"/>
<f:selectItems value="#{parttimeController.agentDTOs}" var="item1"
itemLabel="#{item1.userName}"
itemValue="#{item1}"/>
</p:selectOneMenu>
</div>
</div>
My Converter:
#FacesConverter(forClass = AgentDTO.class,value = "agentConverter")
public class AgentConverter implements Converter {
public static List<AgentDTO> listAgentDTOs;
#Override
public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String agentId) {
if (agentId.trim().equals("")) {
return null;
} else {
try {
Long number = Long.parseLong(agentId);
for (AgentDTO a : listAgentDTOs) {
if (a.getAgentId() == number) {
return a;
}
}
} catch (NumberFormatException exception) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Conversion Error", "Not a valid data"));
}
}
return null;
}
#Override
public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object value) {
if (value == null || value.equals("") || "-1".equals(value)) {
return "";
} else {
String result = String.valueOf(((AgentDTO) value).getAgentId());
return result;
}
}
}
My bean:
#Component
#Scope("view")
#ManagedBean(name = "parttimeController")
public class ParttimeController extends BaseController implements Serializable {
private AgentDTO selectedAgentDTO;
private AgentDTO selectedAgentDTOForRegister;
private List<AgentDTO> agentDTOs;
.... getter/setter and initiallize AgentCenvert.listAgentDTOs
My class:
public class AgentDTO{
private Long agentId;
private String userName;
....getter/setter
}
I found out the reason - I only remove editable attribute in selectOneMenu. So getAsObject() will pass a value instead of a label
The functionality I need is as follows:
I have a datatable with 4 columns(already works well, for the purpose of explanation I provided just one column "Price") and in the last column I have a "modify" icon. When I click on "modify" icon I would like inputText to pop-up where I can do my modifications for each column in the row.
From technical perspective I'm doing it:
In JSF:
<h:dataTable value="#{item.getItemList()}" var="c"
styleClass="order-table"
headerClass="order-table-header"
rowClasses="order-table-odd-row,order-table-even-row">
<h:column>
<f:facet name="header"> Price </f:facet>
<h:inputText value="#{c.price}" size="5" rendered="#{c.editable}" />
<h:outputText value="#{c.price}" rendered="#{not c.editable}" />
</h:column>
<h:column>
<f:facet name="header"> Operation </f:facet>
<h:form>
<h:commandLink action="#{item.editAction(c)}">
<h:graphicImage library="images"
name="modifyIcon.png"
width="20"
rendered="#{not c.editable}"/>
</h:commandLink>
</h:form>
<h:form>
<h:commandLink action="#{item.removeItem(c)}">
<h:graphicImage value="resources/images/deleteIcon.png" width="20" />
</h:commandLink>
</h:form>
</h:column>
</h:dataTable>
In bean:
public String editAction(Item item) {
item.setEditable(true);
return null;
}
and in Item class:
public boolean isEditable() {
return this.editable;
}
public void setEditable(boolean editable) {
this.editable = editable;
}
Then when I click on modifyIcon.png nothing happends. I would expect input fields from the other columns to show up, but they don't. Do you have any idea where I could made a mistake?
since you don't show us where and how you load the list of items, we cannot give you one absolute answer. but here is a working example:
import java.io.Serializable;
public class TestItem implements Serializable{
private static final long serialVersionUID = -2725423502616632442L;
private int id;
private double price;
private boolean editable;
public TestItem(int id, double price, boolean editable) {
super();
this.id = id;
this.price = price;
this.editable = editable;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public boolean isEditable() {
return editable;
}
public void setEditable(boolean editable) {
this.editable = editable;
}
}
Controller:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean(name="testBean")
#SessionScoped
public class Test implements Serializable{
private static final long serialVersionUID = 2010307013874058143L;
private List<TestItem> items;
public Test(){
}
#PostConstruct
public void init(){
items = new ArrayList<TestItem>();
items.add(new TestItem(0,20.99,false));
items.add(new TestItem(1,30.90,false));
items.add(new TestItem(2,23.00,false));
items.add(new TestItem(3,15.50,false));
}
public final String setEditable(TestItem selectedItem){
selectedItem.setEditable(true);
return null;// null or your view-id
}
public final String save(){
for(TestItem i: this.getItems()){
System.out.println(i.getPrice());
i.setEditable(false);
}
return null;// null or your view-id
}
public List<TestItem> getItems() {
return items;
}
public void setItems(List<TestItem> items) {
this.items = items;
}
}
xhtml:
<h:form>
<h:dataTable id="DATA-TABLE" var="c" value="#{testBean.items}">
<h:column>
<f:facet name="header"> Name </f:facet>
<h:inputText value="#{c.price}" size="5" rendered="#{c.editable}" />
<h:outputText value="#{c.price}" rendered="#{not c.editable}" />
</h:column>
<h:column>
<f:facet name="header"> Operation </f:facet>
<h:commandButton action="#{testBean.setEditable(c)}" value="EDIT"
rendered="#{not c.editable}">
</h:commandButton>
<h:commandButton action="#{testBean.save}" value="SAVE"
rendered="#{c.editable}">
</h:commandButton>
</h:column>
</h:dataTable>
</h:form>
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
How would it be possible to retrieve an inputText value foreach row in JSF dataTable, since this data is not an attribute in the object on which we iterate in the loop.
(here 0 as default value). I can't change the Class properties (here Product)
<h:form>
<p:dataTable var="product" value="#{bean.products}">
<p:column headerText="Id">
<h:outputText value="#{product.id}" />
</p:column>
<p:column headerText="Name">
<h:outputText value="#{product.name}" />
</p:column>
<p:column headerText="Quantity">
<h:inputText size="3" value="0" />
</p:column>
</p:dataTable>
<h:commandButton value="Submit" action="#{bean.submit}"/>
</h:form>
Bean.class
#ManagedBean
...
public void submit() {
List<Product> products = this.getProducts();
for(Product product : list) {
System.out.println("Product.name : "+ Product.name );
System.out.println("Quantity : "+ ?? );
}
}
Bind it to a Map with Product (or its ID) as key.
E.g.
private List<Product> products;
private Map<Product, Long> quantities;
#EJB
private ProductService productService;
#PostConstruct
public void init() {
products = productService.list();
quantities = new HashMap<>();
}
public void submit() {
for (Product product : products) {
Long quantity = quantities.get(product);
System.out.println("Quantity: " + quantity);
}
}
// Getters (no setters necessary for those two properties)
with
<h:inputText size="3" value="#{bean.quantities[product]}" />
You can use the visitor pattern to get the values. Something like this:
table.visitTree(VisitContext.createVisitContext(faces),
new VisitCallback() {
#Override public VisitResult visit(VisitContext vc, UIComponent component) {
if (component.equals(quantity) && quantity.getValue() != null) {
cart.addItem(
(Product) table.getRowData(),
(Integer) quantity.getValue());
}
return VisitResult.ACCEPT;
}
});
In JSF2 - I see my datatable reloading each time when i make an ajax call by clicking on each column row. Is there a way to stop loading each time i make an ajax call ? This creates problem by resetting my datatable to default values and i get a wrong value back at managed bean.
<h:inputText size="8" id="startDate"
value="#{contactBean.startDate}">
<f:convertDateTime pattern="MM/dd/yyyy" type="date" />
</h:inputText>
<h:outputText> - </h:outputText>
<h:inputText size="8" id="endDate" value="#{contactBean.endDate}">
<f:convertDateTime pattern="MM/dd/yyyy" type="date" />
</h:inputText>
<h:commandButton value="Filter"
actionListener="#{contactBean.loadAJAXFilterContentList}">
<f:ajax render=":form1:tableContents" />
</h:commandButton>
<h:dataTable id="tableContents"
value="#{contactBean.filterContentList}" var="crs"
binding="#{contactBean.dataTable}" border="1">
<h:column>
<f:facet name="header">
<h:outputText styleClass="contactTableHeader" value="Date/Time" />
</f:facet>
<h:commandLink action="#{contactBean.loadPreviewScreenContents(crs)}">
<h:outputText title="#{crs.dateTime}" value="#{crs.dateTime}">
<f:convertDateTime pattern="MM/dd/yyyy hh:mm a" type="date" />
</h:outputText>
<f:ajax render=":form1:previewScreen" />
</h:commandLink>
</h:column>
</h:dataTable>
<h:panelGrid id="previewScreen">
<h:outputText styleClass="PreviewHeader"
value="Preview of #{contactBean.previewCntDateTime}" />
</h:panelGrid>
So in the above case whenever i click the column it calls the filterContentList() method in my managed bean instead of calling loadPreviewScreenContents(crs) directly.
My bean is RequestScoped. I tried with SessionScope,ViewScope but these 2 scopes retain my previous states like i have other ajax functions in my page and it retains that state. So i cant use Session or ViewScopes in this case.
Is there a solution ?
Bean code:
#ManagedBean(name = "contactBean")
#RequestScoped
public class ContactManagedBean implements Serializable {
private static final long serialVersionUID = 1L;
List<ContactResponseBean> filterContentList = new ArrayList<ContactResponseBean>();
ContactRequestBean contactRequestBean = new ContactRequestBean();
ContactResponseBean crs = new ContactResponseBean();
private String logText;
HtmlDataTable dataTable;
public void setFilterContentList(List<ContactResponseBean> filterContentList) {
this.filterContentList = filterContentList;
}
public void setFilterContentList(List<ContactResponseBean> filterContentList) {
this.filterContentList = filterContentList;
}
public Date getPreviewCntDateTime() {
return previewCntDateTime;
}
public void setPreviewCntDateTime(Date previewCntDateTime) {
this.previewCntDateTime = previewCntDateTime;
}
public String getLogText() {
return logText;
}
public void setLogText(String logText) {
this.logText = logText;
}
public HtmlDataTable getDataTable() {
return dataTable;
}
public void setDataTable(HtmlDataTable dataTable) {
this.dataTable = dataTable;
}
public ContactResponseBean getCrs() {
return crs;
}
public void setCrs(ContactResponseBean crs) {
this.crs = crs;
}
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public void loadAJAXFilterContentList() {
filterButtonAjxFlag = true;
}
public List<ContactResponseBean> getFilterContentList() {
ContactRequestBean contactRequestBean = new ContactRequestBean();
contactRequestBean.setUserId(getUserId());
contactRequestBean.setSummaryType(getSummaryType());
contactRequestBean.setStartDate(getStartDate());
contactRequestBean.setEndDate(getEndDate());
ContactRequestBeanService crbs = new ContactRequestBeanService();
filterContentList = crbs.getFilterContentList(contactRequestBean);
return filterContentList;
}
public void loadPreviewScreenContents(){
crs = (ContactResponseBean) dataTable.getRowData();
setPreviewCntDateTime(crs.getDateTime());
}
}