Checking for messages existence - jsf

I use a method like this for sending error messages to my facelet:
public static void addErrorMessage(String msg) {
FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
FacesContext.getCurrentInstance().addMessage(null, facesMsg);
}
Then I show them inside a dialog with:
<p:messages id="messagesFattura" autoUpdate="true" />
And that works well. Now, my question is:
how can I "check" for messages existence?
I mean, there's another portion of code (a primefaces ) which I want to show/hide conditionally, via the rendered attribute.
I already tried the #{empty facesContext.messageList} EL variable, without success (empty list)

Related

Display IOException into Primefaces Messages

I am trying to display IOException into Primefaces messages but the text is not formated properly
In my code I catch the exception:
} catch (Exception ex) {
System.out.println(ex);
msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, null,ex.toString());
facesGetCurrentInstance(msg);
}
Then add the message:
public void facesGetCurrentInstance(FacesMessage msg) {
FacesContext.getCurrentInstance().addMessage(null, msg);
}
In the XHTML I am using growl to display the message
<p:growl id="messages" showDetail="true" sticky="true" autoUpdate="true" />
Thus far everything works, but I am having an issue with how the message is getting displayed. I am assuming this because I am using .toString. So, is there another way to do this?
try this:
FacesContext.getCurrentInstance().addMessage(FacesMessage.SEVERITY_ERROR,exception.getMessage());

FacesMessage is not displayed when being set in an action method with a redirect outcome

Why the code from the first block works and the other one doesn't? It's all about displaying JSF messages
#PostConstruct
public void init() {
try {
throw new RuntimeException();
} catch (RuntimeException e) {
i18nExceptionHandler.handleException(e);
}
}
The code above works well - it displays the message.
public String login() {
try {
//login actions
} catch (AuthenticationException e) {
//this doesn't work
i18nExceptionHandler.handleException(e);
}
return "/pages/loggedin?faces-redirect=true";
}
This code doesn't work - it doesn't display any message and I'm given following error:
WARNING: There are some unhandled FacesMessages, this means not every FacesMessage had a chance to be rendered.
Why it works like that? Shall I use validator or something else on the login method (and the rest as well)?
You need to include h:messages tag in your jsf page. for example,
<h:messages id="messagesID" globalOnly="true" layout="table" />
If you don't have this in your JSF page, the warning message will arise.
Message from the second code block wasn't displayed, because method hasn't got void signature.

show FacesMessage when invoking wizard.getOldStep()

I'm trying to show a FacesMessage built in onFlowProcess of a primefaces wizard.
public String onFlowProcess(FlowEvent event) {
if (event.getOldStep().equalsIgnoreCase("otherTab")){
if (!hasImage){
FacesUtils.addMessage(null, "Error", "image is required", FacesMessage.SEVERITY_ERROR);
return event.getOldStep();
}
}
return event.getNewStep();
}
The message should be send to the growl but I believe that by invoking getOldStep(), the message is lost along the way.
My growl is declared as :
<p:growl life="2500" showDetail="true" globalOnly="true"/>
and the wizard contains flowListener="#{bean.onFlowProcess}".
I tried to keep my FacesMessage with
FacesContext.getCurrentInstance().getExternalContext().getFlash().setKeepMessages(true);
but this seems to work only for page redirect...
If anybody has any idea... Thx
I solved the problem by updating the <p:growl> from the bean:
RequestContext.getCurrentInstance().update("form:growl");

JSF outputlabel clear

I have the following problem. I use a form when I provide only PIN. I have validator which checks if its a 4-digit number. Then the action on submit is set to the method which checks if the PIN exists in the database. If not it does message = "no PIN"; I used the message in the output label below the form. Previously it was null so there was no message there. Now it changes into "no PIN" but I have to clear it after clicking the submit button again because the error message doesn't disappear when you enter for example "12as" PIN and validator takes care of it. How should i implement such situation? Maybe using an output label in such situtation is a wrong idea?
You should not perform validation in action method. You should use a real validator.
Just implement the Validator interface accordingly. E.g.
#FacesValidator("pinValidator")
public class PinValidator implements Validator {
#Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
String pin = (String) value;
if (pin == null || pin.isEmpty()) {
return; // Let required="true" deal with it if necessary.
}
if (!pin.matches("\\d{4}")) {
throw new ValidatorException(new FacesMessage("PIN must be 4 digits"));
}
if (!somePinService.exists(pin)) {
throw new ValidatorException(new FacesMessage("PIN is unknown"));
}
}
}
Use it as follows:
<h:outputLabel for="pin" value="PIN" />
<h:inputText id="pin" value="#{bean.pin}" validator="pinValidator" />
<h:message for="pin" />
The faces message of the validator exception will end up in the <h:message> associated with the component on which the validator is been fired.
If you're using ajax to submit the form, don't forget to make sure that the message is also taken into account on ajax render.
Unrelated to the concrete problem, the JSF <h:outputLabel> generates a HTML <label> element which is intented to label a form element (e.g. <input>, <select>, etc). It's absolutely not intented to show an arbitrary piece of text such as a validation message. I recommend to put JSF aside for now and start learning basic HTML. This way you will understand better which JSF components to pick to get the desired HTML output.
You can use JSF message component outside a validator:
For a message for your input in your form:
<h:message for="PIN"/>
And at your managed bean you can add a FacesMessage using:
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_WARN,"No pin summary message","No pin detail message");
FacesContext.getCurrentInstance().addMessage("PIN", message);
No need to use a outputLabel here.

How to put validation on p:fileUpload

Along with couples inputText, one of a mandatory component that I have on the page is a p:fileUpload. So when I click submit, <p:message> show up on component that have require=true, but the user did not type/select
I want the red box Required also appear next to the upload component. Here is what I have tried.
1 . when I set required="true" in p:fileUpload, nothing really happen (not sure if this is a bug).
2 . I put validator in p:fileUpload, below is my validator sources
public void validateFileUpload(FacesContext context, UIComponent component,
Object value) throws ValidatorException {
if(value == null){
FacesMessage message = new FacesMessage();
message.setSeverity(FacesMessage.SEVERITY_ERROR);
message.setSummary("Error");
message.setDetail("Required");
throw new ValidatorException(message);
}
}
nothing really happen when I click submit, not even when I go through the upload, validateFileUpload did not get called at all (not sure if this is a bug)
3 . When I click submit, if everything else pass, and I get into my action method, I am able to check if the file is null or not, then return a FacesMessage and let p:growl pick it up. However, I dont like it that way since it give the user a feeling of multiple layer of validation.
Is there a way to do better validation on p:fileUpload?
For those with the same problem, I ran into this problem while creating a wizard. The workaround I used was to store the uploaded file in a field of my viewscoped bean and check this field when trying to navigate to the next step.
Wizard tag:
<p:wizard id="importBankAccountLogWizard"
widgetVar="importBankAccountLogWizard"
flowListener="#{bankAccountLogImportBean.onFlowProcess}">
File upload tag (I have the rendered and the update attribute set up so that a message will be shown and the uploaded will be hidden after the first upload):
<p:fileUpload id="bankAccountLogFileInput"
fileUploadListener="#{bankAccountLogImportBean.setBankAccountLogFile}"
rendered="#{bankAccountLogImportBean.renderFileUploadInput}"
mode="advanced"
update="importBankAccountLogWizard"
auto="true"
sizeLimit="1000000" />
Bean:
public void setBankAccountLogFile(FileUploadEvent event)
{
importFile = event.getFile();
FacesMessage msg = new FacesMessage(Localization.g("FILE_HAS_BEEN_UPLOADED", event.getFile().getFileName()));
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public String onFlowProcess(FlowEvent event)
{
if("bankAccountLogImportInputTab".equals(event.getOldStep()) &&
importFile == null)
{
FacesMessage msg = new FacesMessage(Localization.g("UPLOAD_A_FILE_TO_CONTINUE"));
FacesContext.getCurrentInstance().addMessage(null, msg);
return event.getOldStep();
}
return event.getNewStep();
}

Resources