How to display my application's errors in JSF?
In case anyone was curious, I was able to figure this out based on all of your responses combined!
This is in the Facelet:
<h:form id="myform">
<h:inputSecret value="#{createNewPassword.newPassword1}" id="newPassword1" />
<h:message class="error" for="newPassword1" id="newPassword1Error" />
<h:inputSecret value="#{createNewPassword.newPassword2}" id="newPassword2" />
<h:message class="error" for="newPassword2" id="newPassword2Error" />
<h:commandButton value="Continue" action="#{createNewPassword.continueButton}" />
</h:form>
This is in the continueButton() method:
FacesContext.getCurrentInstance().addMessage("myForm:newPassword1", new FacesMessage(PASSWORDS_DONT_MATCH, PASSWORDS_DONT_MATCH));
And it works! Thanks for the help!
Error messages on page with the h:messages in JSF
The globalOnly
switch should work if you add your messages correctly in your backing bean. The client-id must be null
in FacesContext.addMessage(...)
:
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(message));
Show JSF validation error next to the fields
Just put a <h:message>
right there where you need to see it. E.g.
<tr>
<td class="label">
<h:outputLabel for="email" value="Login Email:"></h:outputLabel>
</td>
<td class="field">
<h:inputText id="email" size="20" maxlength="70" required="true" requiredMessage="Please enter your email,eg:yourid@domain.com" value="#{loginController.selected1.email}"> <f:validateLength maximum="70"></f:validateLength></h:inputText>
<h:message for="email" />
</td>
</tr>
or
<tr>
<td class="label">
<h:outputLabel for="email" value="Login Email:"></h:outputLabel>
</td>
<td class="field">
<h:inputText id="email" size="20" maxlength="70" required="true" requiredMessage="Please enter your email,eg:yourid@domain.com" value="#{loginController.selected1.email}"> <f:validateLength maximum="70"></f:validateLength></h:inputText>
</td>
<td class="message">
<h:message for="email" />
</td>
</tr>
Unrelated to the concrete problem, I suggest to have a look at <h:panelGrid>
. It minimizes the ugly HTML table boilerplate. Your code would then end up like follows:
<h:form id="LoginForm">
<h2>Login</h2>
<h:panelGrid columns="3" columnClasses="label,field,message">
<h:outputLabel for="email" value="Login Email:" />
<h:inputText id="email" value="#{loginController.selected1.email}" size="20" maxlength="70" required="true" requiredMessage="Please enter your email,eg:yourid@domain.com">
<f:validateLength maximum="70" />
</h:inputText>
<h:message for="email" />
<h:outputLabel for="password" value="Password:" />
<h:inputSecret id="password" value="#{loginController.selected1.password}" size="20" maxlength="50" required="true" requiredMessage="Please confirm your password">
<f:validateLength minimum="6" maximum="50" />
</h:inputSecret>
<h:message for="password" />
<h:panelGroup />
<h:commandButton value="Login" action="#{loginController.checkValidUser()}" />
<h:panelGroup />
</h:panelGrid>
</h:form>
Showing the JSF Error Messages
I'm not sure, but this all look like unnecessarily overcomplicated. To change icons/styles based on the message severity, just make use of the CSS powers. You can specify different CSS classes based on message severity using infoClass
and errorClass
attributes of the <h:messages>
and you can specify the icons as CSS background image.
JSF:
<h:messages id="messages" layout="table" infoClass="info" errorClass="error" />
CSS:
#messages .info td {
background: url('info.gif') no-repeat left center;
padding-left: 15px;
}
#messages .error td {
background: url('error.gif') no-repeat left center;
padding-left: 15px;
}
The <h:messages layout="table">
itself already renders a HTML <table>
. I think the whole table around it is unnecessary as well. Just apply styles accordingly the usual CSS way.
#messages {
width: 375px;
margin: 0 auto;
border: 1px black solid;
border-collapse: collapse;
}
See also:
- W3schools CSS tutorial/reference
- CSStutorial.net CSS tutorial
Update: as per the comments, you're looking for something like this:
<h:messages layout="table" styleClass="messages info" infoClass="info" errorClass="error" />
<h:messages layout="table" styleClass="messages error" infoClass="info" errorClass="error" />
with CSS:
.messages {
width: 375px;
margin: 0 auto;
border-collapse: collapse;
border: 1px black solid;
}
.messages.info {
background: url('info.gif') no-repeat left center;
}
.messages.error {
background: url('error.gif') no-repeat left center;
}
.messages.info tr.error, .messages.error tr.info {
display: none;
}
.messages td {
padding-left: 15px;
}
This shows two separate message tables, one for info
and other for error
messages, each with a single icon on the left center.
show error message on the same page
The globalOnly switch should work if you add your messages correctly in your backing bean. The client-id must be null in FacesContext.addMessage(...):
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(message));
JSF Validation Error message doesn't appear
Consider the following:
<p:commandButton id="submit-button" value="#{msg.next}" action="next.xhtml"/>
The p:commandButton
is a Primefaces library tag and is an enhanced version of the JSF's h:commandButton
. The Primefaces button is by default ajax enabled.
In the example posted, when the commend button is pressed the form is processed (this is the default behavior) and the next.xhtml
page is to be displayed.
The application is using bean validation to validate the input text; the p:inputText
tag. When the user enters a 2 character value in the input text and presses the command button the validation is happening. The same page is shown but the expected validation message "At least 3 characters" is not rendered to the page.
One can see something like this in the server log (this is from Apache Tomcat's log files):
org.apache.myfaces.lifecycle.RenderResponseExecutor.execute There are
some unhandled FacesMessages, this means not every FacesMessage had a
chance to be rendered. These unhandled FacesMessages are:
- Name: Minimum 2 characters are required!
This is because the request is originally to render the next.xhtml
; this is the normal behavior. If one enters a valid name with 5 characters the next page will be displayed as expected. Due to the validation exception the current page is shown again but the message is not refreshed to the page. The message component needs to be refreshed explicitly.
Change this:
<h:message for="name"/>
To:
<h:message for="name" id="errmsg"/>
And, specify in the command button that this message component needs to be updated on submit.
Change this:
<p:commandButton id="submit-button" value="#{msg.next}" action="next.xhtml"/>
To:
<p:commandButton id="submit-button" value="#{msg.next}" action="next.xhtml" update="errmsg"/>
Alternate:
Another way of solving this is to simply submit a non-ajax request and then the full page will be refreshed by default - and one can see the validation message. In this case no need to have an "id" attribute for the h:message
tag and the command button can be declared without the ajax behavior as:
<p:commandButton ajax="false" id="submit-button" value="#{msg.next}" action="next.xhtml"/>
NOTES:
The above conclusion is based on code tried on Apache Tomcat 8 web server, Apache MyFaces 2.2, Primefaces 5.3 and Hibernate Bean Validator 5.2.
h:message not displayed in jsf page
Your action method returns a navigation case in all paths. I'm guessing you don't actually have a failure
navigation (i.e. a failure.xhtml
view) so when your client
object is null, you still see the same view without the update message. What should happen is get a redirection to failure
view, and by this, the browser will have no chance to display the error message. Check your server logs for navigation errors.
Since you want the browser to stay on the same page (view) and update the error message, your method should return null
after adding the message, instead of failure
.
Related Topics
Creating Gradient Lines in CSS
Transform-Origin Not Working on Firefox
Why Is The User Agent Style Sheet The Last One Style Sheet to Be Applied
Set Width of "Dialog" Widget to a Percentage of The Page in Vaadin 14
How to Make The Image Full Bleed But Pad The Content
When Printing Page Table Rows/Cells Gets Split on Page Break
Horizontal Sharp Background Gradient with Specific Length of First Color
How to Add Horizontal Scrollbar in a React Bootstrap Table
Rails 3 - Referencing a CSS Class to Form Elements in an Object Dot Style
Issue with: Global() CSS-Module Selectors Not Being Pure in Nextjs
Bootstrap Container Fill Sides with Colors
Weird Float Rendering in Chrome When Using Media Queries
Internet Explorer 8 and Checkbox CSS Problem