show FacesMessage when invoking wizard.getOldStep() - jsf

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");

Related

Strange display of p:fileUpload component

I am trying to use the fileUpload component of PrimeFaces and everything is working BUT an empty error message is displayed when the component appeared with no content and i do not understand why.
And if i add a file to the component is disappeared well but it is still not pretty to have it when the component loads.
// View
<h:form>
<p:fileUpload fileUploadListener="#{bean.handleFileUpload}" />
</h:form>
// ManagedBean
public void handleFileUpload(FileUploadEvent event) {
UploadedFile file = event.getFile();
System.out.println("handleFileUpload : " + file);
}
The managed bean function is well called when I click on the upload button.
Hope some could understand my problem !
Thanks in advance

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());

How to show a primefaces growl message on the next page? [duplicate]

This question already has answers here:
How to use Primefaces' p:growl and redirect to a page
(3 answers)
Closed 6 years ago.
I'm using primefaces 3.5 and I can't figure it out how to growl a message on the next page. For instance I want to add a record in database and after that I make a redirection to another page where I want to show a growl message with "The record has been added with success!"
I tried something like this:
public String addLabelInDB() {
try {
//logic to add a record in DB
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Success!", "Label has been added with success!"));
} catch (Exception e) {
logger.debug(e.getMessage());
}
return "listLabelsPage";
}
and in listLabelsPage.xhtml I have:
<p:growl id="msgs" showDetail="true" autoUpdate="true"/>
but it doesn't work.
I supposed the message is getting lost because is another request or something? It's there any possibility to store the message on request and show it on the next page? Thanks!
You can have a preRender set on the listLabelsPage.xhtml page you're loading
<f:event type="preRenderView" listener="#{yourBean.showGrowl}" />
and a showGrowl method having only
public void showGrowl() {
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Success!", "Label has been added with success!"));
}
I post an answer to my own question in order to help another people which face the same problem like I did:
public String addLabelInDB() {
try {
//some logic to insert in db
//below I set a flag on context which helps me to display a growl message only when the insertion was done with success
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.getRequestMap().put("addedWithSuccess","true");
} catch (Exception e) {
logger.debug(e.getMessage());
}
return "listLabelsPage";
}
public void showGrowl() {
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
String labelAddedWithSuccess = (String) ec.getRequestMap().get("addedWithSuccess");
//if the flag on context is true show the growl message
if (labelAddedWithSuccess!=null && labelAddedWithSuccess.equals("true")) {
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Success!", "Label has been added with success!"));
}
}
and in my xhtml I have:
<f:event type="preRenderView" listener="#{labelsManager.showGrowl}" />
How about this? Make a separated redirect button which will be hit after showing msg:
HTML:
<h:form prependId="false">
<p:growl />
<p:button outcome="gotoABC" id="rdr-btn" style="display: none;" />
<p:commandButton action="#{bean.process()}" update="#form" />
</form>
Bean:
public void process(){
addInfoMsg(summary, msgDetail); //Add msg func
RequestContext.getCurrentInstance().execute("setTimeout(function(){ $('#rdr-btn').click(); }, 3000);"); // 3 seconds delay. I put the script in Constants to config later.
}

Checking for messages existence

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)

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