JSF ajax render message and redirect - ajax

I have a JSF application where users login in a login form inserting their email and password. The ManagedBean has the following 2 methods.
The method checkIdentity1() returns an URL ("" if the validation is incorrect in order to stay in the same page, or /useraccount.xhtml if inserted data is ok in order to go to next page).
The method checkIdentity2() returns a boolean value (false if the validation is wrong in order to show a message, true if it is ok).
loginManagedBean.java
public String checkIdentity1()
{
String strResponse="";
//check id
if(email.equals("jose#a.com") && password.equals("1234"))
{
strResponse="/useraccount.xhtml?faces-redirect=true";
} else {
}
//
return strResponse;
}
public boolean checkIdentity2()
{
boolean bResponse=false;
//check id
if(email.equals("jose#a.com") && password.equals("1234"))
{
//setpassIncorrecta(false);
} else {
bResponse=true;
}
//
return bResponse;
}
What I am trying to do is to mix ajax and JSF to show "Email and/or password incorrect" when I click Login button and validation fails and go to account.xhtml when validation is ok. But when I insert incorrect email and password no message is displayed, and when I insert them correctly the page is no redirected to account.xhtml. What am I doing wrong?
This is my Facelet
<h:form>
<!--Email-->
<h:inputText id="email" label="email" required="true" size="32" maxlength="32"
value="#{loginManagedBean.email}"
requiredMessage="Insert your email">
</h:inputText>
<h:message for="email" />
<!--Password-->
<h:inputSecret id="password" label="password" required="true" size="32" maxlength="40"
value="#{loginManagedBean.password}"
requiredMessage="Insert your password">
</h:inputSecret>
<h:message for="password" />
<!--Button-->
<h:commandButton value="Login" action="#{loginManagedBean.checkIdentity1()}">
<f:ajax execute="#form" render=":loginErrorMessage" />
</h:commandButton>
</h:form>
<h:panelGroup id="loginErrorMessage">
<h:outputText value="Email and/or password incorrect" rendered="#{!loginManagedBean.checkIdentity2()}" />
</h:panelGroup>

Like I explained in the comment, that's just the way JSF works: if a request fails validation, the action method will not be executed. That's defined the JSF request processing lifecycle (which I won't get into here). For the purpose of this answer, all you need to know is that the validation of request parameters happens before the action methods are considered. That being said, if the validation fails, the request processing is short-circuited there and then. To achieve what you're looking for, you should consider the following:
To conditionally render that component, you can examine the validation status in your page:
<h:outputText value="Email and/or password incorrect" rendered="#{facesContext.validationFailed}" />
Ideally, you should just use the <h:messages/> component, where you don't need to manage message display yourself
JSF will stay on the same page by default, if the validation fails, so you needn't take any special steps to that effect

Related

Showing JSF validation errors for several fields with more than h:message

A form with validations on several input fields should show stylish error messages with an icon in front of the message contained in a red box.
The h:panelGroup containing icon and message must be rendered only in case of an error.
With just one validated input field this would work:
<h:panelGroup rendered="#{facesContext.validationFailed}"
But with more than one input field all error panel groups are visible, even those without error showing no text but the icon in a red box.
My solution is now to have a validator for each input and add an attribute ´´validationFailed´´ to each validator.
<p:inputNumber id="mileage" validator="#{mileageValidator.validate}"></p:inputNumber>
<h:panelGroup rendered="#{mileageValidator.validationFailed}" styleClass="wizard-alert-box">
<div class="wizard-alert-content-margin">
<h:graphicImage name="attention.png"/>
<h:message id="invalid-mileage" for="mileage" showSummary="true" showDetail="false"/>
</div>
</h:panelGroup>
<p:calendar id="date" validator="#{dateValidator.validate}"></p:calendar>
<h:panelGroup rendered="#{dateValidator.validationFailed}" styleClass="wizard-alert-box">
<div class="wizard-alert-content-margin">
<h:graphicImage name="attention.png"/>
<h:message id="invalid-date" for="date" showSummary="true" showDetail="false"/>
</div>
</h:panelGroup>
And here is one of the validators:
#Named("mileageValidator")
public class MileageValidator {
#Getter
private boolean validationFailed;
public void validate(FacesContext context, UIComponent component, Object value) {
validationFailed = value == null;
if (validationFailed) {
throw new ValidatorException(new FacesMessage("mileage empty"));
}
}
}

Update multiple components ajax [duplicate]

This question already has an answer here:
Ajax update/render does not work on a component which has rendered attribute
(1 answer)
Closed 7 years ago.
I want to update two components after ajax action but don't know how to do this (if it is even possible).
I have three pages:
<h:form id="loginForm">
<p:panelGrid columns="2" >
<h:outputText value="Login: "/>
<p:inputText value="#{bean.person.username}" requiredMessage="*" />
<h:outputText value="Hasło: "/>
<p:password value="#{bean.person.password}" requiredMessage="*"/>
<p:commandButton value="Login" action="#{bean.validatePerson}" update="loginConfirmationPage"/>
</p:panelGrid>
</h:form>
Menu page is similar to this above with menu items with rendered atribute (fe. show logout button when user is logged in) and loginConfirmationPage on which i want to show username.
I need to update both of these pm:pages to get logout button on menu page and also display username on confirmation page.
How can I do this? For now i can only update one page. I tried to type statement similar to these:
<p:commandButton value="Login" action="#{bean.validatePerson}" update="loginConfirmationPage,menuPage"/>
or
<p:commandButton value="Login" action="#{bean.validatePerson}" update="loginConfirmationPage;menuPage"/>
Both not working. How can i do this?
var name = "";
$.post("Path/To/Server/File", {'serverFileVariableName' : clientElementID},
//data is what the server file will return
function(data){
//In this case, the data is the username.
name = data;
//invoke the show method to display
logOut.show();
}
);
//done

How to pass multiple component values to listener via ajax on button click

I have select box for list of account numbers, an input field to enter amount and a button to calculate total debit. I want to pass the amount and account values via ajax to an event handler on click event.
Some how I am not able to pass the values entered to event handler.
Can someone suggest me, on how to do ?
My Xhtml:
<h:selectOneMenu class="RUIFW-from-el form-control"
id="fromAccountIndex" value="#{parentBean.fromAccountIndex}"
validator="#{tptValidator.validateFromAccount}">
<f:selectItems value="#{parentBean.fromAccountUIMap}"/>
</h:selectOneMenu>
<h:inputText id="amount" name="amount" value="#{parentBean.amount}" class="RUIFW-form-el form-control" validator="#{tptValidator.validateAmount}"/>
Updated code:
<h:commandLink class="RUIFW-btn mar-lft-10 veraligntop">
<h:outputLabel value="#{GIBBundle.tpt_btn_calculate}"/>
<f:ajax execute="#this fromAccountIndex amount onclick" listener="#{parentBean.calculateClickedListener}"/>
</h:commandLink>
My Bean Method
public void calculateClickedListener(AjaxBehaviorEvent event) {
System.out.println("getFromAccountIndex()....."+getFromAccountIndex());
System.out.println("getAmount()....."+getAmount());
}
You're not setting the execute attribute on the f:ajax. That attribute defaults to #this, and as a result, no other component will be processed and no values will be set. This is why the value bindings of your input components are likely to turn out null.
Set your execute="#form" or execute="#this fromAccountIndex amount" to get the values updated in your bean
Reference:
f:ajax Javadoc

Icons with a FacesMessage when validating

PrimeFaces/JSF 2.0
When you use p:message.... and say your outputText has required="true", you see the error icon in the message displayed to the right of the field if the user leaves the field blank.
<!-- NAME -->
<p:panelGrid styleClass="noBorders" columns="2" columnClasses="inputText" style="width:600px">
<h:inputText id="Name" size="60" maxlength="70" required="true" styleClass="#{not component.valid ? 'ui-input-invalid' : ''}" style="width: 300px" value="#{tinRequestBean.name}" >
<f:validator validatorId="gov.irs.eservices.tm.validations.NameValidator" />
</h:inputText>
<p:message for="Name" display="default" style="color: red" />
</p:panelGrid>
However, if you use a Validator to check the contents of the field in some way, the standard FacesMessage, even with FacesMessage.SEVERITY_ERROR, the error icon does not show up.
if (msgStr.length() > 0) {
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "TIN: Validation error: " msgStr, null);
throw new ValidatorException(msg);
}
Does anyone know a way to create a FacesMessage with an icon attached? It's certainly not in the constructor.
Set the display="both" on the <p:message/>(or just leave that attribute out altogether, both is the default). This will display both the text and the icon. As far as I can tell, default is not a valid option

How to customize the presentation of faces messages

I would like to customize the presentation of faces messages.
For this,
<h:inputText id="name" required="true" />
when validation is failed, then it will be shown in a
<h:message for="name" />
However, I would like to customize the presentation call JS as follows:
<div class="notification"></div>
function showNotification(msg){
$(".notification").html(msg);
$(".notification").fadeIn(1000, function(){
timeout = setTimeout(function(){
$(".notification").fadeOut(1000);
}, 5000);
});
}
How can I achieve this?
You can use FacesContext#getMessageList() to get the messages in the view, if necessary the ones for a specific client ID. You can iterate over them in a ui:repeat. Each item is a FacesMessage which has several getters. You can display any HTML in the message unescaped by using <h:outputText escape="false">.
So, in a nutshell:
<ui:repeat value="#{facesContext.messageList('form:name')}" var="message">
<div><h:outputText value="#{message.summary}" escape="false" /></div>
</ui:repeat>
(in the above example, I assume that your form has id="form")
Or, if that HTML help link is actually not part of the message, then so:
<ui:repeat value="#{facesContext.messageList('form:name')}" var="message">
<div>#{message.summary} help</div>
</ui:repeat>

Resources