Dynamic required validation for different buttons? - java

I'm currently learning about jsf 2.0 from core jsf 2.0 book + glassfish + cdi.
I have a question about the validation feature of JSF.
Let's say i have a very simple login application, which has a very simple layout like :
userid : (input field for userid - using required="true")
password : (input secret for password - using required="true")
loginButton + registerButton(using immediate="true") + checkUserIdAvailabilityButton
Now, let's say the loginButton is pressed, and the userid and password are left empty, validation error would occur on both of the fields, and that's working as what i intended.
And when the registerButton is pressed, it doesnt care whether the userid or password is filled by the user, since it's using immediate="true", thus bypassing validation and the command gets executed at the apply request value phase, and that's still working as what i intended.
And here comes my problem .. When the checkUserIdAvailabilityButton is pressed, i only expect the userid to be filled, and i dont need to care about whether the password field is filled or not, but the password field will throw error saying that it's a required field.
Is there anyway to resolve this kind of problem ? I know this could be a very simple application, but in my working place, i think they design lots of screens like this, like the save button along with refresh button with different required fields but the buttons are in the same page.
Thank you !

Set both the availability button and username field with immediate="true" and put the register button in a separate <h:form>.
E.g.
<h:form>
<h:inputText value="#{bean.username}" required="true" immediate="true" />
<h:inputSecret value="#{bean.password}" required="true" />
<h:commandButton value="Login" action="#{bean.login}" />
<h:commandButton value="Check name availability" action="#{bean.checkNameAvailability}" immediate="true" />
</h:form>
<h:form>
<h:commandButton value="Register" action="#{bean.register}" />
</h:form>
An alternative is to determine in the required attribute which button is been pressed (it's then present as request parameter).
<h:form id="form">
<h:inputText value="#{bean.username}" required="#{not empty param['form:login'] or not empty param['form:check']}" />
<h:inputSecret value="#{bean.password}" required="#{not empty param['form:login']}" />
<h:commandButton id="login" value="Login" action="#{bean.login}" />
<h:commandButton id="check" value="Check name availability" action="#{bean.checkNameAvailability}" />
<h:commandButton value="Register" action="#{bean.register}" />
</h:form>

Related

Input fields not emptying after submit and redirect?

When I want to "delete a plane" from my jsf page, if successful the plane deletes, and I do a redirect to the page and show an alert telling the user the plane was succesfully deleted. However, the values the user entered in the h:inputText are still there, they dont empty.
JSF Page:
<h:form>
<h:panelGrid columns="3" class="table">
<h:outputLabel value="Plane ID" />
<h:inputText value="#{listAirplaneBB.airPlaneId}"/>
<h:commandButton value="Delete"
class="btn btn-primary"
action="#{addAirplaneCtrl.deleteAirplane}" />
</h:panelGrid>
</h:form>
Bean code:
public String deleteAirplane(){
//delete the plane
return private/user?faces-redirect=true;
}
Any ideas on why the fields dont empty after redirect?
Maybe your listAirplaneBB is a #ViewScoped bean (cant tell by your example).
In that case you have to clean any particular fields manually before redirecting as JSF keeps alive that bean while the target page has not changed.

form field in jsp not change java variable

I can't change the data information in my jsp page when I submit the form and call a java function(When the button is pressed).
This is a peace of code used in my .jsp form field:
...
<h:form>
<h:panelGrid columns="3">
<h:outputLabel for="contactName" value="#{msj.contactName}"/>
<h:inputText id="contactName" value="#{CustodiaBean.name}" required="true">
<f:validator validatorId = "TextValidator" />
</h:inputText>
<h:message for="contactName" styleClass="errorMessage" style="color:red"/>
<h:outputLabel for="contactLastName" value="#{msj.contactLastName}"/>
<h:inputText id="contactLastName" value="#{CustodiaBean.last_name}" required="true" >
<f:validator validatorId = "TextValidator" />
</h:inputText>
<h:message for="contactLastName" styleClass="errorMessage" style="color:red"/>
</h:panelGrid>
<div id="button">
<h:commandLink styleClass="hoveringLink3doubleGreen" action="#{CustodiaBean.updateAccount}">
<h:outputText id="save_button" value="#{msj.save_changes}"/>
</h:commandLink>
<h:commandLink styleClass="hoveringLink3double" action="myAccountCustodia">
<h:outputText id="cancel_button" value="#{msj.cancel}"/>
</h:commandLink>
</div>
</h:form>
...
This is the same piece of code used in other pages like login and register user.
The form fields get the current values in "CustodiaBean", but i try to change the value in the form and when I press the button to check the value(call a function in "CustodiaBean"), I always get the previous value (The new form value is not changed in my class "CustodiaBean").
I'm using a tomcat server and eclipse.
Is necesary to force the field to be bloqued and save the changes when the button is pressed??
I don't know why this is happen. Can anyone help me or give me some advice??
Thanks a lot in advance
Does h:inputText etc also has a property name? Try to see what html is generated. It may be possible that your data is not getting submitted properly. Any HTML form directly submit feilds which are non disabled with the name property of each field. IF id is present and not name, it wont be submitted correctly. Try debugging at browser level or via some firefox plugin like tamper data.
Hope it helps

How to persist from multiple forms with one button?

I have two forms, an one button.
<h:form>
<h:outputLabel value="Form Name: *" />
<p:inputText required="true" value="#{currentTemplate.name}" />
</h:form>
and one button in another form.
<h:form id="orderListForm">
<p:commandButton value="Submit"
action="#{orderListBean.callPersist}" style="margin-top:5px"
id="btnCitySubmit" />
</h:form>
I want to save the value from the first form with the second.
I really appreciate your answer!
Do you want to execute all inputs in both forms? Then process="#all" attribute of <p:commandButton> is for you. It will process all inputs within a page.
Alternatively, you can specify ids of components to be processed, like process="#form :another-form", if to-be-updated form has id="another-form" specified.

Composite-Component within a form that requires interaction/validation

A quick background : I have put a captcha using the primefaces custom component on my website. People in charge don't like it as it is too difficult to use and clients are/were complaining. I decided I wanted to create a simple component (ie: 4 + 9 = and user inputs the answer) to avoid a bit of spam. No need to have an image display the question, just using simple text. This got me looking into custom components and composite component ( from this article and this one ).
Now, the question is not so much about a makeshift basic "captcha style validation". It's more about a composite component and backing bean combo.
What I would do is create a backing bean in this style :
<cc:interface>
<cc:attribute name="label" />
<!-- edited -->
<cc:attribute name="required" />
<cc:attribute name="ident" />
</cc:interface>
<cc:implementation>
<h:panelGrid columns="3">
<h:outputText value="#{captcha.text}"/>
<h:inputText id="#{cc.attrs.ident}" value="#{captcha.entered}" validator="#{captcha.validate}" required="#{cc.attrs.required eq 'true'}" label="#{cc.attrs.label}" />
<h:message for="captchaAnswer" />
</h:panelGrid>
<h:inputHidden value="#{captcha.value}" />
</cc:implementation>
And then I'd like to use this component in this manner :
<h:form>
...
<tr>
<td>
<my:captcha label="Captcha" ident="captcha" required="true"/> <!-- added after suggested comment -->
<br/>
<h:message for="captcha" class="error"/>
</td>
</tr>
<tr>
<td colspan="3" class="center">
<h:commandButton class="button" value="#{msg['contact.label.send']}" action="#{contact.send}" >
</h:commandButton>
</td>
</tr>
...
</h:form>
How can I make sure that on submit I can check that my {#captcha.entered} value is the required value and if not returns a validation message on the form and prevents it from being submitted?
captcha backing bean would be simple and have values : text, answer, and, entered and a simple function to check if answer == entered.
EDIT : (Attempt #1)
custom validator would look as follow
public void validate(FacesContext context, UIComponent toValidate, Object value) {
System.out.println("validating");
String input = (String) value;
//check to see if input is an integer
//if not we know right away that the value is not good
if(StringUtils.isNumeric(input)) {
//if the input is numeric, convert to an integer
int intValue = new Integer(input).intValue();
if (intValue != answer) {
((UIInput) toValidate).setValid(false);
FacesMessage message = new FacesMessage("Not a match!!");
context.addMessage(toValidate.getClientId(context), message);
}
}
}
In this instance the validator does not even get called and I don't get an error message.
Edit #2
After a bit of working and hints from comments I got this working. To get the h:message working I needed to add the attribute ident instead of id. If not I had to reference it as so : <h:message for="captcha:captcha" /> which was not the desired outcome.
The primary issue with this question was that I couldn't get a reference.
By adding the attribute ident instead of id I got this to work. Please refer to edit #2 in question.

Retrieve values from JSP to Javascript

Below is the javascript on my JSP page:
<SCRIPT language="JavaScript">
function checkPass(){
var pass1=request.getParameter('password');
var pass2=request.getParameter('password2');
if (pass1==pass2){
window.alert("YES");
}
else{
window.alert("NO");
}
}
</SCRIPT>
Below is my form input text boxes:
<h:outputLabel value="Password:" for="password" />
<h:inputSecret id="password" value="#{StaffController.staff.password}"
size="20" required="true"
label="Password" >
<f:validateLength minimum="8" />
</h:inputSecret>
<h:message for="password" style="color:red" />
<h:outputLabel value="Password:" for="password2" />
<h:inputSecret id="password2"
size="20" required="true"
label="Password" >
<f:validateLength minimum="8" />
</h:inputSecret>
<h:message for="password2" style="color:red" />
Below is my commandbutton linked with onmousedown to call the script when clicked:
<h:commandButton action="#{StaffController.saveUser()}" onmousedown="checkPass();" value="Submit"/>
I can't seem to retrieve value from my user input form.
JSF changes id of components - view source of your page in browser. It should be something like a combination of form id+component id
Submit command invokes onmousedown event before making submit, so in checkPass you do not have a request object
Better to write a custom validator for checking password
First you require to set in the h:form the value false to the "prependId" attribute to make possible to get the textboxes by id on javascript. Is not recomended to remove the prependId. But it makes to you easier to work with javascript. In other way you could use a field name or css name an other kind of selection (like using Jquery $('.cssname') or $('#cssid')
Now you need to change the javascript. javascript is performed on the client side. You can't get data from the request because the request is not done when the javascript is executed.
You need to get the inputSecret object ,that in the html is an input item, using something like this:
var pass1 = document.getById('password').value;
var pass2 = document.getById('password2').value;

Categories