I'm creating a registration form. I want to force that p:password is strong. Is there any way to validate that p:password is strong? I want to be taken as 'strong' the same indicator of p:password's feedback.
My solution for this:
<h:form id="form" >
<p:password value="#{regitroCtrl.usuario.contrasenia}"
id="contrasena"
feedback="true"
required="true"
onblur="validarPassword()"/>
<p:message for="contrasena" id="contrasenaMsg" />
<p:commandButton value="Registrarse"
action="#{regitroCtrl.registrarse()}"
update="form"
onclick="return validarPassword()"/>
</h:form>
The validarPassword function:
function validarPassword(){
var strength = PrimeFaces.widget.Password.prototype.testStrength($("#form\\:contrasena").val());
if(strength <= 30){
$("#form\\:contrasenaMsg").html('<span class="ui-message-error-icon"></span><span class="ui-message-error-detail">Por favor, ingresa una contraseña más fuerte</span>');
$("#form\\:contrasena").addClass("ui-state-error");
return false;
}
else {
$("#form\\:contrasenaMsg").html('');
$("#form\\:contrasena").removeClass("ui-state-error");
return true;
}
}
Seems there is no build-in solution for your requirement. Only I can see it in primefaces showcase is password feed back
<p:password id="pwd" value="#{passwordView.password3}" feedback="true"
weakLabel="Weak" goodLabel="Good" strongLabel="Strong"/>
Alternately you can use validator
<p:password id="pwd" value="#{passwordView.password3}" feedback="true"
weakLabel="Weak" goodLabel="Good" strongLabel="Strong">
<f:validateLength minimum="4" maximum="101"/> // or
<f:validator validatorId="passwordValidator" />
</p:password>
Validation class
#ManagedBean
#RequestScoped
#FacesValidator(value = "passwordValidator")
public class PasswordValidator implements Validator, Serializable {
#Override
public void validate(FacesContext fc, UIComponent uic, Object propertyValue) throws ValidatorException {
// your validation here
}
Related
I have a simple form, with some input and a selectonemenu:
<h:panelGroup id="Client">
<h:form id="formClient">
<p:panelGrid columns="3" layout="grid"
columnClasses="labelWidth, ui-grid-col-3">
<p:outputLabel value="CIN:" for="txtCin" />
<h:panelGrid columns="2">
<p:inputText value="#{clientBean.client.identifiant}" id="txtCin"></p:inputText>
<p:commandButton value="Search" process="#parent"
styleClass="orangeButton" update="formClient"
style="margin-top: -10px;" action="#{clientBean.rechercher()}"></p:commandButton>
</h:panelGrid>
<p:message for="txtCin" />
<p:outputLabel value="Nom:" for="txtNom" />
<p:inputText id="txtNom" styleClass="form-control"
value="#{clientBean.client.nomClient}" required="true"
requiredMessage="Le nom est obligatoire" />
<p:message for="txtNom" />
<p:outputLabel value="Type de voie:" for="txtVoie" />
<p:selectOneMenu styleClass="form-control"
value="#{clientBean.client.typeVoie}" id="txtVoie">
<f:selectItem itemLabel="Selectionnez voie..." itemValue="" />
<f:selectItems value="#{clientBean.typeVoies}" var="typeVoie" itemLabel="#{typeVoie.libelle}" itemValue="#{typeVoie}" />
</p:selectOneMenu>
<p:message for="txtVoie" />
<p:outputPanel></p:outputPanel>
<p:outputPanel>
<p:commandButton value="Annuler" update="formClient"
styleClass="redButton" process="#this"
actionListener="#{clientBean.cancel()}" />
<p:commandButton ajax="false" value="Suivant"
styleClass="greenButton" action="Devis?faces-redirect=true"></p:commandButton>
</p:outputPanel>
</p:panelGrid>
</h:form>
</h:panelGroup>
As you see here i have some fields that are a required, and a button to cancel (empties) the form:
#ManagedBean(name = "clientBean")
#SessionScoped
public class ClientBean implements Serializable {
#EJB
private IClientDAO clientDAO;
#EJB
private ITypeVoieDAO typeVoieDAO;
private List<TypeVoie> typeVoies;
private static final long serialVersionUID = -3324864097586374969L;
private Client client = new Client();
#PostConstruct
public void init(){
typeVoies = typeVoieDAO.findAll();
}
public Client getClient() {
return client;
}
public void setClient(Client client) {
this.client = client;
}
public void rechercher(){
if(client != null && client.getIdentifiant() != null){
System.out.println(client.getIdentifiant());
client = clientDAO.findByIdentifiant(client.getIdentifiant());
if(client == null){
cancel();
}
}
}
public void cancel(){
client = new Client();
System.out.println(typeVoies);
}
public String navigateToClientPage(){
rechercher();
return "client?faces-redirect=true";
}
public List<TypeVoie> getTypeVoies() {
return typeVoies;
}
public void setTypeVoies(List<TypeVoie> typeVoies) {
this.typeVoies = typeVoies;
}
}
At the page loads, the selectonemenu loads perfectly, but when i click cancel, the selectonemenu gets emptied, even when i "search" for a client, and updates the form, all the other fields are filled properly, but the selectonemenu gets completely empty.
Using JSF 2.1 and primefaces 6.0
UPDATE:
Added a converter, but nothing change ...
Make sure you dont empty typeVoies list at some point on your backingbean. And if you can share your full java class, you might get more accurate help.
I am working with JSF (PrimeFaces)/EJB/JPA and a MySQL database. What I want to do is to show AT THE TOP OF THE XHTML BODY "User was successfully added to database" info message when an user is introduced successfully in the DB. I know I can use h:messages but then, also the validation error messages `are shown at the top of the body, and I want the error messages to be shown below the input fields. How could I do this?
Facelet code
<h:body>
<h:messages errorStyle="color: red" infoStyle="color: green" layout="table"/>`<!--WRONG-->
<p:inputText id="name" required="true" value="#{usersManagedBean.username}" requiredMessage="requiered field">
<f:validator validatorId="validators.NameValidator"/>
</p:inputText>
<p:watermark for="name" value="User" />
<p:message for="name" />
<p:inputText id="age" required="true" value="#{usersManagedBean.username}" requiredMessage="requiered field">
<f:validator validatorId="validators.AgeValidator"/>
</p:inputText>
<p:watermark for="age" value="Age" />
<p:message for="age" />
<p:commandButton value="Save user" action="#{usersManagedBean.saveUser}" ajax="false" />
</h:body>
Managed Bean code
//imports
#Named(value = "usersManagedBean")
#SessionScoped
public class UsersManagedBean implements Serializable
{
String username;
int userage;
#PostConstruct
public void init()
{
username="";
userage=0;
}
//Getters and Setters
public void saveUser()
{
User eUser = new Users();
eUser.setName(username);
eUser.setAge(userage);
ejbUsersDAO.create(eUser); //DAO
addSuccessMessage("User was successfully added to database");
}
public static void addSuccessMessage(String msg)
{
FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg);
FacesContext fc = FacesContext.getCurrentInstance();
fc.addMessage("successInfo", facesMsg);
}
}
Try setting globalOnly="true" attribute in your <h:messages> and change your addSuccessMessage to
fc.addMessage(null, facesMsg);
I have a problem in connecting My xhtml page to the managed bean, the action on the commandButton works but when it comes to passing values it doesn't work.
here is my jsf code:
<h:form id="form" class="form-signin">
<p:panel id="panel" header=" Authentification" style="" >
<h:panelGrid columns="2" rowClasses="3">
<h:outputLabel for="login" value="Nom d'utilisateur :" styleClass=""/>
<p:inputText id="login" value=" #{authenticationBean.profil.login }" required="true" label="login" >
<f:validateLength minimum="4" />
</p:inputText>
<h:outputLabel for="password" value="Mot de passe :" />
<p:password id="password" value=" #{authenticationBean.profil.password }" required="true" label="password" styleClass=""/>
<p:row>
<p:commandButton id="loginButton" value="Login" ajax="false" action="#{authenticationBean.validate}" />
<h:messages id="messages" globalOnly="false"/>
</p:row>
</h:panelGrid>
</p:panel>
</h:form>
i'm using morphia to map data to mongo db, i have also an entitie called profil and one bean to manage authenfication. here is my athentication bean Code :
public class AuthenticationBean implements Serializable {
private static final long serialVersionUID = 1L;
private Profil profil;
private ProfilDAO profileDao = DAOFactory.getProfilDAO();
public void validate() {
FacesMessage message = new FacesMessage("Succès de l'inscription !");
FacesContext.getCurrentInstance().addMessage(null, message);
}
// getters and setters
here is my profil entitie code :
#Entity("profils")
public class Profil {
#Id protected ObjectId _id;
protected String nomProfil,prenomProfil,login,password;
#Embedded protected List<Droit> droits;
#Reference protected Admin admin;
public Profil() {
}
//getters and setters ...
this is the eror i get when i submit some data and click the submit button :
javax.el.PropertyNotWritableException: /index.xhtml #29,125 value=" #{authenticationBean.profil.login }": Illegal Syntax for Set Operation
Look closer at the value and compare with what all sane JSF tutorials/examples try to show you:
value=" #{authenticationBean.profil.login }"
Whitespace is significant in attributes and EL expressions. Get rid of it:
value="#{authenticationBean.profil.login}"
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'm trying to validate two password fields with JSF but no good until now, I search for it on google but everything was about JSF 1.2 and pretty confusing, I'm using JSF 2.0.
This is what I'm doing so far:
<h:outputLabel for="password" value="Password:" />
<h:inputSecret id="password" value="#{register.user.password}" >
<f:ajax event="blur" listener="#{register.validatePassword}" render="m_password" />
</h:inputSecret>
<rich:message id="m_password" for="password"/>
<h:outputLabel for="password_2" value="Password (again):" />
<h:inputSecret id="password_2" value="#{register.user.password_2}" >
<f:ajax event="blur" listener="#{register.validatePassword}" />
</h:inputSecret>
This is how I it is my controller:
public void validatePassword() {
FacesMessage message;
if (!user.getPassword().equals(user.getPassword_2()) ){
message = new FacesMessage(FacesMessage.SEVERITY_ERROR, null, "different password");
}else{
message = new FacesMessage(FacesMessage.SEVERITY_INFO, null, "ok");
}
FacesContext.getCurrentInstance().addMessage("form:password", message);
}
Any idea guys ?
First of all, use a real Validator to validate the input. Don't do it in an action event method.
As to your concrete problem, you just need to specify the both fields in the execute attribute of the <f:ajax>, it namely defaults to the current component only. If you attach a validator to the first input and send the the value of the second input along as a <f:attribute>, then you will be able to grab it in the validator. You can use the binding attribute to bind the component to the view. This way you can pass its submitted value along by UIInput#getSubmittedValue().
Here's a kickoff example:
<h:outputLabel for="password" value="Password:" />
<h:inputSecret id="password" value="#{bean.password}" required="true">
<f:validator validatorId="confirmPasswordValidator" />
<f:attribute name="confirm" value="#{confirmPassword.submittedValue}" />
<f:ajax event="blur" execute="password confirm" render="m_password" />
</h:inputSecret>
<h:message id="m_password" for="password" />
<h:outputLabel for="confirm" value="Password (again):" />
<h:inputSecret id="confirm" binding="#{confirmPassword}" required="true">
<f:ajax event="blur" execute="password confirm" render="m_password m_confirm" />
</h:inputSecret>
<h:message id="m_confirm" for="confirm" />
(note that I added required="true" to both components and also note that you don't necessarily need to bind the confirm password component value to a managed bean property, it's worthless over there anyway)
with this validator
#FacesValidator("confirmPasswordValidator")
public class ConfirmPasswordValidator implements Validator {
#Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
String password = (String) value;
String confirm = (String) component.getAttributes().get("confirm");
if (password == null || confirm == null) {
return; // Just ignore and let required="true" do its job.
}
if (!password.equals(confirm)) {
throw new ValidatorException(new FacesMessage("Passwords are not equal."));
}
}
}
With seam 2 you have the component <s:validateEquality> and you don't need to write code. For JSF2 then you have Seam 3 modules, particulary Faces module and Cross-field Form Validation. An example :
First you have to use the s:validateForm tag:
<h:form id="passwordForm">
<h:inputSecret id="newPassword"
required="true"
redisplay="true"
value="#{passwordController.newPassword}">
</h:inputSecret>
<h:inputSecret id="confirmationPassword"
value="#{passwordController.confirmPassword}"
required="true"
redisplay="true">
</h:inputSecret>
<h:commandButton id="submit" value="Submit" action="#{passwordController.submitPassword}" />
<s:validateForm validatorId="passwordValidator" />
</h:form>
and the corresponding Validator for the password form above would look like this:
#FacesValidator("PasswordValidator")
public class PasswordValidator implements Validator
{
#Inject
#InputField
private String newPassword;
#Inject
#InputField
private String confirmPassword;
#Override
public void validate(final FacesContext context, final UIComponent comp, final Object values) throws ValidatorException
{
if (!confirmPassword.equals(newPassword))
{
throw new ValidatorException(new FacesMessage("Passwords do not match!"));
}
}
}
You can use Primefaces p:password tag. Please see demo example. It has match attribute which should be the id of confirm password.
<p:panel header="Match Mode">
<p:messages id="messages" showDetail="true" autoUpdate="true"/>
<h:panelGrid columns="2" id="matchGrid">
<h:outputLabel for="pass" value="Password " />
<p:password id="pass" value="#{passwordBean.password}" match="confirmPass" required="true"/>
<h:outputLabel for="confirmPass" value="Confirm Password " />
<p:password id="confirmPass" value="#{passwordBean.confirmPassword}" required="true"/>
</h:panelGrid>
<p:commandButton id="saveButton" update="matchGrid" value="Save" />
</p:panel>