I am building a web application using the technologies mentioned in the post header. I have searched similar threads, but none of them provided an answer to my problem. I have configured my Maven project, the pom file is correct, JSF and PrimeFaces are working, but I encounter a problem when I do the following:
I copied the Client Side Validation example from the Prime Faces Showcase website, and on my end, it isn't working as expected.
When validation fails for a field, an error appears to the right of the field, and as long as it's there, I cannot update the field. When I try to type something, nothing happens on the screen, but if I highlight the text in the field, I can see it there.
Here's my registration.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
Hello from Facelets
<h2>Registration Form</h2>
<h:form id="form">
<p:panel id="panel" header="Form" style="margin-bottom:10px;">
<p:fieldset legend="Registration Form" widgetVar="regWidget" style="width: 600px;">
<h:panelGrid columns="3" width="550" border="0">
<h:outputLabel value="UserName" />
<p:inputText value="#{regCont.prospect.userName}"
id="userName"
required="true"
requiredMessage="UserName is required"
validatorMessage="UserName should be of length from 5 to 15 chars"
>
<f:validateLength minimum="5" maximum="15" for="userName"></f:validateLength>
</p:inputText>
<p:message for="userName"/>
<h:outputLabel value="Password" />
<p:password value="#{regCont.password}"
id="password"
required="true"
requiredMessage="Password is required"
validatorMessage="Password should be of length from 5 to 15 chars"
>
<f:validateRegex pattern="^(?=^.{8,12}$)(?!.*(.)\1{3,})(?=.*[A-Z])(?=.*[a-z]{3,})(?=.*[^a-zA-Z0-9]{2,})(?=.*[0-9]{2,})[a-zA-Z]"/>
</p:password>
<p:message for="password" />
<h:outputLabel value="FirstName" />
<p:inputText value="#{regCont.prospect.firstName}"
id="firstName"
required="true"
requiredMessage="FirstName is required"
validatorMessage="FirstName should be of length from 5 to 15 chars"
>
<f:validateLength minimum="1" maximum="45" for="firstName"></f:validateLength>
</p:inputText>
<p:message for="firstName" display="tooltip" />
<h:outputLabel value="LastName" />
<p:inputText value="#{regCont.prospect.lastName}"
id="lastName"></p:inputText>
<p:message for="lastName" display="tooltip"/>
<h:outputLabel value="Email" />
<p:inputText value="#{regCont.prospect.email}"
id="email"
validatorMessage="Invalid Email">
<f:validateRegex pattern="[a-zA-Z0-9]+#[a-zA-Z]+.[a-zA-Z]{2,3}"></f:validateRegex>
</p:inputText>
<p:message for="email" />
<h:outputLabel value="Nation" />
<p:inputText value="#{regCont.prospect.nation}"
id="nation">
</p:inputText>
<p:message for="nation" />
<h3 style="margin-top:0">User type</h3>
<h:panelGrid columns="2" style="margin-bottom:10px" cellpadding="5">
<p:outputLabel for="type" value="User type:" />
<p:selectOneRadio id="type" value="#{regCont.prospect.userType}">
<f:selectItem itemLabel="Delegate" itemValue="Delegate" />
<f:selectItem itemLabel="Leader" itemValue="Leader" />
</p:selectOneRadio>
</h:panelGrid>
<p:commandButton value="Register" update="panel" icon="ui-icon-check" validateClient="true" style="margin-right:10px"/>
<h:commandButton value="Reset p:ajax" style="margin-right:20px;" >
<p:ajax update="panel" resetValues="true" />
</h:commandButton>
</h:panelGrid>
</p:fieldset>
</p:panel>
</h:form>
</h:body>
</html>
And here's my RegistrationController class:
#ManagedBean(name = "regCont")
#RequestScoped
public class RegistrationController implements Controller {
#ManagedProperty(value = "#{prospect}")
private Prospect prospect;
#ManagedProperty(value = "#{user}")
private User user;
private String msg;
private String password;
public void hashPassword() throws NoSuchAlgorithmException {
byte[] salt = Passwords.getNextSalt();
prospect.setSalt(salt);
prospect.setPasswordHash(Passwords.getHashWithSalt(password, salt));
password = "";
}
public Prospect getProspect() {
return prospect;
}
public void setProspect(Prospect prospect) {
this.prospect = prospect;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
private void clearAll() {
user.setFirstName("");
user.setLastName("");
user.setNation("");
user.setEmail("");
user.setUserName("");
user.setPasswordHash(null);
prospect.setFirstName("");
prospect.setLastName("");
prospect.setNation("");
prospect.setEmail("");
prospect.setUserType("");
prospect.setUserName("");
prospect.setPasswordHash(null);
}
public void saveUser() {
UserDAO dao = new UserDAO();
dao.createEntity(user);
this.msg = "Member Info Saved Successfull!";
clearAll();
}
public void saveProspect() {
ProspectDAO dao = new ProspectDAO();
try {
hashPassword();
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(User.class.getName()).log(Level.SEVERE, null, ex);
}
dao.createEntity(prospect);
this.msg = "Member Info Saved Successfull!";
}
public void reset() {
RequestContext.getCurrentInstance().reset("form");
}
public void updateUser(int id) {
UserDAO dao = new UserDAO();
try {
hashPassword();
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(User.class.getName()).log(Level.SEVERE, null, ex);
}
dao.updateEntity(id);
this.msg = "Member Info Update Successfull!";
clearAll();
}
public void deleteUser(int id) {
UserDAO dao = new UserDAO();
dao.deleteEntity(id);
this.msg = "Member Info Delete Successfull!";
clearAll();
}
}
Only case this works is, when I implemented the Reset button, and on a failed validation, I click reset, then I can input values into fields.
Also, when I hover above a field (p:inputText), the cursor doesn't change to the text cursor like on other fields (eg. h:inputText). Really don't have an idea how does the same piece of code work on the PrimeFaces ShowCase web site, and not on my end?
Does anybody have an idea how can I fix this?
I'm using JSF 2.2 + PrimeFaces 5.3
Related
This question already has answers here:
commandButton/commandLink/ajax action/listener method not invoked or input value not set/updated
(12 answers)
Closed 6 years ago.
I am using the Primefaces Ultima template on a project. I am stuck with an issue trying to fire an action listener on a page.
I am using the ultima template.xhtml as the template for my application.
template.xhtml
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
<f:facet name="first">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="theme-color" content="#{guestPreferences.themeColors[guestPreferences.theme]}" />
</f:facet>
<title><ui:insert name="title"/></title>
<h:outputScript name="js/nanoscroller.js" library="ultima-layout" />
<h:outputScript name="js/layout.js" library="ultima-layout" />
<h:outputScript name="js/ripple.js" library="ultima-layout" />
<h:outputScript name="js/swipe.js" library="ultima-layout" />
<h:outputStylesheet library="css" name="pfcrud.css"/>
<h:outputScript library="scripts" name="pfcrud.js"/>
<ui:insert name="head"/>
</h:head>
<h:body styleClass="main-body #{guestPreferences.compact ? 'layout-compact' : null}">
<p:growl id="growl" life="3000"/>
<div class="layout-wrapper #{guestPreferences.menuLayout} #{guestPreferences.orientationRTL ? 'layout-rtl' : null}">
<ui:include src="./topbar.xhtml" />
<ui:include src="./menu.xhtml" />
<div class="layout-main">
<ui:insert name="content"/>
<ui:include src="./footer.xhtml" />
</div>
</div>
<p:ajaxStatus style="width:32px;height:32px;position:fixed;right:7px;bottom:7px">
<f:facet name="start">
<i class="fa fa-circle-o-notch fa-spin ajax-loader" aria-hidden="true"></i>
</f:facet>
<f:facet name="complete">
<h:outputText value="" />
</f:facet>
</p:ajaxStatus>
<h:outputStylesheet name="css/nanoscroller.css" library="ultima-layout" />
<h:outputStylesheet name="css/animate.css" library="ultima-layout" />
<h:outputStylesheet name="css/ripple.css" library="ultima-layout" />
<h:outputStylesheet name="css/my_layout.css" library="ultima-layout" />
</h:body>
The page I am having issue has the code below.
profile.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">
<ui:composition 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="title">
Profile
</ui:define>
<ui:define name="content">
<div class="ui-g ui-fluid">
<div class="ui-g-12 ui-lg-6">
<!-- Left Side -->
<h:form id="personalForm">
<div class="card card-w-title">
<h1>Personal Info</h1>
<h:panelGroup id="personalInfo" rendered="#{loginController.currentUser != null}">
<p:panelGrid columns="2" layout="grid" styleClass="ui-panelgrid-blank form-group">
<h:panelGroup styleClass="md-inputfield">
<p:inputText id="accessCode" value="#{loginController.tempUser.accessCode}" title="#{messages.CreateUserTitle_firstName}" required="true"
requiredMessage="#{messages.CreateUserRequiredMessage_firstName}" maxlength="50" disabled="true"/>
<label>Access Code</label>
</h:panelGroup>
<h:panelGroup styleClass="md-inputfield">
<p:inputText id="firstName" value="#{loginController.tempUser.firstName}" title="#{messages.CreateUserTitle_firstName}" maxlength="50"/>
<label for="firstName">First Name</label>
</h:panelGroup>
<h:panelGroup styleClass="md-inputfield">
<p:inputText id="lastName" value="#{loginController.tempUser.lastName}" title="#{messages.CreateUserTitle_lastName}" maxlength="50"/>
<label for="lastName">Last Name</label>
</h:panelGroup>
<p:selectOneMenu id="country" value="#{loginController.tempUser.country}" required="true"
requiredMessage="#{messages.CreateUserRequiredMessage_country}" converter="countryConverter" style="width: 100%">
<f:selectItem itemLabel="#{messages.CreateUserLabel_country}"/>
<f:selectItems value="#{countryController.items}"
var="countryItem"
itemValue="#{countryItem}"
itemLabel="#{countryItem.id.toString()}"
/>
</p:selectOneMenu>
<p:selectOneMenu id="nationality" value="#{loginController.tempUser.nationality}" required="true"
requiredMessage="#{messages.CreateUserRequiredMessage_nationality}" converter="countryConverter" style="width: 100%">
<f:selectItem itemLabel="#{messages.CreateUserLabel_nationality}"/>
<f:selectItems value="#{countryController.items}"
var="nationalityItem"
itemValue="#{nationalityItem}"
itemLabel="#{nationalityItem.id.toString()}"
/>
</p:selectOneMenu>
<h:panelGroup styleClass="md-inputfield">
<p:inputText id="city" value="#{loginController.tempUser.city}" title="#{messages.CreateUserTitle_city}" required="true"
requiredMessage="#{messages.CreateUserRequiredMessage_city}" size="50" maxlength="50" style="width: 100%"/>
<label for="city">City</label>
</h:panelGroup>
<h:panelGroup styleClass="md-inputfield">
<p:inputText id="email" value="#{loginController.tempUser.email}" title="#{messages.CreateUserTitle_email}" required="true" requiredMessage="#{messages.CreateUserRequiredMessage_email}" size="50" maxlength="50"/>
<label for="email">Email</label>
</h:panelGroup>
<h:panelGroup styleClass="md-inputfield">
<p:inputText id="telephone1" value="#{loginController.tempUser.telephone1}" title="#{messages.CreateUserTitle_telephone1}"
required="true" requiredMessage="#{messages.CreateUserRequiredMessage_telephone1}" size="20" maxlength="20" style="width: 100%"/>
<label for="telephone1">Telephone 1</label>
</h:panelGroup>
<h:panelGroup styleClass="md-inputfield">
<p:inputText id="telephone2" value="#{loginController.tempUser.telephone2}" title="#{messages.CreateUserTitle_telephone2}"
size="20" maxlength="20" style="width: 100%"/>
<label for="telephone2">Telephone 2</label>
</h:panelGroup>
</p:panelGrid>
<p:commandButton actionListener="#{loginController.updateProfile(event)}" value="Update" update="personalForm:personalInfo, :growl" icon="fa fa-paper-plane-o" >
<p:confirm header="#{messages.ConfirmationHeader}" message="#{messages.ConfirmCreateMessage}"/>
</p:commandButton>
</h:panelGroup>
</div>
</h:form>
</div>
<div class="ui-g-12 ui-lg-6">
<!-- Right Side -->
<h:form id="passwordForm">
<div class="card card-w-title">
<h1>Change Password</h1>
<h:panelGroup id="passwordInfo" rendered="#{loginController.currentUser != null}">
<p:panelGrid columns="2" layout="grid" styleClass="ui-panelgrid-blank form-group">
<h:panelGroup styleClass="md-inputfield">
<p:password id="password" required="true" requiredMessage="Please fill out the new password"
value="#{loginController.password}" match="confirmPassword"/>
<label for="password">New Password</label>
</h:panelGroup>
<h:panelGroup styleClass="md-inputfield">
<p:password id="confirmPassword" value="#{loginController.password}" required="true"
requiredMessage="Please repeate the new password"/>
<label for="confirmPassword">Confirm New Password</label>
</h:panelGroup>
</p:panelGrid>
<p:commandButton actionListener="#{loginController.updatePassword(event)}" value="Update" update="passwordForm:passwordInfo, :growl" icon="fa fa-paper-plane-o" >
<p:confirm header="#{messages.ConfirmationHeader}" message="#{messages.ConfirmCreateMessage}"/>
</p:commandButton>
</h:panelGroup>
</div>
</h:form>
</div>
</div>
</ui:define>
</ui:composition>
And the session beans having the action listeners has the code below:
LoginController.java
#ManagedBean(name = "loginController")
#SessionScoped
public class LoginController implements Serializable {
private static final long serialVersionUID = 1L;
private User currentUser = new User();
private User tempUser = new User();
private User oldUserValue = new User();
private String accessCode;
private String password;
private String telephone;
private String email;
private String userName;
#Inject
RoleFacade roleFacade;
private enum UsersActions {
SIGN_UP,
CHANGE_PWD,
UPDATE
}
#Inject
private UserFacade userFacade;
public String getAccessCode() {
return accessCode;
}
public void setAccessCode(String accessCode) {
this.accessCode = accessCode;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public User getCurrentUser() {
return currentUser;
}
public void setCurrentUser(User currentUser) {
FacesContext.getCurrentInstance().
getExternalContext().getSessionMap().put("currentUser", currentUser);
this.currentUser = currentUser;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public User getOldUserValue() {
return oldUserValue;
}
public void setOldUserValue(User oldUserValue) {
this.oldUserValue = oldUserValue;
}
public User getTempUser() {
return tempUser;
}
public void setTempUser(User tempUser) {
this.tempUser = tempUser;
}
public String authenticate() throws NoSuchAlgorithmException {
User user = userFacade.findByAccessCode(accessCode);
if (user != null && user.getPassword().equals(MyStringUtil.toSHA256(password))) {
this.setCurrentUser(user);
StringBuilder strBuilder = new StringBuilder();
String firstName = getNonNullValue(this.getCurrentUser().getFirstName());
String lastName = getNonNullValue(this.getCurrentUser().getLastName());
strBuilder.append(firstName);
strBuilder.append((lastName.isEmpty() ? "" : " " + lastName));
this.setUserName(strBuilder.toString());
return "/dashboard";
}
return "#";
}
public String signOut() {
this.setCurrentUser(null);
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.invalidateSession();
return "/login";
}
private String getNonNullValue(String value) {
return (value == null || value.isEmpty() ? "" : value);
}
public void forgotPassword(ActionEvent event) {
if (accessCode != null && email != null && telephone != null) {
User user = userFacade.findByEmailAndTelephone(accessCode, email, telephone);
if (user != null) {
try {
String clearPwd = MyStringUtil.generatePwd();
User user2 = (User) (new PersistenceCloner(user)).generateCopyToPersist();
user.setPassword(MyStringUtil.toSHA256(clearPwd));
// outgoing message information
String mailTo = user.getEmail();
String subject = "My Way Investracker Password updated";
// message contains HTML markups
String message = "<i>Hello Investor!</i><br><br>";
message += "<p><b>You new password is:</b><br>";
message += "<i></i> <b><h2><font color=red>" + clearPwd + "</font></h2></b>";
message += "<i>Please kindly change it upon next login.</i><br><br></p>";
message += "<font color=red>My Way Sarl</font>";
System.out.println("User 1 = " + user);
System.out.println("User 2 = " + user2);
try {
this.persist(user, user2, UsersActions.CHANGE_PWD,
"A mail has been sent to you with the new password.");
MailUtil.sendHtmlEmail(mailTo, subject, message);
} catch (Exception ex) {
JsfUtil.addErrorMessage("Sorry there was an error handling this, please try again!");
Logger.getLogger(UserController.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (NoSuchAlgorithmException ex) {
JsfUtil.addErrorMessage("Sorry there was an error handling this, please try again!");
Logger.getLogger(UserController.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
JsfUtil.addErrorMessage("Sorry the email and telephone number doesn't match!");
}
}
}
public void signUp(ActionEvent event) throws NoSuchAlgorithmException {
String access = MyStringUtil.generateAccessCode();
Role role = new Role();
role.setId("NONE");
role.setName("NONE");
this.tempUser.setIdRole(role);
this.tempUser.setAccessCode(access);
this.tempUser.setPassword(MyStringUtil.toSHA256(this.tempUser.getPassword()));
this.tempUser.setActivityStatus(false);
persist(this.tempUser, this.tempUser, LoginController.UsersActions.SIGN_UP, "You have successfully registered, check your email for your access code.");
}
public void updateProfile(ActionEvent event) {
System.out.println("UPDATE PROFILE LAUNCHED.");
System.out.println("UPDATE PROFILE COMPLETED.");
}
public void updatePassword(ActionEvent event) {
System.out.println("UPDATE PASSWORD LAUNCHED");
System.out.println("UPDATE PASSWORD COMPLETED.");
}
private void persist(User newValue, User oldValue, LoginController.UsersActions actionName, String successMessage) {
System.out.println("PERSISTENCE METHOD ALREADY RAN.");
}
}
So far I have made some research on this issue and have come across as similar issue with an answer proposed by #BalusC, but I am unable to find the issue. Please I would need your help!
You are using p:confirm in combination with p:commandButton, but you didn't define a global p:confirmDialog.
You have two options:
Remove the p:confirm child from the p:commandButton.
Add a global p:confirmDialog to your page (see example of p:confirmDialog in PrimeFaces-Showcase). The actionListener will then be invoked on pressing the Yes-button inside the confirmation dialog.
Command Button is not working in my xhtml page when i am clicking on button its not calling Save method of CalendarController but handleSelectData method working fine. so please tell me where i am wrong.
xhtml file
<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"
xmlns:pe="http://primefaces.org/ui/extensions">
<p:dialog id="eventdailog" width="425px" height="320px"
header=" Create Event" widgetVar="dlg" focus="event"
showEffect="explode" hideEffect="explode" modal="true">
<h:form id="createevent">
<p>
<p:commandLink
value="Important:Learn about Event Management features"
style="text-decoration:none" />
</p>
</h:form>
<h:form id="event">
<p:tabView>
<p:tab id="Event1" title="Event">
<h:form id="eventtab">
<h:outputLabel for="event" />
<p:inputText id="event" label="Description" rendered="true" />
<p:watermark for="event" value="Please add description" />
<h:outputLabel for="date" />
<p:calendar value="#{calendar.date}" pattern="MM/dd/yyyy hh:mm a"
id="date" showOn="button" />
<h:outputText value="#{calendar.date}">
<f:convertDateTime pattern="MM/dd/yyyy hh:mm a" />
</h:outputText>
<p:autoComplete id="autoComp"
value="#{autocompleteBeanController.selectedUserProfiles}"
completeMethod="#{autocompleteBeanController.completeUserProfile}"
var="auto" itemLabel="#{auto.displayName}" itemValue="#{auto}"
converter="#{userAutocompleteConverter}" forceSelection="true"
required="true" rerequiredMessage="Send to is required"
label="Send to" minQueryLength="1" maxResults="5" multiple="true">
<p:ajax event="itemUnselect"
listener="#{autocompleteBeanController.handleUnselect}" />
<p:column>
<p:graphicImage value="#{auto.imagePath}" width="30" height="20" />
#{auto.displayName}
</p:column>
</p:autoComplete>
<p:watermark for="autoComp" value="Send to.."
onclick="PrimeFaces.cleanWatermarks();"
oncomplete="PrimeFaces.showWatermarks();" />
<br />
<p:commandButton id="save" value="Create"
actionListner="#{calendarController.save}"
onclick="dlg.hide();return false" />
</h:form>
</p:tab>
CalendarController.java
#Named
#Scope("session")
public class CalendarController implements Serializable {
private static final long serialVersionUID = -6221780314938096482L;
private Date date;
#Inject
private AutocompleteBeanController autocompletebean;
#Inject
private EventService eventService;
#Inject
private ManagedLoginBean login;
public ManagedLoginBean getLogin() {
return login;
}
public void setLogin(ManagedLoginBean login) {
this.login = login;
}
public EventService getEventService() {
return eventService;
}
public void setEventService(EventService eventService) {
this.eventService = eventService;
}
public AutocompleteBeanController getAutocompletebean() {
return autocompletebean;
}
public void setAutocompletebean(AutocompleteBeanController autocompletebean) {
this.autocompletebean = autocompletebean;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public void handleDateSelect(SelectEvent event) {
FacesContext facesContext = FacesContext.getCurrentInstance();
SimpleDateFormat format = new SimpleDateFormat("d/M/yyyy");
RequestContext.getCurrentInstance().execute("dlg.show();");
}
public void save(ActionEvent event) {
EventDTO eventDto = new EventDTO();
eventDto.setEventUserDto(PaatashaalaUtil.getUserProfileDTO(login));
int status = eventService.createEvent(eventDto);
FacesMessage msg = null;
if (status == 1) {
msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Event Update",
null);
FacesContext.getCurrentInstance().addMessage("event", msg);
}
}
}
The correct attribute for p:commandButton is actionListener and not actionlistener
I have a problem with my code where the values from various `'s won't pass over to the bean. The code is basically the same as my old projects (where everything worked perfectly fine), but no matter what I do the values in the bean won't be updated. What I want to do is for the user to fill in a form in order to register an account. I tried doing it in two ways:
<p:inputText id="address" value="#{Register.user.address}.../>
Here Register is the bean with the property user of the User class, where there are several properties including String address. This didn't really work, so I tried putting the getters and setters in the RegisterBean, and setting them to this format
public String getAddress(){
return user.getAdress();
}
and using them like this in the xhtml
<p:inputText id="address" value="#{Register.address]".../>
but it still doesn't work. Tried debugging, and it appears that the setters are never entered at all. Does anybody know why this doesn't work and potentially how to fix it?
Here is the rest of the code:
The .xhtml
<h:head>
<title>Register</title>
</h:head>
<body>
<ui:composition template="userTemplate.xhtml">
<ui:define name="content">
<h:form>
<h:panelGrid id="grid" columns="3" >
<f:facet name="header">
Please fill in the required information
</f:facet>
<p:outputLabel value="Username" />
<p:inputText id="username" value="#{Register.user.username}" validator="#{Register.validateUsername}" required="true" requiredMessage="Cannot be blank!"/>
<p:message for="username"/>
<p:outputLabel value="Password"/>
<p:password id="password" value="#{Register.user.password}" validator="#{Register.validatePasswords}"/>
<p:message for="password" showSummary="true" showDetail="false"/>
<p:outputLabel value="Repeat password" />
<p:password id="repPassword" value="#{Register.user.repeatPass}" validator="#{Register.validateRepPassword}"/>
<p:message for="repPassword" showSummary="true" showDetail="false"/>
<p:outputLabel value="First name" />
<p:inputText id="firstName" value="#{Register.user.firstName}"/>
<p:message for="firstName" showSummary="true" showDetail="false"/>
<p:outputLabel value="Surname" />
<p:inputText id="surname" value="#{Register.user.surname}" required="true" requiredMessage="Cannot be blank!"/>
<p:message for="surname" showSummary="true" showDetail="false"/>
<p:outputLabel value="Address" />
<p:inputText id="address" value="#{Register.user.address}" required="true" requiredMessage="Cannot be blank!"/>
<p:message for="address" showSummary="true" showDetail="false"/>
<p:outputLabel value="Postnumber"/>
<p:inputText id="postnumber" value="#{Register.user.postnumber}" validatorMessage="Can only be numbers!" required="true" requiredMessage="Cannot be blank!"/>
<p:message for="postnumber" showSummary="true" showDetail="false"/>
<p:outputLabel value="City"/>
<p:inputText id="city" value="#{Register.user.city}" required="true" requiredMessage="Cannot be blank!"/>
<p:message for="city" showSummary="true" showDetail="false"/>
<p:outputLabel value="E-mail" />
<p:inputText id="email" validator="#{Register.user.validateEmail}" value="#{Register.email}"/>
<p:message for="email" showSummary="true" showDetail="false"/>
<p:outputLabel value="Phone number" />
<p:inputText id="phone" value="#{Register.user.phone}" required="true" validatorMessage="Phone number must be between 8 and 16 numbers long" requiredMessage="Cannot be blank!">
<f:validateLongRange minimum="8" maximum="16"/>
</p:inputText>
<p:message for="phone" showDetail="false" showSummary="true"/>
<p:commandButton type="submit" id="submitButton" value="submit" update="grid" ajax="true"/>
<p/>
#{Register.user}
</h:panelGrid>
</h:form>
</ui:define>
</ui:composition>
</body>
</html>
The bean:
#SessionScoped
#ManagedBean(name="Register")
public class registerBean implements Serializable {
private User user = new User();
public void validateUsername(FacesContext context, UIComponent component, Object value) {
String message = "";
String username = (String) value;
if(username == null || username.equals("")) {
((UIInput)component).setValid(false);
message = "Enter a username";
context.addMessage(component.getClientId(context), new FacesMessage(message));
}
//else user.setUsername(username);
}
public void validatePasswords(FacesContext context, UIComponent component, Object value) {
String message = "";
String password = (String) value;
boolean hasNumber = false;
for(int i = 0; i < password.length(); i++) {
if(Character.isDigit(password.charAt(i))) {
hasNumber = true;
}
}
if(!hasNumber && password.length() < 8) {
((UIInput)component).setValid(false);
message = "You need to have at least one number and the password must be atleast 8 characters long";
context.addMessage(component.getClientId(context), new FacesMessage(message));
}
//else user.setPassword(password);
}
public void validateRepPassword(FacesContext context, UIComponent component, Object value) {
String message = "";
String repPassword = (String) value;
if(!repPassword.equals(user.getPassword())) {
((UIInput)component).setValid(false);
message = "The passwords don't match.";
context.addMessage(component.getClientId(context), new FacesMessage(message));
}
//else user.setRepeatPass(repPassword);
}
public void validatePostnumber(FacesContext context, UIComponent component, Object value) {
String message = "";
try {
Integer postnumber = (Integer) value;
} catch (Exception e) {
((UIInput)component).setValid(false);
message = "The postnumber can only be numbers";
context.addMessage(component.getClientId(context), new FacesMessage(message));
}
//user.setPostnumber(((Integer) value).intValue());
}
public void validateEmail(FacesContext context, UIComponent component, Object value) {
String message = "";
try {
InternetAddress email = new InternetAddress((String) value);
email.validate();
} catch(AddressException ae) {
((UIInput)component).setValid(false);
message = "Type a valid email address";
context.addMessage(component.getClientId(context), new FacesMessage(message));
}
//user.setEmail((String)value);
}
public User getUser() {
return user;
}
}
And finally the normal User java class
public class User {
private String username;
private String password;
private String repeatPass;
private String address;
private int postnumber;
private String city;
private String firstName;
private String surname;
private String email;
private long phone;
+setters/getters and a toString()
}
I figured out the problem. I feel kinda stupid, but there wasn't really any problem from the start. The thing was that because of all the validators and everything, the validation was set to false on several fields which led to the fact that the values didn't pass back. As soon as I set all correct information, it worked.
I've been strugling with an issue I can't find the way to solve it and I can't find anything related on the web.
I'm using Netbeans with Primefaces to develop a JSF web app.
Everything works fine except that sometimes the call to the actionlisteners is being done several times.
For example this is my JSF page with primefaces:
<h:body>
<ui:composition template="home.xhtml">
<ui:define name="content">
<h2>Administración de alertas SMS</h2>
<p:panel id="display">
<p:selectBooleanCheckbox itemLabel="Enviar alertas SMS" value="#{smsConfigBean.alertsEnabled}"/>
<p>
<h:outputText value="Mensaje de Texto: " /><br /><br />
<p:inputTextarea rows="5" cols="50" counterTemplate="{0} caracteres restantes." counter="counter" maxlength="160" value="#{smsConfigBean.smsMessage}" id="smsMessage"/>
<br />
<h:outputText id="counter" />
</p>
<p>
<h:outputText value="Dispositivo de envio SMS: " />
<p:selectOneRadio id="options" value="#{smsConfigBean.usePhone}">
<f:selectItem itemLabel="Modem USB" itemValue="false" />
<f:selectItem itemLabel="Telefono Android" itemValue="true" />
</p:selectOneRadio>
</p>
<br />
<p:tabView id="tabView">
<p:tab id="tab1" title="Modem USB">
<h:panelGrid id="modemGrid" columns="2" cellpadding="4">
<h:outputText value="Puerto: " />
<p:inputText id="port" value="#{smsConfigBean.port}"/>
<h:outputText value="Bit Rate (Opcional): " />
<p:inputText id="bitRate" value="#{smsConfigBean.bitRate}"/>
<h:outputText value="Nombre de modem (Opcional): " />
<p:inputText id="modemName" value="#{smsConfigBean.modemName}"/>
<h:outputText value="PIN: " />
<p:inputText id="pin" value="#{smsConfigBean.modemPin}"/>
<h:outputText value="Centro de Mensajes: " />
<p:inputText id="smsc" value="#{smsConfigBean.SMSC}"/>
</h:panelGrid>
</p:tab>
<p:tab id="tab2" title="Telefono Android">
<h:panelGrid id="phoneGrid" columns="2" cellpadding="4">
<h:outputText value="Path ADB:" />
<p:inputText id="adbPath" value="#{smsConfigBean.adbPath}"/>
<h:outputText value="Directorio de Configuracion:" />
<p:inputText id="configPath" value="#{smsConfigBean.configPath}"/>
<h:outputText value="Modo de conexion " />
<p:selectOneRadio id="connectOptions" value="#{smsConfigBean.useWifi}">
<f:selectItem itemLabel="USB" itemValue="false"/>
<f:selectItem itemLabel="WiFi" itemValue="true" />
</p:selectOneRadio>
<h:outputText value="Direccion IP (Solo para WiFi): " />
<p:inputText id="ipDir" value="#{smsConfigBean.ipDir}"/>
</h:panelGrid>
</p:tab>
</p:tabView>
</p:panel>
<br />
<p:commandButton id="saveSmsAlerts" value="Guardar" update="messages" action="#{smsConfigBean.saveChanges}" actionListener="#{smsConfigBean.saveChanges}"/>
</ui:define>
</ui:composition>
</h:body>
And this is my backend bean:
package Beans;
import helpers.Global; import javax.faces.bean.ManagedBean; import
javax.faces.bean.SessionScoped;
#ManagedBean #SessionScoped public class SmsConfigBean {
private Boolean alertsEnabled;
private Boolean usePhone;
private Boolean useWifi;
private String port;
private int bitRate;
private String modemName;
private String modemPin;
private String SMSC;
private String adbPath;
private String configPath;
private String ipDir;
private String smsMessage;
public SmsConfigBean() {
alertsEnabled = Global.getAlertsEnabled();
port = Global.getPort();
bitRate = Global.getBitRate();
modemName = Global.getModemName();
modemPin = Global.getModemPin();
SMSC = Global.getSMSC();
usePhone = Global.getUsePhone();
adbPath = Global.getAdbPath();
configPath = Global.getConfigPath();
useWifi = Global.getUseWifi();
ipDir = Global.getIpDir();
smsMessage = Global.getSmsMessage();
}
public Boolean getAlertsEnabled() {
return alertsEnabled;
}
public void setAlertsEnabled(Boolean alertsEnabled) {
this.alertsEnabled = alertsEnabled;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
public int getBitRate() {
return bitRate;
}
public void setBitRate(int bitRate) {
this.bitRate = bitRate;
}
public String getModemName() {
return modemName;
}
public void setModemName(String modemName) {
this.modemName = modemName;
}
public String getModemPin() {
return modemPin;
}
public void setModemPin(String modemPin) {
this.modemPin = modemPin;
}
public String getSMSC() {
return SMSC;
}
public void setSMSC(String SMSC) {
this.SMSC = SMSC;
}
public Boolean getUsePhone() {
return usePhone;
}
public void setUsePhone(Boolean usePhone) {
this.usePhone = usePhone;
}
public String getAdbPath() {
return adbPath;
}
public void setAdbPath(String adbPath) {
this.adbPath = adbPath;
}
public String getConfigPath() {
return configPath;
}
public void setConfigPath(String configPath) {
this.configPath = configPath;
}
public Boolean getUseWifi() {
return useWifi;
}
public void setUseWifi(Boolean useWifi) {
this.useWifi = useWifi;
}
public String getIpDir() {
return ipDir;
}
public void setIpDir(String ipDir) {
this.ipDir = ipDir;
}
public String getSmsMessage() {
return smsMessage;
}
public void setSmsMessage(String smsMessage) {
this.smsMessage = smsMessage;
}
public void saveChanges(){
Global.setSmsMessage(smsMessage);
Global.setIpDir(ipDir);
Global.setUseWifi(useWifi);
Global.setConfigPath(configPath);
Global.setAdbPath(adbPath);
Global.setUsePhone(usePhone);
Global.setSMSC(SMSC);
Global.setModemPin(modemPin);
Global.setModemName(modemName);
Global.setBitRate(bitRate);
Global.setPort(port);
Global.setAlertsEnabled(alertsEnabled);
Global.sendInfoResponseMessage("Cambios guardados con exito");
}
}
The problem is that when saving the changes of this form by hitting the commandButton 'saveSmsAlerts' the call is being made twice. Resulting in the growl message to be shown twice too.
(You won't see the growl component because it was defined in the template)
This happens also in another page that I did for the same app that uploads a file using fileuploader. The file is uploaded 4 times!!
I'm using chrome to test the application and netbeans to develop it.
You should remove one of action or actionListener attribute.
<p:commandButton id="saveSmsAlerts" value="Guardar" update="messages" action="#{smsConfigBean.saveChanges}"/>
if you remove action attribute you should change the action method signature
<p:commandButton id="saveSmsAlerts" value="Guardar" update="messages" actionListener="#{smsConfigBean.saveChanges}"/>
Like this
public void saveChanges(ActionEvent e){
...
}
here is the difference between action and actionListener
Differences between action and actionListener
Anyone know of a way to assign the value of a p:inputText so it displays correctly in a dialog window but only update a change in the value from a commandButton action instead of a dynamic set method of the value in the backing bean. Have the users add a step and it shows up in the ring then they can click the individual steps, but I want them to be able to update the step info only through the update step button, not by just changing the field and closing the dialog? Built-in method would be prefer, I know I can code around, but trying not to.
Thanks in advance....
<p:ajaxStatus onstart="statusDialog.show();" onsuccess="statusDialog.hide();"/>
<p:dialog modal="true" widgetVar="statusDialog" header="Status"
draggable="false" closable="false">
<p:graphicImage value="/resources/images/ajaxloadingbar.gif" />
</p:dialog>
<h:form id="form">
<p:panel header="Setup System" >
<p:selectOneMenu value="#{groups.selected_sys_code}" id="systems" rendered="#{utility.systemDD}">
<f:selectItem itemLabel="Choose System" itemValue="" />
<f:selectItems value="#{supportBean.access_system_codes}"/>
<p:ajax listener="#{groups.valueChanged}" event="valueChange" render="systemForm" execute="#all"/>
</p:selectOneMenu>
<h:panelGroup id="systemForm" >
<p:panel id="panel" header="Step Details">
<p:messages id="msgs"/>
<h:panelGrid columns="2" columnClasses="label, value" styleClass="grid">
<p:panelGrid columns="2" styleClass="veaGrid">
<h:outputLabel for="name" value="Name:"/>
<p:inputText id="name" value="#{setup.name}" label="Name" required="true"/>
<h:outputLabel for="desc" value="Description:"/>
<p:inputText id="desc" value="#{setup.description}" label="Description" required="true"/>
<h:outputLabel for="email" value="Email For Group Responsible:"/>
<p:inputText id="email" value="#{setup.emailResp}" label="Email" required="true"/>
<h:outputLabel for="process" value="Process:"/>
<p:inputText id="process" value="#{setup.process}" label="Process" required="true"/>
</p:panelGrid>
</h:panelGrid>
<p:commandButton value="Add Step" update="panel,stepsRing" actionListener="#{setup.setSteps}" process="#form" >
</p:commandButton>
<p:commandButton value="Submit All Steps" actionListener="setup.submitSteps">
</p:commandButton>
</p:panel>
</h:panelGroup>
<h:panelGroup id="stepsRing" >
<p:panel header="Steps">
<p:ring id="basic" value="#{setup.steps}" var="step" >
<p:column>
<p:outputPanel/>
<p:outputPanel style="text-align:center;" layout="block" >
Step #{step.sequence}
<br/>
<p:commandButton update=":form:detail" title="View" oncomplete="dlg.show()" value="Details" >
<f:setPropertyActionListener value="#{step}" target="#{setup.selectedStep}" />
</p:commandButton>
</p:outputPanel>
</p:column>
</p:ring>
</p:panel>
</h:panelGroup>
<p:dialog id="dialog" widgetVar="dlg" showEffect="fade" hideEffect="fade" modal="true" width="300" >
<p:outputPanel id="detail" style="text-align:center;" layout="block">
<h:panelGrid columns="2" cellpadding="5" rendered="#{not empty setup.selectedStep}">
<f:facet name="header">
Step #{setup.selectedStep.sequence}
</f:facet>
<h:outputText value="Name: " />
<p:inputText id="name2" value="#{setup.selectedStep.name}" />
<h:outputText value="Description: " />
<p:inputText id="desc2" value="#{setup.selectedStep.description}" />
<h:outputText value="Email: " />
<p:inputText id="email2" value="#{setup.selectedStep.emailResp}"/>
<h:outputText value="Process: " />
<p:inputText id="process2" value="#{setup.selectedStep.process}"/>
<p:commandButton update="stepsRing" actionListener="#{setup.removeStep}" title="Remove" oncomplete="dlg.hide()" value="Remove Step" >
<f:setPropertyActionListener value="#{step}" target="#{setup.selectedStep}" />
</p:commandButton>
<p:commandButton update="stepsRing" process="#form" actionListener="#{setup.updateStep}" title="Update" value="Update Step" >
<f:setPropertyActionListener value="#{step}" target="#{setup.selectedStep}" />
</p:commandButton>
</h:panelGrid>
</p:outputPanel>
</p:dialog>
</p:panel>
</h:form>
BackingBean
#ManagedBean(name="setup")
#ViewScoped
public class WorkStepSetupSystemBean implements Serializable{
private WorkSetup step;
public ArrayList <WorkSetup> steps=new ArrayList <WorkSetup> ();
private WorkSetup ws;
private String system="test1";
private String emailResp;
private String process;
private String name;
private String description;
private Integer sequence;
private String email2;
private String process2;
private String name2;
private String desc2;
private WorkSetup selectedStep;
public WorkStepSetupSystemBean(){
}
public String getDesc2() {
return desc2;
}
public String getEmail2() {
return email2;
}
public String getName2() {
return name2;
}
public String getProcess2() {
return process2;
}
public WorkSetup getSelectedStep() {
return selectedStep;
}
public ArrayList<WorkSetup> getSteps() {
return steps;
}
public WorkSetup getStep() {
return step;
}
public void setSteps(ActionEvent event) {
step= new WorkSetup();
step.setName(name);
step.setEmailResp(emailResp);
step.setDescription(description);
step.setSystem(system);
step.setProcess(process);
step.setSequence(steps.size()+1);
steps.add(step);
return;
}
public void setStep(ArrayList<WorkSetup> steps) {
this.steps = steps;
}
public Integer getSequence() {
return sequence;
}
public String getDescription() {
return description;
}
public String getEmailResp() {
return emailResp;
}
public String getName() {
return name;
}
public String getProcess() {
return process;
}
public String getSystem() {
return system;
}
public void setDescription(String description) {
this.description = description;
}
public void setEmailResp(String emailResp) {
this.emailResp = emailResp;
}
public void setName(String name) {
this.name = name;
}
public void setProcess(String process) {
this.process = process;
}
public void setSequence(Integer sequence) {
this.sequence = sequence;
}
public void setSystem(String system) {
this.system = system;
}
public void setDesc2(String desc2) {
this.desc2 = desc2;
}
public void setEmail2(String email2) {
this.email2 = email2;
}
public void setName2(String name2) {
this.name2 = name2;
}
public void setProcess2(String process2) {
this.process2 = process2;
}
public void setSelectedStep(WorkSetup selectedStep) {
this.selectedStep = selectedStep;
}
public void removeStep(ActionEvent event) {
steps.remove(steps.indexOf(this.selectedStep));
for(int i=0;i<steps.size();i++){
steps.get(i).setSequence(i+1);
}
}
public void updateStep(ActionEvent event) {
step=steps.get(steps.indexOf(this.selectedStep));
step.setName(name2);
step.setEmailResp(email2);
step.setDescription(desc2);
step.setSystem(system);
}
}
Ended up using
<p:inplace id="inplaceName" >
<p:inputText id="name2" value="#{setup.selectedStep.name}" />
<p:tooltip for="inplaceName" value="Click here to edit"/>
</p:inplace>
without the AJAX option